damage_test.go RawHistoryFolder

1package wayland
2
3import (
4	"testing"
5	"time"
6
7	"github.com/bnema/go-wayland-bindings/server/wayland"
8	"github.com/bnema/go-wayland-bindings/server/xdgshell"
9	"github.com/bnema/neferwl/internal/ports"
10	"golang.org/x/sys/unix"
11)
12
13// Damage reaches the renderer in buffer pixels, per content, with the
14// window's recent history; a new buffer without damage is a full change.
15func TestDamageHistory(t *testing.T) {
16	s, events, _, contents, dir := contentServer(t)
17	c := protocolClient(t, s, dir)
18	comp := bindVersion(t, c, "wl_compositor", 4)
19	wm := bindProtocol(t, c, "xdg_wm_base")
20	shm := bindProtocol(t, c, "wl_shm")
21	registerProtocol(t, c, shm)
22	surf, xdg, top := c.AllocateID(), c.AllocateID(), c.AllocateID()
23	requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, surf)
24	registerProtocol(t, c, surf)
25	requestProtocol(t, c, wm, xdgshell.WmBaseRequestGetXdgSurface, xdg, surf)
26	serials := make(chan uint32, 8)
27	xp := &configureProxy{serial: serials}
28	xp.SetID(xdg)
29	registerWireProxy(c, xp)
30	registerProtocol(t, c, top)
31	requestProtocol(t, c, xdg, xdgshell.SurfaceRequestGetToplevel, top)
32	requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
33	if err := c.Roundtrip(); err != nil {
34		t.Fatal(err)
35	}
36	requestProtocol(t, c, xdg, xdgshell.SurfaceRequestAckConfigure, <-serials)
37	fd, err := unix.MemfdCreate("damage", 0)
38	if err != nil {
39		t.Fatal(err)
40	}
41	defer unix.Close(fd)
42	if err := unix.Ftruncate(fd, 2*16*16*4); err != nil {
43		t.Fatal(err)
44	}
45	pool := c.AllocateID()
46	registerProtocol(t, c, pool)
47	if err := wireRequest(c, shm, uint16(wayland.ShmRequestCreatePool), []int{fd}, pool, int32(2*16*16*4)); err != nil {
48		t.Fatal(err)
49	}
50	bufs := [2]uint32{c.AllocateID(), c.AllocateID()}
51	for i, b := range bufs {
52		registerProtocol(t, c, b)
53		requestProtocol(t, c, pool, wayland.ShmPoolRequestCreateBuffer, b, int32(i*16*16*4), int32(16), int32(16), int32(64), uint32(0))
54	}
55	next := func() ports.SurfaceContent {
56		t.Helper()
57		if err := c.Roundtrip(); err != nil {
58			t.Fatal(err)
59		}
60		deadline := time.After(2 * time.Second)
61		for {
62			select {
63			case got := <-contents:
64				if got.Width == 16 {
65					return got
66				}
67			case <-deadline:
68				t.Fatal("no content")
69			}
70		}
71	}
72	// A new size: full.
73	requestProtocol(t, c, surf, wayland.SurfaceRequestAttach, bufs[0], int32(0), int32(0))
74	requestProtocol(t, c, surf, wayland.SurfaceRequestDamageBuffer, int32(0), int32(0), int32(4), int32(4))
75	requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
76	mapped(t, events, 2*time.Second)
77	first := next()
78	if h := first.DamageHistory; len(h) == 0 || h[len(h)-1].Seq != first.Seq || !h[len(h)-1].Full {
79		t.Fatalf("resize: %+v", h)
80	}
81	// Buffer and surface damage, clipped to the buffer.
82	requestProtocol(t, c, surf, wayland.SurfaceRequestAttach, bufs[1], int32(0), int32(0))
83	requestProtocol(t, c, surf, wayland.SurfaceRequestDamageBuffer, int32(2), int32(3), int32(4), int32(5))
84	requestProtocol(t, c, surf, wayland.SurfaceRequestDamage, int32(14), int32(14), int32(1<<30), int32(1<<30))
85	requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
86	second := next()
87	got, ok := second.DamageSince(first.Seq)
88	want := []ports.Rect{{X: 2, Y: 3, W: 4, H: 5}, {X: 14, Y: 14, W: 2, H: 2}}
89	if !ok || len(got) != 2 || got[0] != want[0] || got[1] != want[1] {
90		t.Fatalf("damage %v %v", got, ok)
91	}
92	// Same buffer size, new logical size (buffer scale): full.
93	requestProtocol(t, c, surf, wayland.SurfaceRequestAttach, bufs[0], int32(0), int32(0))
94	requestProtocol(t, c, surf, wayland.SurfaceRequestSetBufferScale, int32(2))
95	requestProtocol(t, c, surf, wayland.SurfaceRequestDamageBuffer, int32(0), int32(0), int32(1), int32(1))
96	requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
97	scaled := next()
98	if _, ok := scaled.DamageSince(second.Seq); ok {
99		t.Fatal("logical resize kept partial damage")
100	}
101	second = scaled
102	// No damage with a new buffer: full.
103	requestProtocol(t, c, surf, wayland.SurfaceRequestAttach, bufs[0], int32(0), int32(0))
104	requestProtocol(t, c, surf, wayland.SurfaceRequestCommit)
105	third := next()
106	if _, ok := third.DamageSince(second.Seq); ok {
107		t.Fatal("undamaged new buffer taken as unchanged")
108	}
109}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close