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 // HintLabels are the keyboard hint labels of this output, drawn over
73 // everything, after CaptureIndicators; nil when hint mode is not shown
74 // here. Captures never contain them.
75 HintLabels []HintLabel
76 HintStyle HintStyle
77 // Flash is the focus flash drawn over everything of this output; nil
78 // draws nothing.
79 Flash *FocusFlash
80 // Animating is set by core when a spring or a focus flash runs on
81 // this output after this frame was computed: the output reports the
82 // flip of the scene to core (OutputFrame), which moves the animation to
83 // the next frame. A scene of a settled output carries false, so a flip
84 // of it wakes nobody. It describes scheduling, not drawing: SameAs and
85 // the renderer ignore it.
86 Animating bool
87}
88
89// SameAs reports whether o draws exactly what s draws: every field other
90// than Seq and Animating (scheduling only, not drawn) is equal. A scene
91// carrying a CaptureScene is never the same (conservative: the capture image
92// is not compared). Add every new Scene field here;
93// TestSceneSameAsCoversEveryField fails until the field count is updated.
94func (s Scene) SameAs(o Scene) bool {
95 if s.Security != o.Security || s.Output != o.Output ||
96 s.OutputWidth != o.OutputWidth || s.OutputHeight != o.OutputHeight ||
97 s.Scale != o.Scale || s.Transform != o.Transform || s.Off != o.Off ||
98 s.Background != o.Background || s.Border != o.Border ||
99 s.WorkspaceClip != o.WorkspaceClip || s.TileInset != o.TileInset || s.Dim != o.Dim || s.DimBehind != o.DimBehind {
100 return false
101 }
102 if (s.Flash == nil) != (o.Flash == nil) || (s.Flash != nil && *s.Flash != *o.Flash) {
103 return false
104 }
105 if s.CaptureScene != nil || o.CaptureScene != nil {
106 return false
107 }
108 if (s.Capture == nil) != (o.Capture == nil) {
109 return false
110 }
111 if s.Capture != nil {
112 a, b := *s.Capture, *o.Capture
113 if a.Shown != b.Shown || a.Session != b.Session || a.Revision != b.Revision ||
114 a.Workspace != b.Workspace || a.Window != b.Window || !slices.Equal(a.Excluded, b.Excluded) {
115 return false
116 }
117 }
118 return slices.Equal(s.Windows, o.Windows) && slices.Equal(s.Separators, o.Separators) &&
119 slices.Equal(s.DropHints, o.DropHints) && slices.Equal(s.Layers, o.Layers) &&
120 slices.Equal(s.CaptureIndicators, o.CaptureIndicators) &&
121 s.HintStyle == o.HintStyle && slices.Equal(s.HintLabels, o.HintLabels)
122}
123
124// Shows reports whether the scene draws the surface of id: only its
125// content changes need a new frame. A window scrolled off the output is
126// not drawn (Draws).
127func (s Scene) Shows(id WindowID) bool {
128 for _, w := range s.Windows {
129 if w.ID == id && s.Draws(w) {
130 return true
131 }
132 }
133 for _, l := range s.Layers {
134 if l.ID == id {
135 return true
136 }
137 }
138 return false
139}
140
141// Draws reports whether any of w is drawn: not hidden, on the output,
142// inside WorkspaceClip (OverLayers popups remain output-wide) and, for a
143// tile, inside TileArea.
144func (s Scene) Draws(w SceneWindow) bool {
145 if w.Hidden || !w.Rect.Overlaps(Rect{W: s.OutputWidth, H: s.OutputHeight}) {
146 return false
147 }
148 if !w.OverLayers && s.WorkspaceClip != (Rect{}) && !w.Rect.Overlaps(s.WorkspaceClip) {
149 return false
150 }
151 if a, ok := s.TileArea(); ok && w.Tile() {
152 return w.Rect.Overlaps(a)
153 }
154 return true
155}
156
157// TileArea is where tiles are drawn: the output minus TileInset, empty
158// when the panels cover it. ok is false when TileInset is zero: tiles are
159// not clipped beyond the output and WorkspaceClip.
160func (s Scene) TileArea() (r Rect, ok bool) {
161 in := s.TileInset
162 if in == (Insets{}) {
163 return Rect{}, false
164 }
165 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
166}
167
168// Border carries the window border style; colors are #rrggbb, "" skips
169// drawing. Width is in logical pixels.
170type Border struct {
171 Width int
172 Active, Inactive string
173}
174
175// Separator is a line between windows, in logical pixels. Active lines
176// mark the focused window and use Border.Active, others Border.Inactive.
177// Window is the float whose border it is; 0 for lines between tiles.
178type Separator struct {
179 Rect Rect
180 Active bool
181 Window WindowID
182}
183
184// SceneLayer carries core → renderer layer surface placement.
185type SceneLayer struct {
186 ID WindowID
187 Layer Layer
188 Rect Rect
189}
190
191// FocusFlash is a brief inner border marking the entity an action just
192// changed: a window, a column or a whole output. Rect is in logical
193// pixels, Width the border width inside it, Color #rrggbb and Alpha its
194// opacity at this frame (0 to 1).
195type FocusFlash struct {
196 Rect Rect
197 Width int
198 Color string
199 Alpha float64
200}
201
202// SceneWindow carries core → renderer window placement.
203type SceneWindow struct {
204 ID WindowID
205 Rect Rect
206 Focused, Fullscreen, Hidden bool
207 // Inset sides carry a separator line inside Rect: the client is drawn
208 // inside it.
209 Inset Sides
210 // Floating windows draw at their placed size. Below marks a native
211 // covering float behind the column group.
212 Floating, Below bool
213 // Dim darkens the window, border included, with black at this
214 // opacity, 0 to 1: a stashed window peeking in. 0 draws nothing.
215 Dim float64
216 // Fade makes the whole window translucent, border and content: 0 is
217 // opaque, 1 invisible (like SurfaceContent.Fade). A window appearing
218 // or leaving animates it; a faded window is composed, never scanned
219 // out.
220 Fade float64
221 // Preview, above 0, draws the window's surfaces that much smaller in
222 // Rect (an overview thumbnail): the client keeps its size. A preview
223 // is a card: it never opens the floats.
224 Preview float64
225 // Zoom, above 0, is the content scale of a window whose frame is
226 // animating (appearing, leaving, an overview card in flight): it
227 // replaces Preview for drawing only; the window keeps its kind.
228 Zoom float64
229 // Popups are drawn from their content only: no border, no background.
230 Popup bool
231 // OverLayers popups hang from a layer surface: drawn over the top and
232 // overlay layers. Window popups stay with the windows, under them.
233 OverLayers bool
234}
235
236// Tile reports whether w is a tile: laid out in the usable area and
237// clipped to Scene.TileArea. Floats, fullscreen windows, overview previews
238// and popups are placed against the whole viewport.
239func (w SceneWindow) Tile() bool {
240 return !w.Floating && !w.Fullscreen && !w.Popup && w.Preview == 0
241}
242
243// HintStyle carries reloadable label settings and untransformed output density.
244type HintStyle struct {
245 Size float64
246 Background, Foreground string
247 Width, Height, PhysicalW, PhysicalH int
248}