detached fb82a5b

test(wayland): cover the first-size report of output-sized toplevels

commit
fb82a5ba14a385f0f2aaedfadbeaaacda5c9c89f
author
brice · · 2026-10-22 19:47 UTC
parent
43dcf6e
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +59 -0
A internal/adapters/wayland/legacy_fullscreen_test.go +59 -0
@@ -0,0 +1,59 @@
1+package wayland
2+
3+import (
4+ "context"
5+ "testing"
6+ "time"
7+
8+ "github.com/bnema/neferwl/internal/adapters/logging"
9+ "github.com/bnema/neferwl/internal/ports"
10+)
11+
12+// outputSizedServer runs a server whose only output is w×h logical.
13+func outputSizedServer(t *testing.T, w, h int) (*Server, chan ports.ClientEvent, string) {
14+ t.Helper()
15+ dir := t.TempDir()
16+ events := make(chan ports.ClientEvent, 16)
17+ out := ports.Layout{{Info: ports.OutputInfo{Name: "HEADLESS-1", Width: w, Height: h}, Width: w, Height: h, Scale: 1}}
18+ s, err := New(Options{RuntimeDir: dir, Outputs: out}, Channels{Events: events, Commands: make(chan ports.ClientCommand, 16)}, logging.For(context.Background(), "wayland"))
19+ if err != nil {
20+ t.Fatal(err)
21+ }
22+ ctx, cancel := context.WithCancel(context.Background())
23+ done := make(chan error, 1)
24+ go func() { done <- s.Run(ctx) }()
25+ t.Cleanup(func() {
26+ cancel()
27+ <-done
28+ })
29+ return s, events, dir
30+}
31+
32+// A tiled toplevel whose first committed size is its output's size reports
33+// it once (core then fullscreens it); a smaller one reports nothing.
34+func TestTiledFirstSizeAtOutputSizeEmitsResized(t *testing.T) {
35+ s, events, dir := outputSizedServer(t, 1, 1)
36+ c := protocolClient(t, s, dir)
37+ w := toplevelMapper(t, c, events)()
38+ if w.Floating {
39+ t.Fatal("expected a tiled window")
40+ }
41+ ev := waitEvent(t, events, 2*time.Second)
42+ if r, ok := ev.(ports.WindowResized); !ok || r.ID != w.ID || r.Width != 1 || r.Height != 1 {
43+ t.Fatalf("got %#v, want WindowResized 1x1 for %d", ev, w.ID)
44+ }
45+}
46+
47+func TestTiledSmallerThanOutputEmitsNoResized(t *testing.T) {
48+ s, events, dir := outputSizedServer(t, 2, 2)
49+ c := protocolClient(t, s, dir)
50+ toplevelMapper(t, c, events)()
51+ if err := c.Roundtrip(); err != nil {
52+ t.Fatal(err)
53+ }
54+ select {
55+ case ev := <-events:
56+ t.Fatalf("unexpected event %#v", ev)
57+ case <-time.After(200 * time.Millisecond):
58+ }
59+}
@@ -0,0 +1,59 @@
1+package wayland
2+
3+import (
4+ "context"
5+ "testing"
6+ "time"
7+
8+ "github.com/bnema/neferwl/internal/adapters/logging"
9+ "github.com/bnema/neferwl/internal/ports"
10+)
11+
12+// outputSizedServer runs a server whose only output is w×h logical.
13+func outputSizedServer(t *testing.T, w, h int) (*Server, chan ports.ClientEvent, string) {
14+ t.Helper()
15+ dir := t.TempDir()
16+ events := make(chan ports.ClientEvent, 16)
17+ out := ports.Layout{{Info: ports.OutputInfo{Name: "HEADLESS-1", Width: w, Height: h}, Width: w, Height: h, Scale: 1}}
18+ s, err := New(Options{RuntimeDir: dir, Outputs: out}, Channels{Events: events, Commands: make(chan ports.ClientCommand, 16)}, logging.For(context.Background(), "wayland"))
19+ if err != nil {
20+ t.Fatal(err)
21+ }
22+ ctx, cancel := context.WithCancel(context.Background())
23+ done := make(chan error, 1)
24+ go func() { done <- s.Run(ctx) }()
25+ t.Cleanup(func() {
26+ cancel()
27+ <-done
28+ })
29+ return s, events, dir
30+}
31+
32+// A tiled toplevel whose first committed size is its output's size reports
33+// it once (core then fullscreens it); a smaller one reports nothing.
34+func TestTiledFirstSizeAtOutputSizeEmitsResized(t *testing.T) {
35+ s, events, dir := outputSizedServer(t, 1, 1)
36+ c := protocolClient(t, s, dir)
37+ w := toplevelMapper(t, c, events)()
38+ if w.Floating {
39+ t.Fatal("expected a tiled window")
40+ }
41+ ev := waitEvent(t, events, 2*time.Second)
42+ if r, ok := ev.(ports.WindowResized); !ok || r.ID != w.ID || r.Width != 1 || r.Height != 1 {
43+ t.Fatalf("got %#v, want WindowResized 1x1 for %d", ev, w.ID)
44+ }
45+}
46+
47+func TestTiledSmallerThanOutputEmitsNoResized(t *testing.T) {
48+ s, events, dir := outputSizedServer(t, 2, 2)
49+ c := protocolClient(t, s, dir)
50+ toplevelMapper(t, c, events)()
51+ if err := c.Roundtrip(); err != nil {
52+ t.Fatal(err)
53+ }
54+ select {
55+ case ev := <-events:
56+ t.Fatalf("unexpected event %#v", ev)
57+ case <-time.After(200 * time.Millisecond):
58+ }
59+}

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