scene.go RawHistoryFolder

1package ports
2
3import "slices"
4
5// Scene carries core → renderer immutable snapshots with fresh Windows slices,
6// one per output. Rects and the output size are logical and local to the
7// output; the renderer multiplies by Scale.
8type Scene struct {
9	// Security is the owner epoch captured when this scene was published.
10	// Output owners reject stale scenes rather than showing a queued desktop
11	// or accepting old locker buffers across acquisition/release.
12	Security                  SecurityState
13	Output                    string
14	Seq                       uint64
15	OutputWidth, OutputHeight int
16	Scale                     float64
17	// Transform is how the output target holds this scene
18	// (wl_output.transform); 0 for capture child scenes. OutputWidth and
19	// OutputHeight are already in the transformed (logical) orientation.
20	Transform BufferTransform
21	// Off turns the display off (output power management): nothing is
22	// drawn until a scene without it.
23	Off        bool
24	Background string
25	Border     Border
26	// WorkspaceClip bounds workspace windows, their popups and separators
27	// in logical output coordinates. Zero inherits the full output. Layers
28	// remain output-wide; overview previews do not use this clip.
29	WorkspaceClip Rect
30	// TileInset is what exclusive layers (panels) and a workspace size
31	// override take from the output's edges: tiles (SceneWindow.Tile) and
32	// their lines are drawn only in what is left, the usable area
33	// (TileArea). A tile is never drawn over a panel, whatever its layer;
34	// insets covering the output leave no tile drawn. Zero: the usable
35	// area is the whole output (and the overview, capture scenes).
36	TileInset Insets
37	// Dim darkens the background, bottom layers and tiles (tile lines
38	// included) inside WorkspaceClip when set, with black at this opacity,
39	// 0 to 1, under the first
40	// visible float. 0 draws nothing.
41	Dim float64
42	// DimBehind draws the Dim veil under every window instead, right over
43	// the background and bottom layers (the overview).
44	DimBehind bool
45	Windows   []SceneWindow
46	// Separators are the lines between windows, drawn in slice order with
47	// the Border colors: tile lines over the tiles, under the floats; a
48	// float's border right after the float.
49	Separators []Separator
50	// DropHints show where a dragged tile lands, filled with Border.Active
51	// over the windows of the workspace, under the top layers. Only the
52	// output under the pointer has them, during a drag.
53	DropHints []Rect
54	// Layers are the shown layer surfaces, drawn in slice order: background
55	// and bottom before windows, top and overlay after. Core leaves out
56	// those a fullscreen window hides (all but the background and a surface
57	// taking the keyboard exclusively); adapters draw every layer given.
58	// Window popups are drawn after the windows, layer popups
59	// (SceneWindow.OverLayers) last, over every layer.
60	Layers []SceneLayer
61	// Capture is the capture state of this output: exclusion and hidden
62	// workspace; nil while nothing is captured (capture.go).
63	Capture *SceneCapture
64	// CaptureScene is the workspace captured off screen (Capture.Workspace)
65	// drawn for capture only: a workspace that is not on screen. Only the
66	// root scene carries it; CaptureScene.Capture and .CaptureScene are nil.
67	CaptureScene *Scene
68	// CaptureIndicators are the marks of live captures of this output,
69	// drawn over everything; nil when none. Captures never hold them: the
70	// capture pipeline serves requests from a scene without them.
71	CaptureIndicators []CaptureIndicator
72	// Animating is set by core when a spring or the focus pulse runs on
73	// this output after this frame was computed: the output reports the
74	// flip of the scene to core (OutputFrame), which moves the animation to
75	// the next frame. A scene of a settled output carries false, so a flip
76	// of it wakes nobody. It describes scheduling, not drawing: SameAs and
77	// the renderer ignore it.
78	Animating bool
79}
80
81// SameAs reports whether o draws exactly what s draws: every field other
82// than Seq and Animating (scheduling only, not drawn) is equal. A scene carrying a CaptureScene is never the same
83// (conservative: the capture image is not compared). Add every new Scene
84// field here; TestSceneSameAsCoversEveryField fails until the field count
85// is updated.
86func (s Scene) SameAs(o Scene) bool {
87	if s.Security != o.Security || s.Output != o.Output ||
88		s.OutputWidth != o.OutputWidth || s.OutputHeight != o.OutputHeight ||
89		s.Scale != o.Scale || s.Transform != o.Transform || s.Off != o.Off ||
90		s.Background != o.Background || s.Border != o.Border ||
91		s.WorkspaceClip != o.WorkspaceClip || s.TileInset != o.TileInset || s.Dim != o.Dim || s.DimBehind != o.DimBehind {
92		return false
93	}
94	if s.CaptureScene != nil || o.CaptureScene != nil {
95		return false
96	}
97	if (s.Capture == nil) != (o.Capture == nil) {
98		return false
99	}
100	if s.Capture != nil {
101		a, b := *s.Capture, *o.Capture
102		if a.Shown != b.Shown || a.Session != b.Session || a.Revision != b.Revision ||
103			a.Workspace != b.Workspace || a.Window != b.Window || !slices.Equal(a.Excluded, b.Excluded) {
104			return false
105		}
106	}
107	return slices.Equal(s.Windows, o.Windows) && slices.Equal(s.Separators, o.Separators) &&
108		slices.Equal(s.DropHints, o.DropHints) && slices.Equal(s.Layers, o.Layers) &&
109		slices.Equal(s.CaptureIndicators, o.CaptureIndicators)
110}
111
112// Shows reports whether the scene draws the surface of id: only its
113// content changes need a new frame. A window scrolled off the output is
114// not drawn (Draws).
115func (s Scene) Shows(id WindowID) bool {
116	for _, w := range s.Windows {
117		if w.ID == id && s.Draws(w) {
118			return true
119		}
120	}
121	for _, l := range s.Layers {
122		if l.ID == id {
123			return true
124		}
125	}
126	return false
127}
128
129// Draws reports whether any of w is drawn: not hidden, on the output,
130// inside WorkspaceClip (OverLayers popups remain output-wide) and, for a
131// tile, inside TileArea.
132func (s Scene) Draws(w SceneWindow) bool {
133	if w.Hidden || !w.Rect.Overlaps(Rect{W: s.OutputWidth, H: s.OutputHeight}) {
134		return false
135	}
136	if !w.OverLayers && s.WorkspaceClip != (Rect{}) && !w.Rect.Overlaps(s.WorkspaceClip) {
137		return false
138	}
139	if a, ok := s.TileArea(); ok && w.Tile() {
140		return w.Rect.Overlaps(a)
141	}
142	return true
143}
144
145// TileArea is where tiles are drawn: the output minus TileInset, empty
146// when the panels cover it. ok is false when TileInset is zero: tiles are
147// not clipped beyond the output and WorkspaceClip.
148func (s Scene) TileArea() (r Rect, ok bool) {
149	in := s.TileInset
150	if in == (Insets{}) {
151		return Rect{}, false
152	}
153	return Rect{X: in.Left, Y: in.Top, W: max(s.OutputWidth-in.Left-in.Right, 0), H: max(s.OutputHeight-in.Top-in.Bottom, 0)}, true
154}
155
156// Border carries the window border style; colors are #rrggbb, "" skips
157// drawing. Width is in logical pixels.
158type Border struct {
159	Width            int
160	Active, Inactive string
161}
162
163// Separator is a line between windows, in logical pixels. Active lines
164// mark the focused window and use Border.Active, others Border.Inactive.
165// Window is the float whose border it is; 0 for lines between tiles.
166type Separator struct {
167	Rect   Rect
168	Active bool
169	Window WindowID
170}
171
172// SceneLayer carries core → renderer layer surface placement.
173type SceneLayer struct {
174	ID    WindowID
175	Layer Layer
176	Rect  Rect
177}
178
179// SceneWindow carries core → renderer window placement.
180type SceneWindow struct {
181	ID                          WindowID
182	Rect                        Rect
183	Focused, Fullscreen, Hidden bool
184	// Inset sides carry a separator line inside Rect: the client is drawn
185	// inside it.
186	Inset Sides
187	// Floating windows draw at their placed size. Below marks a native
188	// covering float behind the column group.
189	Floating, Below bool
190	// Dim darkens the window, border included, with black at this
191	// opacity, 0 to 1: a stashed window peeking in. 0 draws nothing.
192	Dim float64
193	// Fade makes the whole window translucent, border and content: 0 is
194	// opaque, 1 invisible (like SurfaceContent.Fade). A window appearing
195	// or leaving animates it; a faded window is composed, never scanned
196	// out.
197	Fade float64
198	// FocusEffect, above 0, is the focus indicator's effect at this frame
199	// (focus.animation, focus.effect): the window's surfaces are lifted
200	// toward white by that fraction (screen blend). Renderers without the
201	// effect ignore it.
202	//
203	// Only focus.effect = screen exists, so the effect kind is not carried:
204	// core ignores Config.Focus.Effect and the shaders always apply screen
205	// (compose.frag, compose_hdr.frag, push constant mapy.z). A second effect
206	// needs its kind here and in the push constants (a misc flag).
207	FocusEffect float64
208	// Preview, above 0, draws the window's surfaces that much smaller in
209	// Rect (an overview thumbnail): the client keeps its size. A preview
210	// is a card: it never opens the floats.
211	Preview float64
212	// Zoom, above 0, is the content scale of a window whose frame is
213	// animating (appearing, leaving, an overview card in flight): it
214	// replaces Preview for drawing only; the window keeps its kind.
215	Zoom float64
216	// Popups are drawn from their content only: no border, no background.
217	Popup bool
218	// OverLayers popups hang from a layer surface: drawn over the top and
219	// overlay layers. Window popups stay with the windows, under them.
220	OverLayers bool
221}
222
223// Tile reports whether w is a tile: laid out in the usable area and
224// clipped to Scene.TileArea. Floats, fullscreen windows, overview previews
225// and popups are placed against the whole viewport.
226func (w SceneWindow) Tile() bool {
227	return !w.Floating && !w.Fullscreen && !w.Popup && w.Preview == 0
228}

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 23

Tags 10

↑↓ moveenter openesc close