detached 4bb8af0

test(protocol): require complete headless feedback and data-device bind

commit
4bb8af06a47765165a745336b285035bc9a60ecc
author
brice · · 2026-09-28 08:00 UTC
parent
090bcc4
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +8 -4
M protocol/headless_test.go +8 -4
@@ -103,6 +103,8 @@ func TestHeadlessNeferWL(t *testing.T) {
103103 }
104104 syncManager := drmsyncobj.NewWpLinuxDrmSyncobjManager(d.Context())
105105 bind(drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, syncManager)
106+ dataManager := core.NewDataDeviceManager(d.Context())
107+ bind(core.DataDeviceManagerInterface, 4, dataManager)
106108 vp := viewporter.NewWpViewporter(d.Context())
107109 bind(viewporter.WpViewporterInterface, 1, vp)
108110 if g, ok := d.Registry().FindGlobal(fractionalscale.WpFractionalScaleManagerInterface); ok {
@@ -127,19 +129,20 @@ func TestHeadlessNeferWL(t *testing.T) {
127129 noerr(t, e)
128130 ss, e := syncManager.GetSurface(surface)
129131 noerr(t, e)
130- configured, done := false, false
132+ configured, done, mainDevice, tableOK := false, false, false, false
131133 top.OnConfigure(func(w, h int32, states []byte) { t.Logf("xdg_toplevel.configure %dx%d", w, h) })
132134 xs.OnConfigure(func(serial uint32) {
133135 noerr(t, xs.AckConfigure(serial))
134136 configured = true
135137 t.Logf("xdg_surface.configure ack=%d", serial)
136138 })
137- feedback.OnMainDevice(func(b []byte) { t.Logf("main_device=%x", b) })
139+ feedback.OnMainDevice(func(b []byte) { mainDevice = len(b) == 8; t.Logf("main_device=%x", b) })
138140 feedback.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) {
139141 entries, e := linuxdmabuf.ReadFormatTable(fd, size)
140142 if e != nil {
141143 t.Errorf("format table: %v", e)
142144 } else {
145+ tableOK = len(entries) > 0
143146 t.Logf("format-table entries=%d", len(entries))
144147 }
145148 })
@@ -151,8 +154,8 @@ func TestHeadlessNeferWL(t *testing.T) {
151154 t.Fatalf("dispatch: %v\n%s", e, headlessLog(log))
152155 }
153156 }
154- if !configured || !done {
155- t.Fatalf("configure=%t feedback=%t: %v\n%s", configured, done, ctx.Err(), headlessLog(log))
157+ if !configured || !done || !mainDevice || !tableOK {
158+ t.Fatalf("configure=%t feedback=%t main_device=%t table=%t: %v\n%s", configured, done, mainDevice, tableOK, ctx.Err(), headlessLog(log))
156159 }
157160 noerr(t, surface.Commit())
158161 // Drop all child objects while their parents are still alive.
@@ -162,6 +165,7 @@ func TestHeadlessNeferWL(t *testing.T) {
162165 noerr(t, xs.Destroy())
163166 noerr(t, surface.Destroy())
164167 noerr(t, vp.Destroy())
168+ noerr(t, dataManager.Release())
165169 noerr(t, syncManager.Destroy())
166170 noerr(t, dm.Destroy())
167171 noerr(t, wm.Destroy())
@@ -103,6 +103,8 @@ func TestHeadlessNeferWL(t *testing.T) {
103 }103 }
104 syncManager := drmsyncobj.NewWpLinuxDrmSyncobjManager(d.Context())104 syncManager := drmsyncobj.NewWpLinuxDrmSyncobjManager(d.Context())
105 bind(drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, syncManager)105 bind(drmsyncobj.WpLinuxDrmSyncobjManagerInterface, 1, syncManager)
106+ dataManager := core.NewDataDeviceManager(d.Context())
107+ bind(core.DataDeviceManagerInterface, 4, dataManager)
106 vp := viewporter.NewWpViewporter(d.Context())108 vp := viewporter.NewWpViewporter(d.Context())
107 bind(viewporter.WpViewporterInterface, 1, vp)109 bind(viewporter.WpViewporterInterface, 1, vp)
108 if g, ok := d.Registry().FindGlobal(fractionalscale.WpFractionalScaleManagerInterface); ok {110 if g, ok := d.Registry().FindGlobal(fractionalscale.WpFractionalScaleManagerInterface); ok {
@@ -127,19 +129,20 @@ func TestHeadlessNeferWL(t *testing.T) {
127 noerr(t, e)129 noerr(t, e)
128 ss, e := syncManager.GetSurface(surface)130 ss, e := syncManager.GetSurface(surface)
129 noerr(t, e)131 noerr(t, e)
130- configured, done := false, false132+ configured, done, mainDevice, tableOK := false, false, false, false
131 top.OnConfigure(func(w, h int32, states []byte) { t.Logf("xdg_toplevel.configure %dx%d", w, h) })133 top.OnConfigure(func(w, h int32, states []byte) { t.Logf("xdg_toplevel.configure %dx%d", w, h) })
132 xs.OnConfigure(func(serial uint32) {134 xs.OnConfigure(func(serial uint32) {
133 noerr(t, xs.AckConfigure(serial))135 noerr(t, xs.AckConfigure(serial))
134 configured = true136 configured = true
135 t.Logf("xdg_surface.configure ack=%d", serial)137 t.Logf("xdg_surface.configure ack=%d", serial)
136 })138 })
137- feedback.OnMainDevice(func(b []byte) { t.Logf("main_device=%x", b) })139+ feedback.OnMainDevice(func(b []byte) { mainDevice = len(b) == 8; t.Logf("main_device=%x", b) })
138 feedback.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) {140 feedback.OnFormatTable(func(fd *wlturbo.OwnedFD, size uint32) {
139 entries, e := linuxdmabuf.ReadFormatTable(fd, size)141 entries, e := linuxdmabuf.ReadFormatTable(fd, size)
140 if e != nil {142 if e != nil {
141 t.Errorf("format table: %v", e)143 t.Errorf("format table: %v", e)
142 } else {144 } else {
145+ tableOK = len(entries) > 0
143 t.Logf("format-table entries=%d", len(entries))146 t.Logf("format-table entries=%d", len(entries))
144 }147 }
145 })148 })
@@ -151,8 +154,8 @@ func TestHeadlessNeferWL(t *testing.T) {
151 t.Fatalf("dispatch: %v\n%s", e, headlessLog(log))154 t.Fatalf("dispatch: %v\n%s", e, headlessLog(log))
152 }155 }
153 }156 }
154- if !configured || !done {157+ if !configured || !done || !mainDevice || !tableOK {
155- t.Fatalf("configure=%t feedback=%t: %v\n%s", configured, done, ctx.Err(), headlessLog(log))158+ t.Fatalf("configure=%t feedback=%t main_device=%t table=%t: %v\n%s", configured, done, mainDevice, tableOK, ctx.Err(), headlessLog(log))
156 }159 }
157 noerr(t, surface.Commit())160 noerr(t, surface.Commit())
158 // Drop all child objects while their parents are still alive.161 // Drop all child objects while their parents are still alive.
@@ -162,6 +165,7 @@ func TestHeadlessNeferWL(t *testing.T) {
162 noerr(t, xs.Destroy())165 noerr(t, xs.Destroy())
163 noerr(t, surface.Destroy())166 noerr(t, surface.Destroy())
164 noerr(t, vp.Destroy())167 noerr(t, vp.Destroy())
168+ noerr(t, dataManager.Release())
165 noerr(t, syncManager.Destroy())169 noerr(t, syncManager.Destroy())
166 noerr(t, dm.Destroy())170 noerr(t, dm.Destroy())
167 noerr(t, wm.Destroy())171 noerr(t, wm.Destroy())

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 1

Tags 8

↑↓ moveenter openesc close