Pre-release review of v0.9.0..353b4e3 (drag and drop, output/command decoupling, focus flash, hint mode). Three reviewers, 12 findings, all fixed.
Drag and drop
Pre-v3 targets get drop without calling accept (feedback-only before v3).
Destroying the target's last data device clears the target; release then cancels the source instead of reporting a performed drop.
The negotiated action is sent to every target offer; destroying the accepting offer resets negotiation.
Client events that change hit testing (input region, map, resize…) re-route an active drag with a still pointer.
Negative test assertions use protocol barriers instead of fixed sleeps.
Commands and stats
Slot/stash placement tokens are read on the first toplevel map, independent of command draining. The SlotsPending command and its flush path are removed.
Ring and outbox stats sample current occupancy, so a long stall keeps being reported.
Hints and focus flash
Hint targets keep their source window geometry; results and clicks are rejected after a move or resize.
AT-SPI fallback walk stays within its node budget before allocating.
tesseract --list-langs has its own 5 s timeout.
A running focus flash stops when its rect changes.
Docs: accessibility is enabled on the first hint scan.
Performance
No new allocations on hot paths. Zero-allocation tests cover the drag re-hit and flash revalidation; /proc is read once per new toplevel.
Checks
make check, make race, make mocks-check, staticcheck ./...: pass.
Headless e2e: column slot and stash <cmd> placement (stash_index 1), focus flash on column focus and stop on column resize, hint labels on two OCR links and Escape cancel.
Not covered end to end: real client drag and drop (no scriptable DnD client), AT-SPI apps, multi-output.
// newMocklanguageRunner creates a new instance of mocklanguageRunner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
14
+
// The first argument is typically a *testing.T value.
15
+
func newMocklanguageRunner(t interface {
16
+
mock.TestingT
17
+
Cleanup(func())
18
+
}) *mocklanguageRunner {
19
+
if helper, ok := t.(interface{ Helper() }); ok {
20
+
helper.Helper()
21
+
}
22
+
23
+
mock := &mocklanguageRunner{}
24
+
mock.Mock.Test(t)
25
+
26
+
t.Cleanup(func() {
27
+
if helper, ok := t.(interface{ Helper() }); ok {
28
+
helper.Helper()
29
+
}
30
+
mock.AssertExpectations(t)
31
+
})
32
+
33
+
return mock
34
+
}
35
+
36
+
// mocklanguageRunner is an autogenerated mock type for the languageRunner type
// newMocklanguageRunner creates a new instance of mocklanguageRunner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
14
+
// The first argument is typically a *testing.T value.
15
+
func newMocklanguageRunner(t interface {
16
+
mock.TestingT
17
+
Cleanup(func())
18
+
}) *mocklanguageRunner {
19
+
if helper, ok := t.(interface{ Helper() }); ok {
20
+
helper.Helper()
21
+
}
22
+
23
+
mock := &mocklanguageRunner{}
24
+
mock.Mock.Test(t)
25
+
26
+
t.Cleanup(func() {
27
+
if helper, ok := t.(interface{ Helper() }); ok {
28
+
helper.Helper()
29
+
}
30
+
mock.AssertExpectations(t)
31
+
})
32
+
33
+
return mock
34
+
}
35
+
36
+
// mocklanguageRunner is an autogenerated mock type for the languageRunner type