detached 6648be1

feat(packaging): grant CAP_SYS_NICE at install and add make install (#61)

commit
6648be1cb23b41d4a2cf0464f2fd632d70a83f53
author
bnema · · 2026-09-29 06:22 UTC
committer
GitHub · · 2026-09-29 06:22 UTC
parent
ded8960
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
8 files · +31 -10
M .goreleaser.yaml +3 -0
@@ -123,6 +123,8 @@ aurs:
123123 license: GPL-3.0-only
124124 # The release workflow verifies and publishes the generated PKGBUILD.
125125 skip_upload: true
126+ # publish.sh ships the file next to the PKGBUILD.
127+ install: ./packaging/neferwl.install
126128 provides: [neferwl]
127129 conflicts: [neferwl, neferwl-git]
128130 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
@@ -136,6 +138,7 @@ aurs:
136138 - vulkan-driver
137139 - wayland
138140 - dbus
141+ - libcap
139142 optdepends:
140143 - "xwayland-satellite>=0.7: X11 apps"
141144 - "foot: default terminal"
@@ -123,6 +123,8 @@ aurs:
123 license: GPL-3.0-only123 license: GPL-3.0-only
124 # The release workflow verifies and publishes the generated PKGBUILD.124 # The release workflow verifies and publishes the generated PKGBUILD.
125 skip_upload: true125 skip_upload: true
126+ # publish.sh ships the file next to the PKGBUILD.
127+ install: ./packaging/neferwl.install
126 provides: [neferwl]128 provides: [neferwl]
127 conflicts: [neferwl, neferwl-git]129 conflicts: [neferwl, neferwl-git]
128 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.130 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
@@ -136,6 +138,7 @@ aurs:
136 - vulkan-driver138 - vulkan-driver
137 - wayland139 - wayland
138 - dbus140 - dbus
141+ - libcap
139 optdepends:142 optdepends:
140 - "xwayland-satellite>=0.7: X11 apps"143 - "xwayland-satellite>=0.7: X11 apps"
141 - "foot: default terminal"144 - "foot: default terminal"
M Makefile +6 -2
@@ -1,4 +1,4 @@
1-.PHONY: build test vet race mocks mocks-check spv-check fakes-check arch check perf-check bin tty logs pkg
1+.PHONY: build test vet race mocks mocks-check spv-check fakes-check arch check perf-check bin tty logs pkg install
22
33 # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net.
44 TTY_TIMEOUT ?= 0
@@ -66,7 +66,11 @@ pkg:
6666 echo "$${t:-0.0.0}.r$$(git rev-list --count HEAD).g$$(git rev-parse --short HEAD)"); \
6767 d=$$(mktemp -d /tmp/neferwl-pkg.XXXXXX); trap 'rm -rf "$$d"' EXIT; \
6868 git archive --prefix=neferwl-$$v/ -o "$$d/neferwl-$$v.tar.gz" HEAD; \
69- cp packaging/arch/PKGBUILD "$$d/"; \
69+ cp packaging/arch/PKGBUILD packaging/neferwl.install "$$d/"; \
7070 cd "$$d" && sed -i "s/^pkgver=.*/pkgver=$$v/; s/^sha256sums=.*/sha256sums=('$$(sha256sum *.tar.gz | cut -d' ' -f1)')/" PKGBUILD; \
7171 makepkg -f --noconfirm; mkdir -p $(CURDIR)/dist; rm -f $(CURDIR)/dist/neferwl-*.pkg.tar.zst; mv *.pkg.tar.zst $(CURDIR)/dist/
7272 @ls dist/*.pkg.tar.zst
73+
74+# Build the package, then install it with pacman (asks for sudo).
75+install: pkg
76+ sudo pacman -U dist/neferwl-*.pkg.tar.zst
@@ -1,4 +1,4 @@
1-.PHONY: build test vet race mocks mocks-check spv-check fakes-check arch check perf-check bin tty logs pkg1+.PHONY: build test vet race mocks mocks-check spv-check fakes-check arch check perf-check bin tty logs pkg install
2 2
3 # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net.3 # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net.
4 TTY_TIMEOUT ?= 04 TTY_TIMEOUT ?= 0
@@ -66,7 +66,11 @@ pkg:
66 echo "$${t:-0.0.0}.r$$(git rev-list --count HEAD).g$$(git rev-parse --short HEAD)"); \66 echo "$${t:-0.0.0}.r$$(git rev-list --count HEAD).g$$(git rev-parse --short HEAD)"); \
67 d=$$(mktemp -d /tmp/neferwl-pkg.XXXXXX); trap 'rm -rf "$$d"' EXIT; \67 d=$$(mktemp -d /tmp/neferwl-pkg.XXXXXX); trap 'rm -rf "$$d"' EXIT; \
68 git archive --prefix=neferwl-$$v/ -o "$$d/neferwl-$$v.tar.gz" HEAD; \68 git archive --prefix=neferwl-$$v/ -o "$$d/neferwl-$$v.tar.gz" HEAD; \
69- cp packaging/arch/PKGBUILD "$$d/"; \69+ cp packaging/arch/PKGBUILD packaging/neferwl.install "$$d/"; \
70 cd "$$d" && sed -i "s/^pkgver=.*/pkgver=$$v/; s/^sha256sums=.*/sha256sums=('$$(sha256sum *.tar.gz | cut -d' ' -f1)')/" PKGBUILD; \70 cd "$$d" && sed -i "s/^pkgver=.*/pkgver=$$v/; s/^sha256sums=.*/sha256sums=('$$(sha256sum *.tar.gz | cut -d' ' -f1)')/" PKGBUILD; \
71 makepkg -f --noconfirm; mkdir -p $(CURDIR)/dist; rm -f $(CURDIR)/dist/neferwl-*.pkg.tar.zst; mv *.pkg.tar.zst $(CURDIR)/dist/71 makepkg -f --noconfirm; mkdir -p $(CURDIR)/dist; rm -f $(CURDIR)/dist/neferwl-*.pkg.tar.zst; mv *.pkg.tar.zst $(CURDIR)/dist/
72 @ls dist/*.pkg.tar.zst72 @ls dist/*.pkg.tar.zst
73+
74+# Build the package, then install it with pacman (asks for sudo).
75+install: pkg
76+ sudo pacman -U dist/neferwl-*.pkg.tar.zst
M README.md +2 -3
@@ -85,11 +85,10 @@ paru -S neferwl-git # latest main, built from source
8585 From a checkout (needs Go 1.27):
8686
8787 ```sh
88-make pkg # builds dist/neferwl-*.pkg.tar.zst from HEAD
89-sudo pacman -U dist/neferwl-*.pkg.tar.zst
88+make install # builds dist/neferwl-*.pkg.tar.zst from HEAD, then installs it with pacman
9089 ```
9190
92-The package installs `neferwl` and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.
91+`make pkg` only builds the package. The package installs `neferwl` with CAP_SYS_NICE (real-time scheduling, see [performance](docs/performance.md)) and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.
9392
9493 On other distributions, download a `linux_amd64` or `linux_arm64` archive from [Releases](https://github.com/bnema/neferwl/releases) and check it against `checksums.txt`, or run `make bin` to build `bin/neferwl`.
9594
@@ -85,11 +85,10 @@ paru -S neferwl-git # latest main, built from source
85 From a checkout (needs Go 1.27):85 From a checkout (needs Go 1.27):
86 86
87 ```sh87 ```sh
88-make pkg # builds dist/neferwl-*.pkg.tar.zst from HEAD88+make install # builds dist/neferwl-*.pkg.tar.zst from HEAD, then installs it with pacman
89-sudo pacman -U dist/neferwl-*.pkg.tar.zst
90 ```89 ```
91 90
92-The package installs `neferwl` and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.91+`make pkg` only builds the package. The package installs `neferwl` with CAP_SYS_NICE (real-time scheduling, see [performance](docs/performance.md)) and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.
93 92
94 On other distributions, download a `linux_amd64` or `linux_arm64` archive from [Releases](https://github.com/bnema/neferwl/releases) and check it against `checksums.txt`, or run `make bin` to build `bin/neferwl`.93 On other distributions, download a `linux_amd64` or `linux_arm64` archive from [Releases](https://github.com/bnema/neferwl/releases) and check it against `checksums.txt`, or run `make bin` to build `bin/neferwl`.
95 94
M docs/performance.md +3 -1
@@ -9,7 +9,9 @@ How NeferWL keeps its CPU and memory use low, how to measure it, and the referen
99 - **Cursor rides on game frames under VRR.** While a fullscreen game drives VRR, a cursor move waits for the game's next frame instead of its own commit: a cursor-only commit refreshes the panel at its slowest rate (~21 ms at 48 Hz) and delays the next game frame by as much. If the game stops drawing, the cursor still commits alone at 24 Hz.
1010 - **Default GOGC.** The Go live heap is a few MB (client buffers live in shared and GPU memory), so the runtime default `GOGC=100` with a 256 MiB soft limit gives 2 collections on the tiled playback test where `GOGC=50` gave 13. `GOGC` and `GOMEMLIMIT` from the environment win.
1111
12-Output and input threads request real-time scheduling, and the Vulkan queue requests elevated priority. Both require CAP_SYS_NICE: `sudo setcap cap_sys_nice+ep /usr/bin/neferwl`. Without it NeferWL runs at normal priority.
12+Output and input threads request real-time scheduling, and the Vulkan queue requests elevated priority. Both require CAP_SYS_NICE, which the Arch packages set on `/usr/bin/neferwl` at install. Apps launched by NeferWL inherit neither. Set `performance.realtime = false` to opt out. A binary built with `make bin` runs at normal priority unless you grant it: `sudo setcap cap_sys_nice+ep bin/neferwl`.
13+
14+With the capability, the dynamic loader ignores `LD_PRELOAD` and `LD_LIBRARY_PATH` for NeferWL, and debuggers need root to attach.
1315
1416 ## Guards
1517
@@ -9,7 +9,9 @@ How NeferWL keeps its CPU and memory use low, how to measure it, and the referen
9 - **Cursor rides on game frames under VRR.** While a fullscreen game drives VRR, a cursor move waits for the game's next frame instead of its own commit: a cursor-only commit refreshes the panel at its slowest rate (~21 ms at 48 Hz) and delays the next game frame by as much. If the game stops drawing, the cursor still commits alone at 24 Hz.9 - **Cursor rides on game frames under VRR.** While a fullscreen game drives VRR, a cursor move waits for the game's next frame instead of its own commit: a cursor-only commit refreshes the panel at its slowest rate (~21 ms at 48 Hz) and delays the next game frame by as much. If the game stops drawing, the cursor still commits alone at 24 Hz.
10 - **Default GOGC.** The Go live heap is a few MB (client buffers live in shared and GPU memory), so the runtime default `GOGC=100` with a 256 MiB soft limit gives 2 collections on the tiled playback test where `GOGC=50` gave 13. `GOGC` and `GOMEMLIMIT` from the environment win.10 - **Default GOGC.** The Go live heap is a few MB (client buffers live in shared and GPU memory), so the runtime default `GOGC=100` with a 256 MiB soft limit gives 2 collections on the tiled playback test where `GOGC=50` gave 13. `GOGC` and `GOMEMLIMIT` from the environment win.
11 11
12-Output and input threads request real-time scheduling, and the Vulkan queue requests elevated priority. Both require CAP_SYS_NICE: `sudo setcap cap_sys_nice+ep /usr/bin/neferwl`. Without it NeferWL runs at normal priority.12+Output and input threads request real-time scheduling, and the Vulkan queue requests elevated priority. Both require CAP_SYS_NICE, which the Arch packages set on `/usr/bin/neferwl` at install. Apps launched by NeferWL inherit neither. Set `performance.realtime = false` to opt out. A binary built with `make bin` runs at normal priority unless you grant it: `sudo setcap cap_sys_nice+ep bin/neferwl`.
13+
14+With the capability, the dynamic loader ignores `LD_PRELOAD` and `LD_LIBRARY_PATH` for NeferWL, and debuggers need root to attach.
13 15
14 ## Guards16 ## Guards
15 17
M packaging/arch/PKGBUILD +2 -1
@@ -8,12 +8,13 @@ url='https://github.com/bnema/neferwl'
88 license=('GPL-3.0-only')
99 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
1010 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
11- 'vulkan-driver' 'wayland' 'dbus')
11+ 'vulkan-driver' 'wayland' 'dbus' 'libcap')
1212 makedepends=('go')
1313 optdepends=('xwayland-satellite>=0.7: X11 apps'
1414 'foot: default terminal'
1515 'fuzzel: launcher'
1616 'xdg-desktop-portal-gtk: file pickers and settings for apps')
17+install=neferwl.install
1718 source=("$pkgname-$pkgver.tar.gz")
1819 sha256sums=('SKIP')
1920
@@ -8,12 +8,13 @@ url='https://github.com/bnema/neferwl'
8 license=('GPL-3.0-only')8 license=('GPL-3.0-only')
9 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.9 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
10 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'10 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
11- 'vulkan-driver' 'wayland' 'dbus')11+ 'vulkan-driver' 'wayland' 'dbus' 'libcap')
12 makedepends=('go')12 makedepends=('go')
13 optdepends=('xwayland-satellite>=0.7: X11 apps'13 optdepends=('xwayland-satellite>=0.7: X11 apps'
14 'foot: default terminal'14 'foot: default terminal'
15 'fuzzel: launcher'15 'fuzzel: launcher'
16 'xdg-desktop-portal-gtk: file pickers and settings for apps')16 'xdg-desktop-portal-gtk: file pickers and settings for apps')
17+install=neferwl.install
17 source=("$pkgname-$pkgver.tar.gz")18 source=("$pkgname-$pkgver.tar.gz")
18 sha256sums=('SKIP')19 sha256sums=('SKIP')
19 20
M packaging/aur/neferwl-git/PKGBUILD +2 -1
@@ -10,7 +10,7 @@ url='https://github.com/bnema/neferwl'
1010 license=('GPL-3.0-only')
1111 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
1212 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
13- 'vulkan-driver' 'wayland' 'dbus')
13+ 'vulkan-driver' 'wayland' 'dbus' 'libcap')
1414 makedepends=('go>=2:1.27' 'git')
1515 optdepends=('xwayland-satellite>=0.7: X11 apps'
1616 'foot: default terminal'
@@ -18,6 +18,7 @@ optdepends=('xwayland-satellite>=0.7: X11 apps'
1818 'xdg-desktop-portal-gtk: file pickers and settings for apps')
1919 provides=('neferwl')
2020 conflicts=('neferwl' 'neferwl-bin')
21+install=neferwl.install
2122 source=('git+https://github.com/bnema/neferwl.git')
2223 sha256sums=('SKIP')
2324
@@ -10,7 +10,7 @@ url='https://github.com/bnema/neferwl'
10 license=('GPL-3.0-only')10 license=('GPL-3.0-only')
11 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.11 # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
12 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'12 depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
13- 'vulkan-driver' 'wayland' 'dbus')13+ 'vulkan-driver' 'wayland' 'dbus' 'libcap')
14 makedepends=('go>=2:1.27' 'git')14 makedepends=('go>=2:1.27' 'git')
15 optdepends=('xwayland-satellite>=0.7: X11 apps'15 optdepends=('xwayland-satellite>=0.7: X11 apps'
16 'foot: default terminal'16 'foot: default terminal'
@@ -18,6 +18,7 @@ optdepends=('xwayland-satellite>=0.7: X11 apps'
18 'xdg-desktop-portal-gtk: file pickers and settings for apps')18 'xdg-desktop-portal-gtk: file pickers and settings for apps')
19 provides=('neferwl')19 provides=('neferwl')
20 conflicts=('neferwl' 'neferwl-bin')20 conflicts=('neferwl' 'neferwl-bin')
21+install=neferwl.install
21 source=('git+https://github.com/bnema/neferwl.git')22 source=('git+https://github.com/bnema/neferwl.git')
22 sha256sums=('SKIP')23 sha256sums=('SKIP')
23 24
M packaging/aur/publish.sh +4 -2
@@ -14,6 +14,8 @@ pkgname=$1
1414 work=$(mktemp -d)
1515 trap 'rm -rf "$work"' EXIT
1616 cp "$2" "$work/PKGBUILD"
17+# The install script sets CAP_SYS_NICE; the AUR repo carries it too.
18+cp "$(dirname "$0")/../neferwl.install" "$work/"
1719 cd "$work"
1820
1921 makepkg --syncdeps --force --noconfirm
@@ -52,9 +54,9 @@ echo 'aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6Nc
5254 export GIT_SSH_COMMAND="ssh -i $key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$ssh_dir/known_hosts"
5355
5456 git clone "ssh://aur@aur.archlinux.org/$pkgname.git" aur
55-cp PKGBUILD .SRCINFO aur/
57+cp PKGBUILD .SRCINFO neferwl.install aur/
5658 cd aur
57-git add PKGBUILD .SRCINFO
59+git add PKGBUILD .SRCINFO neferwl.install
5860 if git diff --cached --quiet; then
5961 echo "$pkgname $pkgver is already on the AUR"
6062 exit 0
@@ -14,6 +14,8 @@ pkgname=$1
14 work=$(mktemp -d)14 work=$(mktemp -d)
15 trap 'rm -rf "$work"' EXIT15 trap 'rm -rf "$work"' EXIT
16 cp "$2" "$work/PKGBUILD"16 cp "$2" "$work/PKGBUILD"
17+# The install script sets CAP_SYS_NICE; the AUR repo carries it too.
18+cp "$(dirname "$0")/../neferwl.install" "$work/"
17 cd "$work"19 cd "$work"
18 20
19 makepkg --syncdeps --force --noconfirm21 makepkg --syncdeps --force --noconfirm
@@ -52,9 +54,9 @@ echo 'aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6Nc
52 export GIT_SSH_COMMAND="ssh -i $key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$ssh_dir/known_hosts"54 export GIT_SSH_COMMAND="ssh -i $key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$ssh_dir/known_hosts"
53 55
54 git clone "ssh://aur@aur.archlinux.org/$pkgname.git" aur56 git clone "ssh://aur@aur.archlinux.org/$pkgname.git" aur
55-cp PKGBUILD .SRCINFO aur/57+cp PKGBUILD .SRCINFO neferwl.install aur/
56 cd aur58 cd aur
57-git add PKGBUILD .SRCINFO59+git add PKGBUILD .SRCINFO neferwl.install
58 if git diff --cached --quiet; then60 if git diff --cached --quiet; then
59 echo "$pkgname $pkgver is already on the AUR"61 echo "$pkgname $pkgver is already on the AUR"
60 exit 062 exit 0
A packaging/neferwl.install +9 -0
@@ -0,0 +1,9 @@
1+# Real-time input and output threads and the high-priority Vulkan queue need
2+# CAP_SYS_NICE. Apps launched by NeferWL do not inherit it.
3+post_install() {
4+ setcap cap_sys_nice=ep usr/bin/neferwl || echo 'neferwl: setcap failed, real-time scheduling is off'
5+}
6+
7+post_upgrade() {
8+ post_install
9+}
@@ -0,0 +1,9 @@
1+# Real-time input and output threads and the high-priority Vulkan queue need
2+# CAP_SYS_NICE. Apps launched by NeferWL do not inherit it.
3+post_install() {
4+ setcap cap_sys_nice=ep usr/bin/neferwl || echo 'neferwl: setcap failed, real-time scheduling is off'
5+}
6+
7+post_upgrade() {
8+ post_install
9+}

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 25

Tags 10

↑↓ moveenter openesc close