← recipes

Commit e18c63a3

10
files
+950
added
-90
deleted
@@ -1,90 +1,154 @@
1 -# PaganOS Recipes
2 -
3 -Receptury pakietów dla [PaganOS](https://paganlinux.eu). Każdy plik `PAGBUILD.yaml` definiuje jak zbudować pojedynczy pakiet.
4 -
5 -## Struktura
6 -
7 -```
8 -recipes/
9 -├── core/ # pakiety bazowe (binutils, gcc, glibc, ...)
10 -├── drivers/ # sterowniki (libinput, mesa, ...)
11 -├── net/ # sieć (curl, wget, NetworkManager, ...)
12 -├── gui/ # pakiety GUI (gtk, qt, xfce, ...)
13 -├── utils/ # narzędzia (bubblewrap, ripgrep, ...)
14 -└── boot/ # bootloader (grub)
15 -```
16 -
17 -
18 -## Format PAGBUILD.yaml
19 -
20 -```yaml
21 -pkgname: acl
22 -pkgver: '2.4.0'
23 -pkgrel: 1
24 -pkgdesc: Commands for Manipulating POSIX Access Control Lists.
25 -url: http://savannah.nongnu.org/projects/acl
26 -arch: x86_64
27 -license:
28 -- GPL-2.0-only
29 -depends:
30 -- attr
31 -makedepends:
32 -- gcc
33 -source:
34 -- http://download.savannah.gnu.org/releases/${pkgname}/${pkgname}-${pkgver}.tar.gz
35 -sha256sums:
36 -- SKIP
37 -build: |
38 - cd "${pkgname}-${pkgver}"
39 - ./configure --prefix=/usr
40 - make -j$(nproc)
41 -package: |
42 - cd "${pkgname}-${pkgver}"
43 - make DESTDIR="${PKGDIR}" install
44 -```
45 -
46 -### Zmienne dostępne w fazach build/package
47 -
48 -- `${PKGDIR}` — katalog DESTDIR (instalacja pakietu)
49 -- `${pkgname}`, `${pkgver}`, `${pkgrel}` — podstawiane też w adresach `source:`
50 -
51 -### Model pakietu (jak Arch/Debian — bez footprintów)
52 -
53 -Receptura **nie deklaruje listy plików**. Faza `package:` instaluje wszystko do
54 -`${PKGDIR}` (DESTDIR) i z tego katalogu `pagbuild` tworzy **jeden pakiet** —
55 -dokładnie jak `PKGBUILD` w Archu czy reguły `install` w Debianie. Lista plików
56 -nie jest danymi wejściowymi, tylko **pochodną** pakietu: `pag` wylicza SHA256
57 -dla każdego pliku przy instalacji i zapisuje je w `/var/lib/pag/files.db`
58 -(rola, którą w Debianie pełni `md5sums`/`.list`, a w Archu `.MTREE`).
59 -
60 -> **Nie używamy już pól `footprint`, `footprint_devel`, `footprint_man`,
61 -> `footprint_<lang>`** — to balast z formatu cards/NuTyX, którego `pagbuild`
62 -> nigdy nie czytał. Podpakiety deweloperskie/dokumentacyjne/językowe są scalane
63 -> z pakietem głównym (ich pliki i tak trafiają do DESTDIR). Do usuwania tych pól
64 -> z istniejących receptur służy `strip-recipes-footprints.py`.
65 -
66 -### Pakiet wyjściowy
67 -
68 -`pagbuild` buduje pakiety **`.pag`** (tar.xz z `metadata.json` + `data.tar.xz`),
69 -gotowe do instalacji przez `pag install plik.pag`. W repo trzymamy wyłącznie
70 -aktualną wersję każdego pakietu — starsze są usuwane przez `pagsync`.
71 -
72 -## Budowanie lokalnie
73 -
74 -```bash
75 -pagbuild recipes/core/acl/PAGBUILD.yaml
76 -```
77 -
78 -## Narzędzia
79 -
80 -- `migrate-recipes.py` — konwertuje receptury `cards` (Pkgfile) na `PAGBUILD.yaml`
81 - (footprinty są celowo pomijane)
82 -- `strip-recipes-footprints.py` — usuwa pola `footprint*` z istniejących receptur
83 - (idempotentne; `--apply`, aby zapisać, domyślnie dry-run)
84 -
85 -## Polityka forków
86 -
87 -Fork-first w całym repo: [`../../FORK-POLICY.md`](../../FORK-POLICY.md).
88 -Krótko: co możemy zrobić forkiem, robimy forkiem — źródła w repo, pakiet
89 -`-pagan`, lokalny tarball + wyliczony sha256 (build bez sieci) i adnotacja
90 -licencyjna o statusie forka (`FORK.md` + `NOTICE`).
1 +# PaganOS Recipes
2 +
3 +Receptury pakietów dla [PaganOS](https://paganlinux.eu). Każdy plik `PAGBUILD.yaml` definiuje jak zbudować pojedynczy pakiet.
4 +
5 +## Struktura
6 +
7 +```
8 +recipes/
9 +├── core/ # pakiety bazowe (binutils, gcc, glibc, ...)
10 +├── drivers/ # sterowniki (libinput, mesa, ...)
11 +├── net/ # sieć (curl, wget, NetworkManager, ...)
12 +├── gui/ # pakiety GUI (gtk, qt, xfce, ...)
13 +├── utils/ # narzędzia (bubblewrap, ripgrep, ...)
14 +└── boot/ # bootloader (grub)
15 +```
16 +
17 +
18 +## Format PAGBUILD.yaml
19 +
20 +```yaml
21 +pkgname: acl
22 +pkgver: '2.4.0'
23 +pkgrel: 1
24 +pkgdesc: Commands for Manipulating POSIX Access Control Lists.
25 +url: http://savannah.nongnu.org/projects/acl
26 +arch: x86_64
27 +license:
28 +- GPL-2.0-only
29 +depends:
30 +- attr
31 +makedepends:
32 +- gcc
33 +source:
34 +- http://download.savannah.gnu.org/releases/${pkgname}/${pkgname}-${pkgver}.tar.gz
35 +sha256sums:
36 +- SKIP
37 +build: |
38 + cd "${pkgname}-${pkgver}"
39 + ./configure --prefix=/usr
40 + make -j$(nproc)
41 +package: |
42 + cd "${pkgname}-${pkgver}"
43 + make DESTDIR="${PKGDIR}" install
44 +```
45 +
46 +### Zmienne dostępne w fazach build/package
47 +
48 +- `${PKGDIR}` — katalog DESTDIR (instalacja pakietu)
49 +- `${pkgname}`, `${pkgver}`, `${pkgrel}` — podstawiane też w adresach `source:`
50 +
51 +### Model pakietu (jak Arch/Debian — bez footprintów)
52 +
53 +Receptura **nie deklaruje listy plików**. Faza `package:` instaluje wszystko do
54 +`${PKGDIR}` (DESTDIR) i z tego katalogu `pagbuild` tworzy **jeden pakiet** —
55 +dokładnie jak `PKGBUILD` w Archu czy reguły `install` w Debianie. Lista plików
56 +nie jest danymi wejściowymi, tylko **pochodną** pakietu: `pag` wylicza SHA256
57 +dla każdego pliku przy instalacji i zapisuje je w `/var/lib/pag/files.db`
58 +(rola, którą w Debianie pełni `md5sums`/`.list`, a w Archu `.MTREE`).
59 +
60 +> **Nie używamy już pól `footprint`, `footprint_devel`, `footprint_man`,
61 +> `footprint_<lang>`** — to balast z formatu cards/NuTyX, którego `pagbuild`
62 +> nigdy nie czytał. Podpakiety deweloperskie/dokumentacyjne/językowe są scalane
63 +> z pakietem głównym (ich pliki i tak trafiają do DESTDIR). Do usuwania tych pól
64 +> z istniejących receptur służy `strip-recipes-footprints.py`.
65 +
66 +### Pakiet wyjściowy
67 +
68 +`pagbuild` buduje pakiety **`.pag`** (tar.xz z `metadata.json` + `data.tar.xz`),
69 +gotowe do instalacji przez `pag install plik.pag`. W repo trzymamy wyłącznie
70 +aktualną wersję każdego pakietu — starsze są usuwane przez `pagsync`.
71 +
72 +## Pakiet wydania (`pagan-release`) — wersja systemu przez repo
73 +
74 +`recipes/core/pagan-release` to **pakiet wydania** („os-info”). Jego `pkgver`
75 +JEST wersją systemu, a `depends` opisuje, co to wydanie ma zawierać.
76 +
77 +Dlaczego tak, a nie „wersja wpisana w obraz”:
78 +
79 +* pliki `/etc/os-release` i `/etc/pagan-release` należą do PAKIETU, więc
80 + `pag verify` je obejmuje, a `pag upgrade` podmienia je przy nowszej wersji
81 + (z ochroną `.pacnew`, jeśli użytkownik je zmienił),
82 +* w obrazie pakiet jest instalowany od razu, więc `pag base register`
83 + zapamiętuje go z wersją obrazu,
84 +* `provides: pagan-system=<wersja>` pozwala innym pakietom wymagać
85 + `pagan-system>=1.0.0` bez wiązania się z nazwą pakietu wydania,
86 +* klucze dodatkowe `codename:` i `desktop:` (pagbuild je ignoruje) czyta
87 + `build-pagan.sh` — jedno miejsce z prawdą o kodename i środowisku.
88 +
89 +### Nowe wydanie — kolejność
90 +
91 +1. Podnieś `pkgver` (i ewentualnie `codename`) w
92 + `recipes/core/pagan-release/PAGBUILD.yaml`; dopisz nowe pozycje w `depends`,
93 + jeśli wydanie ma dołożyć tapety/programy.
94 +2. Podnieś `PAGAN_VERSION` w `build-pagan.sh` (builder ostrzeże w fazie
95 + weryfikacji obrazu, jeśli te dwie wartości się rozjadą).
96 +3. `pagbuild pagan-release` → podpis → `pagsync --gen-repo` (albo GUI-Build).
97 +4. Na maszynie użytkownika: `sudo pag upgrade` → nowa wersja systemu.
98 +
99 +### Uwagi
100 +
101 +* **`depends` muszą istnieć w repozytorium.** `pagan-wallpapers` buduje sam
102 + builder (tapety leżą w `branding/`, do którego repo receptur nie ma dostępu),
103 + więc jego `.pag` (z `ISO/packages/` po buildzie) wysyła się do repozytorium
104 + razem z `pagan-release`.
105 +* Hooki: katalog `hooks/` w `.pag` obsługuje `pre-install`, `post-install`,
106 + `pre-remove`, `post-remove` (API `PKG_HOOK_API`, `PAG_NO_HOOKS=1` wyłącza,
107 + `PAG_HOOK_TIMEOUT` ogranicza czas). `pagan-release` używa `post-install` do
108 + odświeżenia baz pulpitu/ikon po dodaniu programów w wydaniu.
109 +
110 +## Receptury z własną konfiguracją (`pagan-xfce-panel-layout`)
111 +
112 +Nie każdy pakiet jest kompilowany – niektóre wnoszą samą **konfigurację**.
113 +Wzorzec: pliki leżą w katalogu receptury i są wymienione w `source:` (pagbuild
114 +kopiuje je do katalogu budowy, więc w `build:` są dostępne po nazwie, bez
115 +ścieżek).
116 +
117 +Przykład: `recipes/gui/pagan-xfce-panel-layout` wnosi domyślny układ panelu XFCE
118 +(`/etc/xdg/xfce4/panel/default.xml`) oraz skrypty widgetów genmon
119 +(`/usr/libexec/pagan/panel/`: CPU, RAM, sieć, bateria).
120 +
121 +### Jedno źródło prawdy dla repo i ISO
122 +
123 +Układ panelu generuje `gen-panel-xml.sh` z **tej samej** receptury, której używa
124 +`build-pagan.sh` – nie ma drugiej kopii definicji układu do rozjechania:
125 +
126 +* tutaj (pagbuild) generator jest wołany **bez flag**, bo `depends` gwarantuje
127 + obecność wtyczek (`xfce4-panel`, `xfce4-whiskermenu-plugin`,
128 + `xfce4-genmon-plugin`, `xfce4-clipman-plugin`),
129 +* `build-pagan.sh` buduje te wtyczki „best-effort”, więc sam wykrywa braki
130 + w rootfs i przekazuje je flagami (`--no-whiskermenu`, `--no-genmon`,
131 + `--no-clipman`) – panel nigdy nie wskazuje na niezainstalowany moduł.
132 +
133 +Zmieniając układ panelu (kolejność wtyczek, widgety, ulubione w menu) edytuje
134 +się **tylko** `gen-panel-xml.sh` i podnosi `pkgver` w tej recepturze.
135 +
136 +## Budowanie lokalnie
137 +
138 +```bash
139 +pagbuild recipes/core/acl/PAGBUILD.yaml
140 +```
141 +
142 +## Narzędzia
143 +
144 +- `migrate-recipes.py` — konwertuje receptury `cards` (Pkgfile) na `PAGBUILD.yaml`
145 + (footprinty są celowo pomijane)
146 +- `strip-recipes-footprints.py` — usuwa pola `footprint*` z istniejących receptur
147 + (idempotentne; `--apply`, aby zapisać, domyślnie dry-run)
148 +
149 +## Polityka forków
150 +
151 +Fork-first w całym repo: [`../../FORK-POLICY.md`](../../FORK-POLICY.md).
152 +Krótko: co możemy zrobić forkiem, robimy forkiem — źródła w repo, pakiet
153 +`-pagan`, lokalny tarball + wyliczony sha256 (build bez sieci) i adnotacja
154 +licencyjna o statusie forka (`FORK.md` + `NOTICE`).
91 155 new file mode 100644
@@ -0,0 +1,90 @@
1 +# Pagan Linux – PAKIET WYDANIA (os-info).
2 +#
3 +# PO CO: żeby wersję systemu dało się podnosić PRZEZ REPOZYTORIUM, bez nowego ISO.
4 +# Ten pakiet jest „metadanymi wydania”:
5 +#
6 +# • jego pkgver JEST wersją systemu (trafia do /etc/os-release),
7 +# • jego depends opisuje, co to wydanie ma zawierać (tapety, programy),
8 +# • pliki /etc/os-release i /etc/pagan-release stają się WŁASNOŚCIĄ pakietu,
9 +# więc `pag verify` je obejmuje, a `pag upgrade` podmienia je przy nowszej
10 +# wersji – z ochroną .pacnew, jeśli użytkownik je zmienił.
11 +#
12 +# Nowe wydanie = podnieś pkgver, dopisz nowe pozycje w depends, zbuduj i opublikuj:
13 +# pagbuild pagan-release && (podpis + pagsync --gen-repo / GUI-Build)
14 +# Na maszynie użytkownika: sudo pag upgrade → nowa wersja systemu.
15 +#
16 +# UWAGA o spójności: build-pagan.sh ma własne PAGAN_VERSION i ostrzeże w fazie
17 +# weryfikacji obrazu, jeśli pkgver tutaj się rozjedzie. Trzymaj je razem.
18 +pkgname: pagan-release
19 +pkgver: '0.5.2'
20 +pkgrel: 1
21 +pkgdesc: 'Pagan Linux – pakiet wydania: wersja systemu (/etc/os-release) i zależności wydania.'
22 +url: https://paganlinux.eu
23 +arch: x86_64
24 +license:
25 +- GPL-2.0-only
26 +
27 +# Klucze dodatkowe (pagbuild je ignoruje, czyta je build-pagan.sh) – jedno miejsce
28 +# z prawdą o kodename i środowisku wydania.
29 +codename: 'Mokosza'
30 +desktop: xfce
31 +
32 +# Co to wydanie ma zawierać. NAZWY MUSZĄ ISTNIEĆ W REPOZYTORIUM, inaczej
33 +# `pag install pagan-release` na czystej maszynie padnie na brakującym pakiecie.
34 +# `pagan-wallpapers` buduje sam builder (tapety leżą w branding/, do którego to
35 +# repo nie ma dostępu) – jego .pag wysyła się do repozytorium razem z tym pakietem.
36 +depends:
37 +- pagan-wallpapers
38 +- nano
39 +- fish
40 +- thunar
41 +- noto-fonts
42 +- wget
43 +makedepends: []
44 +
45 +# Zależność wirtualna: inne pakiety mogą wymagać „pagan-system” w dowolnej wersji
46 +# (`pagan-system>=0.5.0`) nie wiążąc się z konkretną nazwą pakietu wydania.
47 +provides:
48 +- pagan-system=0.5.0
49 +
50 +# UWAGA na wcięcia: w bloku `|` YAML odcina wcięcie od pierwszej linii, więc
51 +# KAŻDA linia poniżej (także ciała heredoców) musi mieć te same 2 spacje –
52 +# inaczej shell zobaczy treść z wcięciem, a /etc/os-release nie może mieć
53 +# wiodących spacji.
54 +build: |
55 + mkdir -p "${PKGDIR}/etc" "${PKGDIR}/usr/share/pag"
56 +
57 + cat > "${PKGDIR}/etc/os-release" <<EOF
58 + NAME="Pagan Linux"
59 + VERSION="${pkgver} Mokosza"
60 + VERSION_ID="${pkgver}"
61 + ID=pagan
62 + ID_LIKE=linux
63 + PRETTY_NAME="Pagan Linux ${pkgver} Mokosza"
64 + ANSI_COLOR="1;32"
65 + LOGO=paganlinux
66 + HOME_URL="https://paganlinux.eu"
67 + SUPPORT_URL="https://paganlinux.eu/support"
68 + BUG_REPORT_URL="https://paganlinux.eu"
69 + EOF
70 +
71 + cat > "${PKGDIR}/etc/pagan-release" <<EOF
72 + Pagan Linux ${pkgver} Mokosza
73 + Wersja wydania: ${pkgver}
74 + Kodename: Mokosza
75 + Środowisko: xfce
76 + EOF
77 +
78 + cat > "${PKGDIR}/usr/share/pag/release.conf" <<EOF
79 + name=Pagan Linux
80 + version=${pkgver}
81 + codename=Mokosza
82 + desktop=xfce
83 + EOF
84 +
85 + chmod 644 "${PKGDIR}/etc/os-release" \
86 + "${PKGDIR}/etc/pagan-release" \
87 + "${PKGDIR}/usr/share/pag/release.conf"
88 +
89 +package: |
90 + true
0 91 new file mode 100755
@@ -0,0 +1,199 @@
1 +#!/bin/sh
2 +# pagan-wifi – wybór sieci Wi-Fi w PaganLinux (NetworkManager + nmcli).
3 +#
4 +# Uruchamiane z menu/pulpitu w sesji live, ale działa też w zainstalowanym
5 +# systemie. Bez zależności poza nmcli (jest w NetworkManagerze) i xfce4-terminal
6 +# jako hostem okna.
7 +#
8 +# Tryby:
9 +# pagan-wifi – interaktywny wybór sieci
10 +# pagan-wifi --list – sama lista wykrytych sieci (do diagnostyki/testów)
11 +# pagan-wifi --status – stan interfejsów i adresy IP
12 +
13 +set -u
14 +
15 +# Terse output nmcli jest stabilny maszynowo, ale komunikaty dla użytkownika
16 +# zostawiamy po polsku (piszemy je sami, nie tłumaczymy nmcli).
17 +msg() { printf '%s\n' "$*"; }
18 +err() { printf '%s\n' "$*" >&2; }
19 +
20 +have_nmcli() {
21 + command -v nmcli >/dev/null 2>&1
22 +}
23 +
24 +# Nazwa interfejsu Wi-Fi (puste, jeśli brak karty).
25 +wifi_iface() {
26 + nmcli -t -f DEVICE,TYPE device 2>/dev/null | awk -F: '$2 == "wifi" { print $1; exit }'
27 +}
28 +
29 +# Lista sieci: "SIGNAL<TAB>SECURITY<TAB>SSID", posortowana malejąco po sygnale.
30 +#
31 +# Uwaga na format: `nmcli -t` rozdziela pola dwukropkiem, a SSID może dwukropki
32 +# zawierać. `-e no` wyłącza escapowanie (inaczej nmcli zapisuje je jako \:) i
33 +# wtedy dwoma ostatnimi polami są zawsze SYGNAŁ i ZABEZPIECZENIA, a SSID to
34 +# wszystko przed nimi.
35 +list_networks() {
36 + nmcli -e no -t -f SSID,SIGNAL,SECURITY device wifi list --rescan yes 2>/dev/null | \
37 + awk -F: '
38 + NF >= 3 {
39 + sec = $NF
40 + sig = $(NF - 1)
41 + ssid = ""
42 + for (i = 1; i < NF - 1; i++) {
43 + ssid = ssid (i > 1 ? ":" : "") $i
44 + }
45 + if (ssid == "" || sig == "") {
46 + next
47 + }
48 + if (!(ssid in best) || sig + 0 > best[ssid] + 0) {
49 + best[ssid] = sig
50 + secs[ssid] = sec
51 + }
52 + }
53 + END {
54 + for (s in best) {
55 + printf "%s\t%s\t%s\n", best[s], secs[s], s
56 + }
57 + }
58 + ' | sort -rn
59 +}
60 +
61 +show_status() {
62 + msg "=== Interfejsy (nmcli device) ==="
63 + nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device 2>/dev/null | tr ':' '\t' || true
64 + msg ""
65 + msg "=== Adresy IP ==="
66 + if command -v ip >/dev/null 2>&1; then
67 + ip -4 -brief addr 2>/dev/null || ip -4 addr 2>/dev/null || true
68 + fi
69 + msg ""
70 + msg "=== Łączność ==="
71 + if ping -c1 -W3 1.1.1.1 >/dev/null 2>&1; then
72 + msg "Internet: OK (1.1.1.1 odpowiada)"
73 + else
74 + msg "Internet: brak odpowiedzi z 1.1.1.1"
75 + fi
76 +}
77 +
78 +connect_network() {
79 + _ssid="$1"
80 + _sec="$2"
81 +
82 + _pass=""
83 + if [ "$_sec" != "--" ] && [ "$_sec" != "" ]; then
84 + printf 'Hasło do "%s" (nie będzie widoczne): ' "$_ssid"
85 + if command -v stty >/dev/null 2>&1; then
86 + stty -echo 2>/dev/null || true
87 + read -r _pass
88 + stty echo 2>/dev/null || true
89 + printf '\n'
90 + else
91 + read -r _pass
92 + fi
93 + fi
94 +
95 + msg "Łączenie z \"$_ssid\"..."
96 + if [ -n "$_pass" ]; then
97 + if nmcli device wifi connect "$_ssid" password "$_pass"; then
98 + _rc=0
99 + else
100 + _rc=1
101 + fi
102 + else
103 + if nmcli device wifi connect "$_ssid"; then
104 + _rc=0
105 + else
106 + _rc=1
107 + fi
108 + fi
109 + _pass=""
110 +
111 + if [ "$_rc" -eq 0 ]; then
112 + msg "Połączono."
113 + else
114 + err "Nie udało się połączyć. Sprawdź hasło albo spróbuj ponownie."
115 + fi
116 + msg ""
117 + show_status
118 + return "$_rc"
119 +}
120 +
121 +interactive() {
122 + if ! have_nmcli; then
123 + err "Brak polecenia nmcli. Zainstaluj/uruchom NetworkManager: sudo systemctl start NetworkManager"
124 + return 1
125 + fi
126 +
127 + _iface="$(wifi_iface)"
128 + if [ -z "$_iface" ]; then
129 + err "Nie wykryto karty Wi-Fi."
130 + err "Sprawdź, czy adapter jest widoczny: lsusb / ip link"
131 + err "Oraz czy sterownik się załadował: dmesg | grep -i firmware"
132 + msg ""
133 + show_status
134 + return 1
135 + fi
136 +
137 + msg "Karta Wi-Fi: $_iface"
138 + msg "Szukam sieci (chwilę to potrwa)..."
139 + _list="$(list_networks)"
140 +
141 + if [ -z "$_list" ]; then
142 + err "Nie znaleziono żadnej sieci Wi-Fi."
143 + return 1
144 + fi
145 +
146 + # Numerowana lista (zachowujemy SSID i zabezpieczenia w plikach tymczasowych).
147 + _tmp="$(mktemp)" || return 1
148 + printf '%s\n' "$_list" | awk -F'\t' '{ printf "%2d) %-32s %3s%% %s\n", NR, $3, $1, $2 }'
149 + printf '%s\n' "$_list" > "$_tmp"
150 +
151 + printf '\nNumer sieci (lub "q" aby wyjść): '
152 + read -r _choice
153 + case "$_choice" in
154 + q|Q|"")
155 + rm -f "$_tmp"
156 + return 0
157 + ;;
158 + esac
159 +
160 + case "$_choice" in
161 + *[!0-9]*)
162 + err "Niepoprawny wybór."
163 + rm -f "$_tmp"
164 + return 1
165 + ;;
166 + esac
167 +
168 + _entry="$(sed -n "${_choice}p" "$_tmp")"
169 + rm -f "$_tmp"
170 + if [ -z "$_entry" ]; then
171 + err "Nie ma sieci o numerze $_choice."
172 + return 1
173 + fi
174 +
175 + _sig="$(printf '%s' "$_entry" | cut -f1)"
176 + _sec="$(printf '%s' "$_entry" | cut -f2)"
177 + _ssid="$(printf '%s' "$_entry" | cut -f3-)"
178 +
179 + connect_network "$_ssid" "$_sec"
180 + return $?
181 +}
182 +
183 +case "${1:-}" in
184 + --list)
185 + list_networks
186 + ;;
187 + --status)
188 + show_status
189 + ;;
190 + --help|-h)
191 + msg "pagan-wifi – wybór sieci Wi-Fi (NetworkManager)"
192 + msg " pagan-wifi interaktywny wybór sieci"
193 + msg " pagan-wifi --list lista wykrytych sieci"
194 + msg " pagan-wifi --status stan interfejsów i adresy IP"
195 + ;;
196 + *)
197 + interactive
198 + ;;
199 +esac
0 200 new file mode 100644
@@ -0,0 +1,63 @@
1 +# Pagan Linux – domyślny układ panelu XFCE + widgety genmon.
2 +#
3 +# ── PO CO OSOBNY PAKIET ─────────────────────────────────────────────────
4 +# Układ panelu (/etc/xdg/xfce4/panel/default.xml) i skrypty widgetów nie należą
5 +# do żadnej wtyczki z osobna – to NASZA konfiguracja. Trzymanie ich w recepturze
6 +# (a nie tylko w build-pagan.sh) daje jedno źródło prawdy: ten sam
7 +# gen-panel-xml.sh woła i pagbuild (tutaj), i builder ISO.
8 +#
9 +# ── ZALEŻNOŚCI SĄ CELOWO TWARDE ─────────────────────────────────────────
10 +# gen-panel-xml.sh generuje tu PEŁNY układ, więc każda wymieniona wtyczka musi
11 +# być zainstalowana – inaczej panel wskazywałby na nieistniejący moduł
12 +# („broken plugin”) i pokazywał użytkownikowi błąd. Builder ISO buduje wtyczki
13 +# „best-effort”, dlatego tamten sam generator wyłącza brakujące flagami
14 +# (--no-whiskermenu / --no-genmon / --no-clipman).
15 +#
16 +# ── WERSJONOWANIE ───────────────────────────────────────────────────────
17 +# pkgver podnosimy, gdy zmienia się układ panelu albo skrypty widgetów – dzięki
18 +# temu `pag upgrade` na maszynie użytkownika podłoży nową wersję.
19 +pkgname: pagan-xfce-panel-layout
20 +pkgver: '1.0'
21 +pkgrel: 1
22 +pkgdesc: 'Pagan Linux – domyślny układ panelu XFCE: Whisker Menu + widgety genmon (CPU/RAM/sieć/bateria).'
23 +url: https://paganlinux.eu
24 +arch: x86_64
25 +license:
26 +- GPL-2.0-only
27 +
28 +depends:
29 +- xfce4-panel
30 +- xfce4-whiskermenu-plugin
31 +- xfce4-genmon-plugin
32 +- xfce4-clipman-plugin
33 +makedepends: []
34 +
35 +# Wszystko lokalne (pliki z tego katalogu). pagbuild kopiuje je do katalogu
36 +# budowy, więc w `build:` są dostępne po nazwie (bez ścieżek).
37 +source:
38 +- 'gen-panel-xml.sh'
39 +- 'genmon-cpu.sh'
40 +- 'genmon-ram.sh'
41 +- 'genmon-net.sh'
42 +- 'genmon-battery.sh'
43 +
44 +sha256sums:
45 +- SKIP
46 +- SKIP
47 +- SKIP
48 +- SKIP
49 +- SKIP
50 +
51 +build: |
52 + install -d "${PKGDIR}/etc/xdg/xfce4/panel" "${PKGDIR}/usr/libexec/pagan/panel"
53 +
54 + # Układ panelu – pełny (bez flag wyłączających).
55 + bash gen-panel-xml.sh > "${PKGDIR}/etc/xdg/xfce4/panel/default.xml"
56 +
57 + # Skrypty widgetów. Ścieżkę tego katalogu wpisuje generator jako komendę
58 + # wtyczki genmon (jego --widgets-dir domyślnie = /usr/libexec/pagan/panel).
59 + install -m755 genmon-cpu.sh genmon-ram.sh genmon-net.sh genmon-battery.sh \
60 + "${PKGDIR}/usr/libexec/pagan/panel/"
61 +
62 +package: |
63 + true
0 64 new file mode 100755
@@ -0,0 +1,211 @@
1 +#!/bin/bash
2 +# Pagan Linux – generator domyślnego układu panelu XFCE (default.xml).
3 +#
4 +# ── JEDNO ŹRÓDŁO PRAWDY DLA UKŁADU PANELU ────────────────────────────────
5 +# Układ panelu (menu, widgety genmon, tacka, zegar) jest zdefiniowany TYLKO
6 +# tutaj. Korzystają z niego dwa miejsca:
7 +#
8 +# 1. receptura pagan-xfce-panel-layout (ten katalog) – jej `depends`
9 +# gwarantuje, że wszystkie wtyczki są zainstalowane, więc woła generator
10 +# BEZ flag wyłączających (pełny układ) i pakuje wynik do .pag,
11 +#
12 +# 2. build-pagan.sh – buduje wtyczki „best-effort”, więc wykrywa, czego
13 +# brakuje w rootfs, i wyłącza to flagami (--no-genmon itd.). Dzięki temu
14 +# panel nigdy nie wskazuje na niezainstalowany moduł („broken plugin”).
15 +#
16 +# Wynik leci na stdout (pełny plik /etc/xdg/xfce4/panel/default.xml), więc
17 +# wołający decyduje, gdzie go zapisać.
18 +#
19 +# ── Użycie ──────────────────────────────────────────────────────────────
20 +# gen-panel-xml.sh [--configver N] [--widgets-dir DIR]
21 +# [--no-whiskermenu] [--no-genmon] [--no-clipman]
22 +#
23 +# --configver N wartość configver (domyślnie 2 = seria Xfce 4.20).
24 +# xfconf migruje układy po tym numerze, więc zmiana serii
25 +# Xfce nie musi oznaczać zmiany naszego układu.
26 +# --widgets-dir DIR katalog skryptów widgetów genmon wpisywany jako komenda
27 +# wtyczki (domyślnie /usr/libexec/pagan/panel).
28 +# --no-whiskermenu menu = applicationsmenu (Whisker Menu nieobecne).
29 +# --no-genmon pomiń widgety CPU/RAM/sieć/bateria.
30 +# --no-clipman pomiń menedżer schowka.
31 +#
32 +# ── Dlaczego nie ma tu sztywnych numerów plugin-N ───────────────────────
33 +# Numery wtyczek nadajemy dynamicznie, w kolejności wywołań. Dzięki temu
34 +# pominięcie wtyczki flagą nie zostawia dziur w plugin-ids i nie trzeba
35 +# pilnować ręcznej numeracji przy każdej zmianie układu.
36 +
37 +set -euo pipefail
38 +
39 +CONFIGVER=2
40 +WIDGETS_DIR=/usr/libexec/pagan/panel
41 +MENU=whiskermenu
42 +WITH_GENMON=1
43 +WITH_CLIPMAN=1
44 +
45 +usage() {
46 + cat >&2 <<'EOF'
47 +Użycie: gen-panel-xml.sh [opcje]
48 + --configver N wartość configver (domyślnie 2)
49 + --widgets-dir DIR katalog skryptów genmon (domyślnie /usr/libexec/pagan/panel)
50 + --no-whiskermenu użyj applicationsmenu zamiast Whisker Menu
51 + --no-genmon pomiń widgety CPU/RAM/sieć/bateria
52 + --no-clipman pomiń menedżer schowka
53 + -h, --help ta pomoc
54 +EOF
55 +}
56 +
57 +while [[ $# -gt 0 ]]; do
58 + case "$1" in
59 + --configver) CONFIGVER="$2"; shift 2 ;;
60 + --widgets-dir) WIDGETS_DIR="$2"; shift 2 ;;
61 + --no-whiskermenu) MENU=applicationsmenu; shift ;;
62 + --no-genmon) WITH_GENMON=0; shift ;;
63 + --no-clipman) WITH_CLIPMAN=0; shift ;;
64 + -h|--help) usage; exit 0 ;;
65 + *) echo "gen-panel-xml.sh: nieznana opcja: $1" >&2; usage; exit 2 ;;
66 + esac
67 +done
68 +
69 +# ── Generator układu ────────────────────────────────────────────────────
70 +N=0
71 +P1_IDS=""
72 +P2_IDS=""
73 +PDEFS=""
74 +
75 +# _panel_plug <panel:1|2> <nazwa-wtyczki> [xml-konfiguracji]
76 +_panel_plug() {
77 + local _panel="$1" _name="$2" _extra="${3:-}"
78 + N=$((N + 1))
79 + if [[ "$_panel" == 1 ]]; then
80 + P1_IDS+=" <value type=\"int\" value=\"$N\"/>"$'\n'
81 + else
82 + P2_IDS+=" <value type=\"int\" value=\"$N\"/>"$'\n'
83 + fi
84 + if [[ -n "$_extra" ]]; then
85 + PDEFS+=" <property name=\"plugin-$N\" type=\"string\" value=\"$_name\">"$'\n'"$_extra"" </property>"$'\n'
86 + else
87 + PDEFS+=" <property name=\"plugin-$N\" type=\"string\" value=\"$_name\"/>"$'\n'
88 + fi
89 +}
90 +
91 +# _panel_sep <panel> [expand] – separator (jak w domyślnym układzie Xfce)
92 +_panel_sep() {
93 + if [[ "${2:-}" == expand ]]; then
94 + _panel_plug "$1" separator ' <property name="expand" type="bool" value="true"/>
95 + <property name="style" type="uint" value="0"/>
96 +'
97 + else
98 + _panel_plug "$1" separator ' <property name="style" type="uint" value="0"/>
99 +'
100 + fi
101 +}
102 +
103 +# _panel_genmon <panel> <skrypt> <okres-ms> – widget z genmon-*.sh (ten katalog).
104 +# Ścieżkę podajemy bezwzględną: genmon uruchamia komendę przez
105 +# g_shell_parse_argv (bez shella i bez PATH z profilu użytkownika).
106 +_panel_genmon() {
107 + _panel_plug "$1" genmon " <property name=\"use-label\" type=\"bool\" value=\"false\"/>
108 + <property name=\"command\" type=\"string\" value=\"$WIDGETS_DIR/$2\"/>
109 + <property name=\"update-period\" type=\"int\" value=\"$3\"/>
110 + <property name=\"font\" type=\"string\" value=\"(default)\"/>
111 +"
112 +}
113 +
114 +# _panel_launcher <panel> <id.desktop>
115 +_panel_launcher() {
116 + _panel_plug "$1" launcher " <property name=\"items\" type=\"array\">
117 + <value type=\"string\" value=\"$2\"/>
118 + </property>
119 +"
120 +}
121 +
122 +# Konfiguracja Whisker Menu (tylko gdy używamy tej wtyczki). „Ulubione” to
123 +# identyfikatory .desktop – te same, których używa panel (xdg-utils) i które
124 +# whiskermenu sam mapuje z historycznych nazw exo-* (patrz settings.cpp).
125 +MENU_EXTRA=""
126 +if [[ "$MENU" == whiskermenu ]]; then
127 + MENU_EXTRA=' <property name="view-mode" type="int" value="0"/>
128 + <property name="launcher-icon-size" type="int" value="3"/>
129 + <property name="category-icon-size" type="int" value="1"/>
130 + <property name="launcher-show-description" type="bool" value="false"/>
131 + <property name="menu-width" type="int" value="420"/>
132 + <property name="menu-height" type="int" value="520"/>
133 + <property name="favorites" type="array">
134 + <value type="string" value="xfce4-file-manager.desktop"/>
135 + <value type="string" value="xfce4-terminal-emulator.desktop"/>
136 + <value type="string" value="xfce4-web-browser.desktop"/>
137 + <value type="string" value="org.xfce.mousepad.desktop"/>
138 + <value type="string" value="org.xfce.ristretto.desktop"/>
139 + <value type="string" value="xfce4-appfinder.desktop"/>
140 + <value type="string" value="xfce-settings-manager.desktop"/>
141 + </property>
142 +'
143 +fi
144 +
145 +# ── Panel górny: menu | okna | … statusy … | zegar | menu zasilania ──
146 +_panel_plug 1 "$MENU" "$MENU_EXTRA"
147 +_panel_plug 1 tasklist ' <property name="grouping" type="uint" value="1"/>
148 +'
149 +_panel_sep 1 expand
150 +_panel_plug 1 pager
151 +_panel_sep 1
152 +if [[ "$WITH_GENMON" == 1 ]]; then
153 + _panel_genmon 1 genmon-cpu.sh 2000
154 + _panel_genmon 1 genmon-ram.sh 3000
155 + _panel_genmon 1 genmon-net.sh 2000
156 + _panel_genmon 1 genmon-battery.sh 30000
157 +fi
158 +_panel_sep 1
159 +_panel_plug 1 systray ' <property name="square-icons" type="bool" value="true"/>
160 +'
161 +if [[ "$WITH_CLIPMAN" == 1 ]]; then
162 + _panel_plug 1 xfce4-clipman-plugin
163 +fi
164 +_panel_sep 1
165 +_panel_plug 1 clock
166 +_panel_sep 1
167 +_panel_plug 1 actions
168 +
169 +# ── Panel dolny (dock, autohide) ──
170 +_panel_plug 2 showdesktop
171 +_panel_plug 2 separator
172 +_panel_launcher 2 xfce4-terminal-emulator.desktop
173 +_panel_launcher 2 xfce4-file-manager.desktop
174 +_panel_launcher 2 xfce4-web-browser.desktop
175 +_panel_launcher 2 xfce4-appfinder.desktop
176 +_panel_plug 2 separator
177 +_panel_plug 2 directorymenu
178 +
179 +# ── Emisja pliku ──
180 +cat <<EOF
181 +<?xml version="1.0" encoding="UTF-8"?>
182 +
183 +<channel name="xfce4-panel" version="1.0">
184 + <property name="configver" type="int" value="${CONFIGVER}"/>
185 + <property name="panels" type="array">
186 + <value type="int" value="1"/>
187 + <value type="int" value="2"/>
188 + <property name="dark-mode" type="bool" value="true"/>
189 + <property name="panel-1" type="empty">
190 + <property name="position" type="string" value="p=6;x=0;y=0"/>
191 + <property name="length" type="uint" value="100"/>
192 + <property name="position-locked" type="bool" value="true"/>
193 + <property name="icon-size" type="uint" value="16"/>
194 + <property name="size" type="uint" value="26"/>
195 + <property name="plugin-ids" type="array">
196 +${P1_IDS} </property>
197 + </property>
198 + <property name="panel-2" type="empty">
199 + <property name="autohide-behavior" type="uint" value="1"/>
200 + <property name="position" type="string" value="p=10;x=0;y=0"/>
201 + <property name="length" type="uint" value="1"/>
202 + <property name="position-locked" type="bool" value="true"/>
203 + <property name="size" type="uint" value="48"/>
204 + <property name="plugin-ids" type="array">
205 +${P2_IDS} </property>
206 + </property>
207 + </property>
208 + <property name="plugins" type="empty">
209 +${PDEFS} </property>
210 +</channel>
211 +EOF
0 212 new file mode 100755
@@ -0,0 +1,52 @@
1 +#!/bin/sh
2 +# Pagan-Flat – widget panelu XFCE (xfce4-genmon-plugin): bateria.
3 +#
4 +# Czyta /sys/class/power_supply/* – bez upower/acpi (działa też bez usługi).
5 +# Gdy w systemie nie ma baterii (desktop, maszyna wirtualna), skrypt nie
6 +# wypisuje nic: genmon pokaże wtedy pusty widget zamiast błędu.
7 +#
8 +# Ikona zależy od poziomu naładowania i stanu (ładowanie), wg nazw z Papirusa:
9 +# battery-NNN-symbolic (NNN = 000, 010, ... 100)
10 +# battery-NNN-charging-symbolic
11 +
12 +LC_ALL=C
13 +export LC_ALL
14 +
15 +bat=""
16 +for d in /sys/class/power_supply/*; do
17 + [ -e "$d" ] || continue
18 + read -r type < "$d/type" 2>/dev/null
19 + [ "$type" = "Battery" ] || continue
20 + bat=$d
21 + break
22 +done
23 +
24 +# Brak baterii → puste wyjście (widget bez treści).
25 +[ -n "$bat" ] || exit 0
26 +
27 +read -r cap < "$bat/capacity" 2>/dev/null
28 +read -r status < "$bat/status" 2>/dev/null
29 +
30 +case "$cap" in
31 + ''|*[!0-9]*) printf '<txt>—</txt><tool>Bateria: brak danych</tool>\n'; exit 0 ;;
32 +esac
33 +
34 +# Poziom zaokrąglamy do najbliższej dziesiątki (nazwy ikon Papirusa).
35 +lvl=$(( (cap + 5) / 10 * 10 ))
36 +[ "$lvl" -lt 0 ] && lvl=0
37 +[ "$lvl" -gt 100 ] && lvl=100
38 +
39 +st_pl="$status"
40 +case "$status" in
41 + Charging)
42 + st_pl="ładowanie"
43 + icon=$(printf 'battery-%03d-charging-symbolic' "$lvl")
44 + ;;
45 + Discharging) st_pl="rozładowywanie"; icon=$(printf 'battery-%03d-symbolic' "$lvl") ;;
46 + Full) st_pl="naładowana"; icon=$(printf 'battery-%03d-symbolic' "$lvl") ;;
47 + *) icon=$(printf 'battery-%03d-symbolic' "$lvl") ;;
48 +esac
49 +
50 +pct="${cap}%"
51 +printf '<icon>%s</icon><txt>%s</txt><tool>Bateria: %s (%s)</tool>\n' \
52 + "$icon" "$pct" "$pct" "$st_pl"
0 53 new file mode 100755
@@ -0,0 +1,65 @@
1 +#!/bin/sh
2 +# Pagan-Flat – widget panelu XFCE (xfce4-genmon-plugin): obciążenie CPU.
3 +#
4 +# Skrypt wypisuje na stdout XML, które rozumie genmon (tagi <icon>, <txt>,
5 +# <tool>). Użycie CPU liczymy z różnicy dwóch odczytów /proc/stat, więc nie
6 +# potrzebujemy procps (w rootfs PaganLinux nie ma „top”/„free”) ani żadnych
7 +# innych zewnętrznych narzędzi – wystarczy sh i /proc.
8 +#
9 +# Poprzedni odczyt trzymamy w pliku w katalogu runtime użytkownika, dzięki
10 +# czemu kolejne wywołania (co ~2 s) nie muszą czekać na drugą próbkę.
11 +# Pierwsze uruchomienie (brak stanu) robi krótką próbkę 0,15 s.
12 +#
13 +# Ikona „cpu-symbolic” pochodzi z Papirus-Dark; jest monochromatyczna i CSS
14 +# motywu (.genmon_image w Pagan-Flat/gtk-3.0/gtk.css) barwi ją kolorem akcentu.
15 +
16 +LC_ALL=C
17 +export LC_ALL
18 +
19 +state_dir="${XDG_RUNTIME_DIR:-/tmp}"
20 +[ -d "$state_dir" ] || state_dir=/tmp
21 +state="$state_dir/.pagan-genmon-cpu"
22 +
23 +# Jeden odczyt /proc/stat → idle_cpu, total_cpu.
24 +# Format: cpu <user> <nice> <system> <idle> <iowait> <irq> <softirq> <steal> ...
25 +read_cpu() {
26 + read -r _cpu u n s i w irq sirq st rest < /proc/stat
27 + idle_cpu=$((i + w))
28 + total_cpu=$((u + n + s + i + w + irq + sirq + st))
29 +}
30 +
31 +prev_idle=""
32 +prev_total=""
33 +if [ -r "$state" ]; then
34 + read -r prev_idle prev_total < "$state" 2>/dev/null
35 +fi
36 +
37 +read_cpu
38 +
39 +# Próbkujemy od nowa, gdy nie ma zapisanego stanu albo liczniki się cofnęły
40 +# (np. po wznowieniu ze snu / przepełnieniu licznika jiffies).
41 +need_sample=1
42 +case "$prev_total" in
43 + ''|*[!0-9]*) ;;
44 + *) [ "$prev_total" -lt "$total_cpu" ] && [ "$prev_idle" -le "$idle_cpu" ] \
45 + && need_sample=0 ;;
46 +esac
47 +if [ "$need_sample" = 1 ]; then
48 + prev_idle=$idle_cpu
49 + prev_total=$total_cpu
50 + sleep 0.15
51 + read_cpu
52 +fi
53 +
54 +printf '%s %s\n' "$idle_cpu" "$total_cpu" > "$state" 2>/dev/null || true
55 +
56 +d_total=$((total_cpu - prev_total))
57 +d_idle=$((idle_cpu - prev_idle))
58 +[ "$d_total" -gt 0 ] || d_total=1
59 +
60 +usage=$(( (d_total - d_idle) * 100 / d_total ))
61 +[ "$usage" -lt 0 ] && usage=0
62 +[ "$usage" -gt 100 ] && usage=100
63 +
64 +pct="${usage}%"
65 +printf '<icon>cpu-symbolic</icon><txt>%s</txt><tool>CPU: %s</tool>\n' "$pct" "$pct"
0 66 new file mode 100755
@@ -0,0 +1,86 @@
1 +#!/bin/sh
2 +# Pagan-Flat – widget panelu XFCE (xfce4-genmon-plugin): ruch sieciowy.
3 +#
4 +# Pokazuje prędkość pobierania i wysyłania (w tekście obie, ikona zależna od
5 +# typu łącza). Wszystko z /proc i /sys – bez ip/ifconfig (w rootfs ich nie ma).
6 +#
7 +# Interfejs wybieramy w tej kolejności:
8 +# 1. interfejs trasy domyślnej z /proc/net/route (Destination = 00000000),
9 +# 2. pierwszy nie-loopbackowy interfejs z /sys/class/net.
10 +#
11 +# Stan (poprzedni licznik bajtów + czas z /proc/uptime) trzymamy w katalogu
12 +# runtime użytkownika. Czas bierzemy z /proc/uptime (setne sekundy), a nie
13 +# z „date”, żeby wynik był odporny na zmianę zegara systemowego.
14 +#
15 +# Ikony: network-wireless-symbolic / network-wired-symbolic (Papirus-Dark).
16 +
17 +LC_ALL=C
18 +export LC_ALL
19 +
20 +state_dir="${XDG_RUNTIME_DIR:-/tmp}"
21 +[ -d "$state_dir" ] || state_dir=/tmp
22 +state="$state_dir/.pagan-genmon-net"
23 +
24 +# 1. interfejs trasy domyślnej
25 +iface=$(awk '$2 == "00000000" { print $1; exit }' /proc/net/route)
26 +
27 +# 2. fallback: pierwszy nie-loopbackowy interfejs
28 +if [ -z "$iface" ]; then
29 + for d in /sys/class/net/*; do
30 + [ -e "$d" ] || continue
31 + n=${d##*/}
32 + [ "$n" = "lo" ] && continue
33 + iface=$n
34 + break
35 + done
36 +fi
37 +
38 +if [ -z "$iface" ]; then
39 + printf '<icon>network-wired-symbolic</icon><txt>—</txt><tool>Sieć: brak aktywnego interfejsu</tool>\n'
40 + exit 0
41 +fi
42 +
43 +read -r rx < "/sys/class/net/$iface/statistics/rx_bytes" 2>/dev/null
44 +read -r tx < "/sys/class/net/$iface/statistics/tx_bytes" 2>/dev/null
45 +read -r now _rest < /proc/uptime
46 +now=$(awk -v u="$now" 'BEGIN { printf "%d", u * 100 }') # setne sekundy
47 +
48 +prev_iface=""
49 +prev_rx=0
50 +prev_tx=0
51 +prev_now=0
52 +if [ -r "$state" ]; then
53 + read -r prev_iface prev_rx prev_tx prev_now < "$state" 2>/dev/null
54 +fi
55 +printf '%s %s %s %s\n' "$iface" "$rx" "$tx" "$now" > "$state" 2>/dev/null || true
56 +
57 +# Zmiana interfejsu lub brak poprzedniego pomiaru → zero (nie pokazujemy
58 +# bezsensownego „skoku” po przełączeniu Wi-Fi/Ethernet).
59 +drx=0
60 +dtx=0
61 +dt=0
62 +if [ "$prev_iface" = "$iface" ] && [ "$now" -gt "$prev_now" ]; then
63 + drx=$((rx - prev_rx))
64 + dtx=$((tx - prev_tx))
65 + dt=$((now - prev_now))
66 + [ "$drx" -lt 0 ] && drx=0
67 + [ "$dtx" -lt 0 ] && dtx=0
68 +fi
69 +
70 +icon=network-wired-symbolic
71 +[ -e "/sys/class/net/$iface/wireless" ] && icon=network-wireless-symbolic
72 +
73 +awk -v drx="$drx" -v dtx="$dtx" -v dt="$dt" -v iface="$iface" -v icon="$icon" '
74 + function human(b) {
75 + if (b >= 1073741824) return sprintf("%.1fG", b / 1073741824)
76 + if (b >= 1048576) return sprintf("%.1fM", b / 1048576)
77 + if (b >= 1024) return sprintf("%.0fk", b / 1024)
78 + return sprintf("%.0fB", b)
79 + }
80 + BEGIN {
81 + r = (dt > 0) ? drx * 100 / dt : 0
82 + t = (dt > 0) ? dtx * 100 / dt : 0
83 + printf "<icon>%s</icon><txt>↓%s ↑%s</txt>", icon, human(r), human(t)
84 + printf "<tool>Sieć (%s): ↓ %s/s ↑ %s/s</tool>\n", iface, human(r), human(t)
85 + }
86 +'
0 87 new file mode 100755
@@ -0,0 +1,27 @@
1 +#!/bin/sh
2 +# Pagan-Flat – widget panelu XFCE (xfce4-genmon-plugin): pamięć RAM.
3 +#
4 +# Czyta /proc/meminfo bezpośrednio (bez procps) i wypisuje XML dla genmon.
5 +# Użycie = MemTotal - MemAvailable (MemAvailable jest w jądrze od 3.14 i jest
6 +# lepszym przybliżeniem „ile jeszcze można zaalokować” niż MemFree).
7 +#
8 +# Całość liczy jeden proces awk – taniej niż wołać sh do dzielenia liczb.
9 +
10 +LC_ALL=C
11 +export LC_ALL
12 +
13 +awk '
14 + /^MemTotal:/ { total = $2 } # w kB
15 + /^MemAvailable:/ { avail = $2 } # w kB
16 + END {
17 + if (total <= 0) {
18 + print "<icon>memory-symbolic</icon><txt>—</txt><tool>RAM: brak danych</tool>"
19 + exit
20 + }
21 + used = total - avail
22 + pct = int(used * 100 / total + 0.5)
23 + printf "<icon>memory-symbolic</icon><txt>%d%%</txt>", pct
24 + printf "<tool>RAM: %.1f / %.1f GiB (%d%%)</tool>\n",
25 + used / 1048576, total / 1048576, pct
26 + }
27 +' /proc/meminfo
0 28 new file mode 100644
@@ -0,0 +1,3 @@
1 +# Polkit musi być uruchamiany od startu systemu, nie dopiero po ręcznej
2 +# aktywacji przez użytkownika lub pierwszym żądaniu D-Bus.
3 +systemctl enable polkit.service