detached 5d1d4d1

refactor(wayland): reset the fired frame queue after the loop

sendFrames resets the queue after sending instead of in a defer, and the queue test drops a frame-owner check the old code already passed.
commit
5d1d4d1e64aac5e24dd3b278c8616e0cc31c3f55
author
brice · · 2026-10-16 14:08 UTC
parent
7898c05
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +4 -9
M internal/adapters/wayland/alloc_hotpath_test.go +0 -3
@@ -151,9 +151,6 @@ func TestFrameQueueKeepsBackingArray(t *testing.T) {
151151 return
152152 }
153153 first, head = queue[:1][0], &queue[:1][0]
154- if len(s.frameOwners) != 0 {
155- t.Errorf("fired queue keeps %d frame owners", len(s.frameOwners))
156- }
157154 })
158155 if first != nil {
159156 t.Fatal("fired queue pins a callback")
@@ -151,9 +151,6 @@ func TestFrameQueueKeepsBackingArray(t *testing.T) {
151 return151 return
152 }152 }
153 first, head = queue[:1][0], &queue[:1][0]153 first, head = queue[:1][0], &queue[:1][0]
154- if len(s.frameOwners) != 0 {
155- t.Errorf("fired queue keeps %d frame owners", len(s.frameOwners))
156- }
157 })154 })
158 if first != nil {155 if first != nil {
159 t.Fatal("fired queue pins a callback")156 t.Fatal("fired queue pins a callback")
M internal/adapters/wayland/frames.go +4 -6
@@ -350,12 +350,6 @@ func (s *Server) sendFrames(name string, flipped bool) {
350350 if len(callbacks) == 0 {
351351 return
352352 }
353- // The queue keeps its backing array for the next frame (an empty queue
354- // reads like an absent one). Nothing below queues a callback.
355- defer func() {
356- clear(callbacks)
357- s.awaiting[name] = callbacks[:0]
358- }()
359353 // done carries the flip's time when the output flips (the frame the
360354 // client drew for is on screen), else now.
361355 ms := uint32(time.Since(s.started).Milliseconds())
@@ -371,6 +365,10 @@ func (s *Server) sendFrames(name string, flipped bool) {
371365 cb.Destroy()
372366 s.frames++
373367 }
368+ // The queue keeps its backing array for the next frame (an empty queue
369+ // reads like an absent one). Nothing above queues a callback.
370+ clear(callbacks)
371+ s.awaiting[name] = callbacks[:0]
374372 }
375373
376374 // framePeriod is one refresh at refreshMilli mHz, 60 Hz when unknown.
@@ -350,12 +350,6 @@ func (s *Server) sendFrames(name string, flipped bool) {
350 if len(callbacks) == 0 {350 if len(callbacks) == 0 {
351 return351 return
352 }352 }
353- // The queue keeps its backing array for the next frame (an empty queue
354- // reads like an absent one). Nothing below queues a callback.
355- defer func() {
356- clear(callbacks)
357- s.awaiting[name] = callbacks[:0]
358- }()
359 // done carries the flip's time when the output flips (the frame the353 // done carries the flip's time when the output flips (the frame the
360 // client drew for is on screen), else now.354 // client drew for is on screen), else now.
361 ms := uint32(time.Since(s.started).Milliseconds())355 ms := uint32(time.Since(s.started).Milliseconds())
@@ -371,6 +365,10 @@ func (s *Server) sendFrames(name string, flipped bool) {
371 cb.Destroy()365 cb.Destroy()
372 s.frames++366 s.frames++
373 }367 }
368+ // The queue keeps its backing array for the next frame (an empty queue
369+ // reads like an absent one). Nothing above queues a callback.
370+ clear(callbacks)
371+ s.awaiting[name] = callbacks[:0]
374 }372 }
375 373
376 // framePeriod is one refresh at refreshMilli mHz, 60 Hz when unknown.374 // framePeriod is one refresh at refreshMilli mHz, 60 Hz when unknown.

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