capture_window_test.go RawHistoryFolder

1package core_test
2
3import (
4	"testing"
5
6	"github.com/bnema/neferwl/internal/ports"
7)
8
9// A window session renders the window alone, at its client size, from the
10// first frame and whatever workspace is shown; once the window leaves the
11// screen it is configured Captured, and the session ends when it goes.
12func TestCaptureWindowSession(t *testing.T) {
13	r := captureCore(t)
14	r.client <- ports.WindowMapped{ID: 1}
15	scene(t, r.scenes)
16	r.client <- ports.WindowMapped{ID: 2}
17	scene(t, r.scenes)
18	var ws []ports.WorkspaceInfo
19	for len(ws) < 2 {
20		ws = receive(t, r.workspaces).Outputs[0].Workspaces
21	}
22	r.client <- ports.CaptureSessionOpen{ID: 1, Window: 1}
23	st := r.state(t)
24	if !st.Active || !st.Hidden || st.Output != "OUT-1" || st.Rect.W <= 0 || st.Rect.H <= 0 || st.Rect.X != 0 || st.Rect.Y != 0 {
25		t.Fatalf("state %+v", st)
26	}
27	s := r.sceneWith(t, true)
28	if s.Capture.Window != 1 || s.Capture.Workspace != 0 || s.CaptureScene == nil {
29		t.Fatalf("capture %+v scene %v", s.Capture, s.CaptureScene)
30	}
31	c := s.CaptureScene
32	if c.OutputWidth != st.Rect.W || c.OutputHeight != st.Rect.H || len(c.Windows) != 1 || c.Windows[0].ID != 1 || c.Windows[0].Rect != (ports.Rect{W: st.Rect.W, H: st.Rect.H}) {
33		t.Fatalf("window scene %+v", c)
34	}
35
36	// Another workspace on screen: window 1 is hidden yet kept drawing.
37	r.client <- ports.WorkspaceActivate{IDs: []uint64{ws[1].ID}}
38	for {
39		v := r.configureOf(t, 1)
40		if !v.Visible {
41			if !v.Captured || v.Width != st.Rect.W {
42				t.Fatalf("hidden captured window %+v", v)
43			}
44			break
45		}
46	}
47	for {
48		if s = scene(t, r.scenes); s.Capture != nil && s.Capture.Window == 1 && s.CaptureScene != nil {
49			break
50		}
51	}
52
53	// The window goes: the session ends with window-gone.
54	r.client <- ports.WindowUnmapped{ID: 1}
55	for {
56		if st = r.state(t); st.Reason != ports.CaptureReasonNone {
57			break
58		}
59	}
60	if st.Reason != ports.CaptureReasonWindowGone {
61		t.Fatalf("end %+v", st)
62	}
63}
64
65// The indicator of a window session is a pill on its output, and the
66// window's outline while it is on screen.
67func TestCaptureWindowIndicator(t *testing.T) {
68	r := captureCore(t)
69	r.client <- ports.WindowMapped{ID: 1}
70	scene(t, r.scenes)
71	r.client <- ports.CaptureSessionOpen{ID: 1, Window: 1}
72	r.state(t)
73	r.client <- ports.CaptureFrameTaken{Session: 1, Window: 1}
74	for {
75		s := scene(t, r.scenes)
76		pill, border := false, false
77		for _, m := range s.CaptureIndicators {
78			pill = pill || m.Pill
79			border = border || !m.Pill
80		}
81		if pill && border {
82			return
83		}
84	}
85}
86
87// A captured window on a hidden workspace follows that workspace's layout:
88// when a sibling closes, the capture and its configure grow together.
89func TestCaptureWindowHiddenReflow(t *testing.T) {
90	r := captureCore(t)
91	r.client <- ports.WindowMapped{ID: 1}
92	scene(t, r.scenes)
93	r.client <- ports.WindowMapped{ID: 2}
94	scene(t, r.scenes)
95	var ws []ports.WorkspaceInfo
96	for len(ws) < 2 {
97		ws = receive(t, r.workspaces).Outputs[0].Workspaces
98	}
99	r.client <- ports.CaptureSessionOpen{ID: 1, Window: 1}
100	before := r.state(t)
101	r.client <- ports.WorkspaceActivate{IDs: []uint64{ws[1].ID}}
102	for {
103		if v := r.configureOf(t, 1); !v.Visible {
104			break
105		}
106	}
107	r.client <- ports.WindowUnmapped{ID: 2}
108	var after ports.CaptureSessionState
109	for {
110		if after = r.state(t); after.Rect != before.Rect {
111			break
112		}
113	}
114	for {
115		v := r.configureOf(t, 1)
116		if v.Width == after.Rect.W && v.Height == after.Rect.H {
117			if v.Visible || !v.Captured {
118				t.Fatalf("reflowed hidden window %+v", v)
119			}
120			return
121		}
122	}
123}

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