configures.go RawHistoryFolder

1package core
2
3import "github.com/bnema/neferwl/internal/ports"
4
5// configureTarget is where a placement is shown, as the configure needs it.
6type configureTarget struct {
7	output  string
8	area    Rect // the output, to tell whether the window is on screen
9	focused bool // activated: focused on the focused output
10	// client is the placement minus borders; imposed reports core sized a
11	// floating window (native floats pick their own size).
12	client  Rect
13	imposed bool
14	// captureArea is the viewport of the workspace a capture session renders
15	// off screen, when this window belongs to it (captureConfigure).
16	captureArea Rect
17	// realTiled sizes a visible tiled preview from its real client rect.
18	realTiled bool
19}
20
21// configures owns the last configure sent to each window and decides the
22// next one. Configures are sent only when they change.
23type configures struct {
24	sent map[WindowID]ports.ConfigureWindow
25	seen map[WindowID]bool
26	// answer holds windows whose state request awaits a configure, sent
27	// even unchanged: xdg-shell answers every request, a refused one too.
28	answer map[WindowID]bool
29	// cw is the workspace a capture session renders off screen, if any.
30	cw captureWorkspace
31}
32
33func newConfigures() configures {
34	return configures{sent: map[WindowID]ports.ConfigureWindow{}, seen: map[WindowID]bool{}, answer: map[WindowID]bool{}}
35}
36
37// next returns the configure for p at t and whether it must be sent. The
38// caller records it with mark once sent.
39func (s *configures) next(p Placement, t configureTarget) (ports.ConfigureWindow, bool) {
40	s.seen[p.ID] = true
41	old, ok := s.sent[p.ID]
42	v := build(p, t, old, ok)
43	return v, !ok || v != old || s.answer[p.ID]
44}
45
46// nextWithCapture is next for a window of a workspace a capture session
47// renders off screen. p is its placement on the physical layout; cp is its
48// real placement on its own workspace, laid out in the viewport
49// t.captureArea (nil: not captured, exactly next).
50//
51// A hidden p is sized from cp like a shown window and stays physically
52// invisible and deactivated (Visible false). Any other p (an overview
53// preview) is configured as usual, keeping its real size; only when the
54// display does not show it does it get Captured, so a capture that draws it
55// does not see it suspended. Captured is set when cp is drawn in the
56// viewport.
57func (s *configures) nextWithCapture(p Placement, t configureTarget, cp *Placement) (ports.ConfigureWindow, bool) {
58	if cp == nil {
59		return s.next(p, t)
60	}
61	s.seen[p.ID] = true
62	old, ok := s.sent[p.ID]
63	var v ports.ConfigureWindow
64	if p.Hidden {
65		t.focused = false
66		v = build(*cp, t, old, ok)
67		v.Activated, v.Visible = false, false
68	} else {
69		v = build(p, t, old, ok)
70	}
71	v.Captured = !v.Visible && !cp.Hidden && cp.Rect.Overlaps(t.captureArea)
72	return v, !ok || v != old || s.answer[p.ID]
73}
74
75// build is the configure for p at t given the last one sent, if any. It
76// never sets Captured: only nextWithCapture does, so a window that leaves a
77// capture session drops the flag with its next configure.
78func build(p Placement, t configureTarget, old ports.ConfigureWindow, ok bool) ports.ConfigureWindow {
79	var v ports.ConfigureWindow
80	switch {
81	case p.Hidden:
82		// A hidden window keeps its size, state and output; it is only
83		// deactivated and marked invisible. One mapped hidden is told so
84		// at once, sized by the client.
85		v = old
86		if !ok {
87			v = ports.ConfigureWindow{ID: p.ID, Floating: p.Floating}
88		}
89		v.Activated, v.Visible, v.Output, v.Captured = false, false, t.output, false
90	case p.Preview > 0:
91		// A preview keeps its client's size: only its focus changes.
92		v = old
93		if !ok {
94			v = ports.ConfigureWindow{ID: p.ID, Width: int(float64(p.Rect.W) / p.Preview), Height: int(float64(p.Rect.H) / p.Preview), Floating: p.Floating}
95			if p.Floating {
96				// A native float picks its own size.
97				v.Width, v.Height = 0, 0
98			}
99		}
100		if p.Fullscreen && !v.Fullscreen {
101			// A float made fullscreen off screen: its preview row shows
102			// it fullscreen, sized for the output, never the preview.
103			v.Width, v.Height, v.Fullscreen, v.Floating = t.area.W, t.area.H, true, false
104		}
105		if t.realTiled {
106			v.Width, v.Height = t.client.W, t.client.H
107		}
108		v.Activated, v.Visible, v.Output, v.Captured = t.focused, onScreen(p, t.area), t.output, false
109	default:
110		v = ports.ConfigureWindow{ID: p.ID, Width: t.client.W, Height: t.client.H, Fullscreen: p.Fullscreen, Activated: t.focused, Floating: p.Floating && !p.Fullscreen, Output: t.output, Visible: onScreen(p, t.area)}
111		if v.Floating && !t.imposed {
112			v.Width, v.Height = 0, 0
113		}
114	}
115	return v
116}
117
118// mark records v as sent.
119func (s *configures) mark(v ports.ConfigureWindow) {
120	s.sent[v.ID] = v
121	delete(s.answer, v.ID)
122}
123
124// prune forgets the windows no next call saw since the last prune: they
125// left the layout.
126func (s *configures) prune() {
127	for id := range s.sent {
128		if !s.seen[id] {
129			delete(s.sent, id)
130		}
131	}
132	for id := range s.answer {
133		if !s.seen[id] {
134			delete(s.answer, id)
135		}
136	}
137	clear(s.seen)
138}

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