1package core
2
3import "github.com/bnema/neferwl/internal/ports"
4
5// Window capture: a session of one window (CaptureSessionOpen.Window) renders
6// it off screen, alone, at its client size, wherever it is: on screen, on
7// another workspace, under a fullscreen window or in a hidden stash. While it
8// is captured and not on screen its configure says Captured, so the client
9// keeps drawing (not suspended). The scene it is drawn from is
10// Scene.CaptureScene of the output that owns it, like a hidden workspace; one
11// target, a workspace or a window, is rendered off screen at a time.
12
13// windowSize is a window's client size, at the origin: its placement on its
14// own workspace or, when that hides it (a covered float), the float's own
15// size, else the size it was last configured to (a stashed window keeps its
16// imposed stash size).
17func (c *Core) windowSize(w *Workspace, id WindowID) Rect {
18 for _, p := range w.Layout() {
19 if p.ID == id && !p.Hidden && p.Rect.W > 0 && p.Rect.H > 0 {
20 r := c.clientRect(p)
21 return Rect{W: r.W, H: r.H}
22 }
23 }
24 if i := w.floatIndex(id); i >= 0 && w.Floats[i].W > 0 && w.Floats[i].H > 0 {
25 return Rect{W: w.Floats[i].W, H: w.Floats[i].H}
26 }
27 if v, ok := c.configures.sent[id]; ok && v.Width > 0 && v.Height > 0 {
28 return Rect{W: v.Width, H: v.Height}
29 }
30 return Rect{}
31}
32
33// popupOffset is where a popup lies relative to the client area of its root
34// window.
35func (c *Core) popupOffset(id WindowID) Rect {
36 p := c.popups[id]
37 if p == nil {
38 return Rect{}
39 }
40 r := p.rect
41 if c.popups[p.parent] != nil {
42 o := c.popupOffset(p.parent)
43 r.X, r.Y = r.X+o.X, r.Y+o.Y
44 }
45 return r
46}
47
48// captureWindowScene is the window of v drawn for capture only: a scene of its
49// client size with the window at the origin and its mapped popups over it.
50func (c *Core) captureWindowScene(v *capView, seq uint64) *ports.Scene {
51 sz := v.windowSz
52 s := &ports.Scene{
53 Security: c.security,
54 Output: v.windowScr.name(), Seq: seq, OutputWidth: sz.W, OutputHeight: sz.H, WorkspaceClip: Rect{W: sz.W, H: sz.H},
55 Scale: v.windowScr.scale, Background: c.cfg.Background.Color,
56 Border: ports.Border{Width: c.cfg.Border.Width, Active: c.cfg.Border.Active, Inactive: c.cfg.Border.Inactive},
57 Windows: []ports.SceneWindow{{ID: v.window, Rect: Rect{W: sz.W, H: sz.H}, Fullscreen: true}},
58 }
59 for _, id := range c.popupOrder {
60 if p := c.popups[id]; p != nil && p.mapped && c.popupRoot(id) == v.window {
61 s.Windows = append(s.Windows, ports.SceneWindow{ID: id, Rect: c.popupOffset(id), Popup: true})
62 }
63 }
64 return s
65}