1package wayland
2
3import (
4 "math"
5 "testing"
6 "time"
7
8 "github.com/bnema/go-wayland-bindings/server/alphamodifier"
9 "github.com/bnema/go-wayland-bindings/server/wayland"
10 "github.com/bnema/neferwl/internal/ports"
11)
12
13// contentMatching waits for a content of the window that matches want.
14func contentMatching(t *testing.T, contents <-chan ports.SurfaceContent, id ports.WindowID, want func(ports.SurfaceContent) bool) ports.SurfaceContent {
15 t.Helper()
16 deadline := time.After(2 * time.Second)
17 for {
18 select {
19 case c := <-contents:
20 if c.ID == id && want(c) {
21 return c
22 }
23 case <-deadline:
24 t.Fatal("no matching content")
25 }
26 }
27}
28
29// The multiplier is double-buffered, fades the content and makes it
30// translucent; destroying the modifier restores the surface on commit.
31func TestAlphaModifier(t *testing.T) {
32 s, events, _, contents, dir := contentServer(t)
33 c := protocolClient(t, s, dir)
34 w, surf, _ := surfaceMapper(t, c, events)()
35 comp := bindProtocol(t, c, "wl_compositor")
36 region := c.AllocateID()
37 registerProtocol(t, c, region)
38 requestProtocol(t, c, comp, wayland.CompositorRequestCreateRegion, region)
39 requestProtocol(t, c, region, wayland.RegionRequestAdd, int32(0), int32(0), int32(1), int32(1))
40 requestProtocol(t, c, surf, wayland.SurfaceRequestSetOpaqueRegion, region)
41 requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
42 contentMatching(t, contents, w.ID, func(c ports.SurfaceContent) bool { return c.Opaque })
43
44 manager := bindProtocol(t, c, "wp_alpha_modifier_v1")
45 mod := c.AllocateID()
46 registerProtocol(t, c, mod)
47 requestProtocol(t, c, manager, alphamodifier.WpAlphaModifierV1RequestGetSurface, mod, surf)
48 requestProtocol(t, c, mod, alphamodifier.WpAlphaModifierSurfaceV1RequestSetMultiplier, uint32(math.MaxUint32/4))
49 requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
50 got := contentMatching(t, contents, w.ID, func(c ports.SurfaceContent) bool { return c.Fade > 0 })
51 if got.Opaque || math.Abs(float64(got.Fade)-0.75) > 1e-6 {
52 t.Fatalf("faded content %+v", got)
53 }
54
55 requestProtocol(t, c, mod, alphamodifier.WpAlphaModifierSurfaceV1RequestDestroy)
56 requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
57 got = contentMatching(t, contents, w.ID, func(c ports.SurfaceContent) bool { return c.Fade == 0 })
58 if !got.Opaque {
59 t.Fatalf("restored content %+v", got)
60 }
61
62 // A second modifier on the same surface is a protocol error.
63 mod2, mod3 := c.AllocateID(), c.AllocateID()
64 registerProtocol(t, c, mod2)
65 registerProtocol(t, c, mod3)
66 requestProtocol(t, c, manager, alphamodifier.WpAlphaModifierV1RequestGetSurface, mod2, surf)
67 requestProtocol(t, c, manager, alphamodifier.WpAlphaModifierV1RequestGetSurface, mod3, surf)
68 if err := c.Roundtrip(); err == nil {
69 t.Fatal("second modifier accepted")
70 }
71}
72
73func TestFade(t *testing.T) {
74 for factor, want := range map[uint32]float32{0: 1, math.MaxUint32: 0} {
75 if got := fade(factor); got != want {
76 t.Fatalf("fade(%d) = %v, want %v", factor, got, want)
77 }
78 }
79}