v0.4.0 b6be3a8

viewport_queue_test.go RawHistoryFolder

1package wayland
2
3import (
4	"fmt"
5	"testing"
6	"time"
7
8	"github.com/bnema/go-wayland-bindings/server/viewporter"
9	"github.com/bnema/go-wayland-bindings/server/wayland"
10)
11
12// A queued attachment that was destroyed cannot apply either its new crop or
13// its scale to the buffer retained by a synchronized child.
14func TestQueuedDestroyedAttachmentRetainsScaleAndCrop(t *testing.T) {
15	s, events, _, contents, dir := contentServer(t)
16	c := protocolClient(t, s, dir)
17	w, root, _ := surfaceMapper(t, c, events)()
18	drainContents(contents)
19	comp := bindVersion(t, c, "wl_compositor", 4)
20	subc := bindProtocol(t, c, "wl_subcompositor")
21	vpm := bindProtocol(t, c, "wp_viewporter")
22	child := c.AllocateID()
23	requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, child)
24	registerProtocol(t, c, child)
25	sub := c.AllocateID()
26	requestProtocol(t, c, subc, wayland.SubcompositorRequestGetSubsurface, sub, child, root)
27	registerProtocol(t, c, sub)
28	vp := c.AllocateID()
29	requestProtocol(t, c, vpm, viewporter.WpViewporterRequestGetViewport, vp, child)
30	registerProtocol(t, c, vp)
31	retained, discarded := shmBuffer(t, c), shmBuffer(t, c)
32	requestProtocol(t, c, vp, viewporter.WpViewportRequestSetSource, int32(0), int32(0), int32(256), int32(256))
33	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, retained, int32(0), int32(0))
34	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
35	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
36	roundtrip(t, c)
37	drainContents(contents)
38	requestProtocol(t, c, child, wayland.SurfaceRequestSetBufferScale, int32(2))
39	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, discarded, int32(0), int32(0))
40	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
41	requestProtocol(t, c, discarded, wayland.BufferRequestDestroy)
42	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
43	roundtrip(t, c)
44	deadline := time.After(2 * time.Second)
45	for {
46		select {
47		case got := <-contents:
48			if got.ID != w.ID {
49				continue
50			}
51			if len(got.Children) != 1 || got.Children[0].Source != ([4]float32{0, 0, 1, 1}) || got.Children[0].LogicalW != 1 {
52				t.Fatalf("retained buffer changed: %+v", got.Children)
53			}
54			return
55		case <-deadline:
56			t.Fatal("retained publication missing")
57		}
58	}
59}
60
61// A scale-only commit validates the retained buffer; same-buffer reattaches
62// still advance its version.
63func TestScaleOnlyRetainedViewportAndSameBufferReattach(t *testing.T) {
64	s, events, _, contents, dir := contentServer(t)
65	c := protocolClient(t, s, dir)
66	w, root, _ := surfaceMapper(t, c, events)()
67	drainContents(contents)
68	comp := bindVersion(t, c, "wl_compositor", 4)
69	subc := bindProtocol(t, c, "wl_subcompositor")
70	vpm := bindProtocol(t, c, "wp_viewporter")
71	child := c.AllocateID()
72	requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, child)
73	registerProtocol(t, c, child)
74	sub := c.AllocateID()
75	requestProtocol(t, c, subc, wayland.SubcompositorRequestGetSubsurface, sub, child, root)
76	registerProtocol(t, c, sub)
77	vp := c.AllocateID()
78	requestProtocol(t, c, vpm, viewporter.WpViewporterRequestGetViewport, vp, child)
79	registerProtocol(t, c, vp)
80	buf := shmBuffer(t, c)
81	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
82	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
83	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
84	roundtrip(t, c)
85	var first uint64
86	deadline := time.After(2 * time.Second)
87	for first == 0 {
88		select {
89		case got := <-contents:
90			if got.ID == w.ID && len(got.Children) == 1 {
91				first = got.Children[0].Version
92			}
93		case <-deadline:
94			t.Fatal("initial child missing")
95		}
96	}
97	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
98	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
99	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
100	roundtrip(t, c)
101	deadline = time.After(2 * time.Second)
102	for {
103		select {
104		case got := <-contents:
105			if got.ID != w.ID || len(got.Children) != 1 {
106				continue
107			}
108			if got.Children[0].Version != first+1 {
109				t.Fatalf("same-buffer version %d, want %d", got.Children[0].Version, first+1)
110			}
111			goto reattached
112		case <-deadline:
113			t.Fatal("same-buffer publication missing")
114		}
115	}
116reattached:
117	requestProtocol(t, c, vp, viewporter.WpViewportRequestSetSource, int32(0), int32(0), int32(256), int32(256))
118	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
119	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
120	roundtrip(t, c)
121	requestProtocol(t, c, child, wayland.SurfaceRequestSetBufferScale, int32(2))
122	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
123	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
124	expectProtocolError(t, c, vp, uint32(viewporter.WpViewportErrorOutOfBuffer))
125}
126
127// A destroyed queued buffer does not suppress the later, valid attachment.
128func TestQueuedDestroyedThenNewBuffer(t *testing.T) {
129	s, events, _, contents, dir := contentServer(t)
130	c := protocolClient(t, s, dir)
131	w, root, _ := surfaceMapper(t, c, events)()
132	drainContents(contents)
133	comp := bindVersion(t, c, "wl_compositor", 4)
134	subc := bindProtocol(t, c, "wl_subcompositor")
135	vpm := bindProtocol(t, c, "wp_viewporter")
136	child := c.AllocateID()
137	requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, child)
138	registerProtocol(t, c, child)
139	sub := c.AllocateID()
140	requestProtocol(t, c, subc, wayland.SubcompositorRequestGetSubsurface, sub, child, root)
141	registerProtocol(t, c, sub)
142	vp := c.AllocateID()
143	requestProtocol(t, c, vpm, viewporter.WpViewporterRequestGetViewport, vp, child)
144	registerProtocol(t, c, vp)
145	first, destroyed, next := shmBuffer(t, c), shmBuffer(t, c), shmBuffer(t, c)
146	requestProtocol(t, c, vp, viewporter.WpViewportRequestSetSource, int32(0), int32(0), int32(256), int32(256))
147	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, first, int32(0), int32(0))
148	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
149	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
150	roundtrip(t, c)
151	drainContents(contents)
152	requestProtocol(t, c, child, wayland.SurfaceRequestSetBufferScale, int32(2))
153	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, destroyed, int32(0), int32(0))
154	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
155	requestProtocol(t, c, destroyed, wayland.BufferRequestDestroy)
156	requestProtocol(t, c, child, wayland.SurfaceRequestSetBufferScale, int32(1))
157	requestProtocol(t, c, child, wayland.SurfaceRequestAttach, next, int32(0), int32(0))
158	requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
159	requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
160	roundtrip(t, c)
161	deadline := time.After(2 * time.Second)
162	for {
163		select {
164		case got := <-contents:
165			if got.ID != w.ID || len(got.Children) != 1 {
166				continue
167			}
168			ch := got.Children[0]
169			if ch.Version < 2 {
170				continue
171			}
172			if ch.Version != 2 || ch.LogicalW != 1 || ch.Source != ([4]float32{0, 0, 1, 1}) {
173				t.Fatalf("later buffer did not apply: %+v", ch)
174			}
175			return
176		case <-deadline:
177			t.Fatal("later buffer not published")
178		}
179	}
180}
181
182// A destroyed viewport in an earlier queued update must not replace the new
183// viewport or steal its protocol errors.
184func TestQueuedViewportRecreatedErrorObject(t *testing.T) {
185	for _, oversized := range []bool{false, true} {
186		t.Run(fmt.Sprintf("oversized=%v", oversized), func(t *testing.T) {
187			s, events, _, contents, dir := contentServer(t)
188			c := protocolClient(t, s, dir)
189			_, root, _ := surfaceMapper(t, c, events)()
190			drainContents(contents)
191			comp := bindVersion(t, c, "wl_compositor", 4)
192			subc := bindProtocol(t, c, "wl_subcompositor")
193			vpm := bindProtocol(t, c, "wp_viewporter")
194			child := c.AllocateID()
195			requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, child)
196			registerProtocol(t, c, child)
197			sub := c.AllocateID()
198			requestProtocol(t, c, subc, wayland.SubcompositorRequestGetSubsurface, sub, child, root)
199			registerProtocol(t, c, sub)
200			old := c.AllocateID()
201			requestProtocol(t, c, vpm, viewporter.WpViewporterRequestGetViewport, old, child)
202			registerProtocol(t, c, old)
203			buf := shmBuffer(t, c)
204			requestProtocol(t, c, old, viewporter.WpViewportRequestSetSource, int32(0), int32(0), int32(256), int32(256))
205			requestProtocol(t, c, child, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
206			requestProtocol(t, c, child, wayland.SurfaceRequestCommit) // old viewport queued
207			requestProtocol(t, c, old, viewporter.WpViewportRequestDestroy)
208			current := c.AllocateID()
209			requestProtocol(t, c, vpm, viewporter.WpViewporterRequestGetViewport, current, child)
210			registerProtocol(t, c, current)
211			width := int32(256)
212			if oversized {
213				width = 512
214			}
215			requestProtocol(t, c, current, viewporter.WpViewportRequestSetSource, int32(0), int32(0), width, int32(256))
216			requestProtocol(t, c, child, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
217			requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
218			requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
219			if oversized {
220				expectProtocolError(t, c, current, uint32(viewporter.WpViewportErrorOutOfBuffer))
221				return
222			}
223			roundtrip(t, c)
224			requestProtocol(t, c, child, wayland.SurfaceRequestCommit)
225			requestProtocol(t, c, root, wayland.SurfaceRequestCommit)
226			roundtrip(t, c)
227			deadline := time.After(2 * time.Second)
228			for {
229				select {
230				case got := <-contents:
231					if len(got.Children) == 1 && got.Children[0].Source == ([4]float32{0, 0, 1, 1}) {
232						return
233					}
234				case <-deadline:
235					t.Fatal("new valid viewport not applied")
236				}
237			}
238		})
239	}
240}

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