feat/hints a471fa4

registry.go RawHistoryFolder

1package screensaver
2
3// maxPerSender bounds the cookies one D-Bus connection may hold, so a
4// looping client cannot grow the registry without limit. It is generous:
5// the GTK portal holds the cookies of every app that inhibits through it.
6const maxPerSender = 1024
7
8// registry is the inhibitions in effect: cookie → owning connection. The
9// session stays awake while it is not empty. It is owned by Run's goroutine.
10type registry struct {
11	next    uint32
12	cookies map[uint32]string
13	counts  map[string]int
14}
15
16func newRegistry() *registry {
17	return &registry{cookies: map[uint32]string{}, counts: map[string]int{}}
18}
19
20// inhibit adds a cookie for sender. ok is false when sender holds too many;
21// first is set when sender had none, so the caller checks it is still on
22// the bus (it may have left before its call was handled).
23func (r *registry) inhibit(sender string) (cookie uint32, first, ok bool) {
24	if r.counts[sender] >= maxPerSender {
25		return 0, false, false
26	}
27	for {
28		r.next++
29		if _, used := r.cookies[r.next]; r.next != 0 && !used {
30			break
31		}
32	}
33	r.cookies[r.next] = sender
34	r.counts[sender]++
35	return r.next, r.counts[sender] == 1, true
36}
37
38// uninhibit removes cookie if sender owns it: one client cannot release
39// another's inhibition.
40func (r *registry) uninhibit(sender string, cookie uint32) bool {
41	if owner, ok := r.cookies[cookie]; !ok || owner != sender {
42		return false
43	}
44	delete(r.cookies, cookie)
45	if r.counts[sender]--; r.counts[sender] == 0 {
46		delete(r.counts, sender)
47	}
48	return true
49}
50
51// drop removes every cookie of a connection that left the bus.
52func (r *registry) drop(sender string) {
53	if r.counts[sender] == 0 {
54		return
55	}
56	for cookie, owner := range r.cookies {
57		if owner == sender {
58			delete(r.cookies, cookie)
59		}
60	}
61	delete(r.counts, sender)
62}
63
64func (r *registry) held() bool { return len(r.cookies) > 0 }

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