Owns its configuration, moved to picom's window rules; started once from the session's xinitrc slot; Go tools restart, rules, window-opacity and toggle, which find the operator's X session from the window manager's environment.
132 lines
4.7 KiB
Go
132 lines
4.7 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A pid above the kernel's largest, so a signal a test sends reaches nothing.
|
|
const nobody = 4194400
|
|
|
|
func TestTheModulesOwnConfigurationReadsAsRulesInOrder(t *testing.T) {
|
|
raw, err := os.ReadFile(filepath.Join("..", "..", "files", "picom.conf"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r := parseRules("picom.conf", string(raw), nil)
|
|
if r.Global["backend"] != "glx" || r.Global["vsync"] != "true" || r.Global["shadow"] != "false" {
|
|
t.Fatalf("global options: %v", r.Global)
|
|
}
|
|
if len(r.Rules) != 5 {
|
|
t.Fatalf("five rules: %+v", r.Rules)
|
|
}
|
|
focused, unfocused := r.Rules[2], r.Rules[3]
|
|
if focused.Match != "class_g = 'XTerm' && focused" || focused.Options["opacity"] != "0.95" ||
|
|
unfocused.Match != "class_g = 'XTerm' && !focused" || unfocused.Options["opacity"] != "0.75" {
|
|
t.Fatalf("the terminal rules: %+v %+v", focused, unfocused)
|
|
}
|
|
if last := r.Rules[4]; last.Match != "fullscreen" || last.Options["opacity"] != "1" {
|
|
t.Fatalf("full screen is opaque, and last so it wins: %+v", last)
|
|
}
|
|
if len(r.Legacy) != 0 {
|
|
t.Fatalf("the module's file sets no option the rules supersede: %v", r.Legacy)
|
|
}
|
|
if _, inGlobal := r.Global["match"]; inGlobal {
|
|
t.Fatal("a rule's key leaked into the global options")
|
|
}
|
|
}
|
|
|
|
func TestTodaysFileIsReportedForTheOptionsItsRulesWouldIgnore(t *testing.T) {
|
|
conf := "inactive-opacity = 1.0;\nopacity-rule = [ \"95:class_g = 'XTerm'\" ];\nrules = (\n { match = \"focused\"; opacity = 1; }\n);\n"
|
|
r := parseRules("x", conf, []int{7})
|
|
if len(r.Rules) != 1 || r.Rules[0].Match != "focused" || len(r.Running) != 1 {
|
|
t.Fatalf("%+v", r)
|
|
}
|
|
if strings.Join(r.Legacy, ",") != "opacity-rule,inactive-opacity" {
|
|
t.Fatalf("legacy: %v", r.Legacy)
|
|
}
|
|
}
|
|
|
|
func TestAWindowIdIsHexOrDecimalAndNeverZero(t *testing.T) {
|
|
for in, want := range map[string]string{"0x3C00012": "0x3c00012", "62914578": "0x3c00012"} {
|
|
if got, err := windowID(in); err != nil || got != want {
|
|
t.Errorf("%s: %s, %v", in, got, err)
|
|
}
|
|
}
|
|
for _, bad := range []string{"0", "0x0", "window", "-1", "0x1ffffffff"} {
|
|
if _, err := windowID(bad); err == nil {
|
|
t.Errorf("%s was accepted", bad)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOpacityIsAPercentOfTheFullCardinal(t *testing.T) {
|
|
if opacityCardinal(0) != 0 || opacityCardinal(100) != 0xffffffff || opacityCardinal(75) != 3221225471 {
|
|
t.Fatalf("%d %d %d", opacityCardinal(0), opacityCardinal(100), opacityCardinal(75))
|
|
}
|
|
r := parseWindow("0x1", "_NET_WM_WINDOW_OPACITY(CARDINAL) = 3221225471\nWM_CLASS(STRING) = \"xterm\", \"XTerm\"\n_NET_WM_NAME(UTF8_STRING) = \"op@host: ~\"\n")
|
|
if r.Opacity == nil || *r.Opacity != 75 || r.Class != "XTerm" || r.Title != "op@host: ~" {
|
|
t.Fatalf("%+v", r)
|
|
}
|
|
if r := parseWindow("0x1", "_NET_WM_WINDOW_OPACITY: not found.\n"); r.Opacity != nil {
|
|
t.Fatalf("no value of its own: %+v", r)
|
|
}
|
|
}
|
|
|
|
func TestSettingTheFocusedWindowsOpacityAsksXpropAndNamesTheRuleThatOutranksIt(t *testing.T) {
|
|
root := fakeMachine(t)
|
|
fakeProcess(t, nobody, "i3", "DISPLAY=:1")
|
|
conf := filepath.Join(root, "home", ".config", "picom")
|
|
if err := os.MkdirAll(conf, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
src, _ := os.ReadFile(filepath.Join("..", "..", "files", "picom.conf"))
|
|
if err := os.WriteFile(filepath.Join(conf, "picom.conf"), src, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
bin := fakeBinaries(t, map[string]string{"xprop": `echo "xprop $* DISPLAY=$DISPLAY" >> "$LOG"
|
|
case "$*" in
|
|
"-root _NET_ACTIVE_WINDOW") echo "_NET_ACTIVE_WINDOW(WINDOW): window id # 0x3c00012" ;;
|
|
*WM_CLASS*) printf '_NET_WM_WINDOW_OPACITY(CARDINAL) = 2147483648\nWM_CLASS(STRING) = "xterm", "XTerm"\n' ;;
|
|
esac`})
|
|
t.Setenv("LOG", filepath.Join(bin, "log"))
|
|
r, err := WindowOpacity("", 50)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if r.Window != "0x3c00012" || r.Opacity == nil || *r.Opacity != 50 || !strings.Contains(r.Note, "XTerm") {
|
|
t.Fatalf("%+v", r)
|
|
}
|
|
log, _ := os.ReadFile(filepath.Join(bin, "log"))
|
|
if !strings.Contains(string(log), "xprop -id 0x3c00012 -f _NET_WM_WINDOW_OPACITY 32c -set _NET_WM_WINDOW_OPACITY 2147483648 DISPLAY=:1") {
|
|
t.Fatalf("xprop was asked:\n%s", log)
|
|
}
|
|
}
|
|
|
|
func TestWithoutASessionTheToolsThatDrawSaySo(t *testing.T) {
|
|
fakeMachine(t)
|
|
if _, err := WindowOpacity("", -1); !errors.Is(err, ErrNoSession) {
|
|
t.Fatalf("window opacity: %v", err)
|
|
}
|
|
on := true
|
|
if _, err := Toggle(&on); !errors.Is(err, ErrNoSession) {
|
|
t.Fatalf("toggle on: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestARunningPicomIsToldToReinitialiseNotRestarted(t *testing.T) {
|
|
fakeMachine(t)
|
|
fakeProcess(t, nobody, "picom", "DISPLAY=:1")
|
|
r, err := Restart(false)
|
|
if err != nil || r.Action != "reinitialised" {
|
|
t.Fatalf("%+v, %v", r, err)
|
|
}
|
|
on := true
|
|
if r, err := Toggle(&on); err != nil || !r.Compositing || r.PIDs[0] != nobody {
|
|
t.Fatalf("on while running: %+v, %v", r, err)
|
|
}
|
|
}
|