Commit Graph

910 Commits

Author SHA1 Message Date
vasilito 0feefedf06 fix: bump ECM 6.10→6.11 for ECMGenerateQDoc module
kf6-ki18n v6.10 tarball has internal KF_VERSION 6.27 and expects
ECMGenerateQDoc which was added in ECM 6.11.
2026-06-29 09:55:54 +03:00
vasilito 1e0581b9c3 fix: kf6-ki18n — use [.] instead of \\. for TOML compat 2026-06-29 09:39:10 +03:00
vasilito c5f09c514c fix: kf6-ki18n — relax ECM requirement 6.27→6.10
KF6 tarball v6.10.0 has internal KF_VERSION 6.27.0 set by release scripts,
requiring ECM >= 6.27.0. Our ECM is 6.10.0. Relax via sed.
2026-06-29 09:22:32 +03:00
vasilito 7b9552c960 docs: QUIRKS-AUDIT — factual inventory of consumers, tombstones, DMI dup
Following a full repo-wide grep and source review of all quirks
files (mod.rs, pci_table.rs, usb_table.rs, dmi.rs, toml_loader.rs,
pci.rs, i2c-hidd/quirks.rs), this companion to QUIRKS-SYSTEM.md
documents the current ground-truth state of the subsystem as of
2026-06-29.

Findings:

- 11 Rust + 6 C consumers of the redox-driver-sys quirks engine
- 1 separate DMI quirks engine in i2c-hidd (uses RON, not TOML)
- 6 dead-code entry points that return empty flags:
  * lookup_pci_quirks_full actions (Vec::new)
  * lookup_xhci_controller_quirks_full (stub)
  * lookup_hid_quirks (stub)
  * load_dmi_acpi_quirks (stub)
  * load_platform_dmi_quirks (stub, empty PLATFORM_RULES)
  * load_drm_panel_orientation (empty PANEL_ORIENTATION_TABLE)
- 4 PciQuirkFlags bits (22-25) have no entry in PCI_FLAG_NAMES,
  so they cannot be set via /etc/quirks.d/*.toml
- DMI is consumed in two incompatible ways:
  * redox-driver-sys reads /scheme/acpi/dmi as a flat key=value file
  * i2c-hidd reads /scheme/acpi/dmi/{system_vendor,...} as per-field
    subpaths, and matches case-insensitive
- redbear-quirks stages 10 TOML files to /etc/quirks.d/; the
  TOML layer is fully live (this corrects an earlier claim
  that it was dormant)

The audit concludes that the system is correctly initialized and
utilized per its design. No redesign is needed; the existing
QUIRKS-SYSTEM.md is mostly accurate but understates how many
defined functions return empty data and how many flag names
are missing from the TOML schema.
2026-06-29 09:15:06 +03:00
vasilito 18adb41cc4 fix: ninja-build — add redox.patch to patches list
Recipe had redox.patch (fork-based subprocess + getloadavg fallback)
but wasn't declaring it in [source] patches, so cookbook never applied it.
2026-06-29 08:58:22 +03:00
vasilito ef72728368 fix: kf6-ki18n — add P1-strtold-include.patch for strtold visibility
Source comes from tar — local edits are overwritten on fetch.
Patch adds #include <stdlib.h> before Qt headers in common_helpers_p.h
so GCC <cstdlib> sees ::strtold declared.
2026-06-29 08:45:22 +03:00
vasilito cce01d0d8e fix: kf6-ki18n — include stdlib.h before Qt headers for strtold
GCC <cstdlib> needs ::strtold declared. Qt's include chain pulls in
<cstdlib> before stdlib.h. Adding #include <stdlib.h> at the top of
common_helpers_p.h fixes the 'strtold has not been declared in ::'
error. Reverted -U_GLIBCXX_USE_C99_STDLIB toolchain breakage.
2026-06-29 08:02:30 +03:00
vasilito db2d68d888 base+base-initfs: integrate CachyOS analysis improvements
Updates the local/sources/base submodule pointer to pick up the
PIIX4 IDE BAR quirk + vgaarb logging + archiso loop_mnt, and
updates the base-initfs recipe to cross-compile loop_mnt before
the redox-initfs-ar archive step.

See local/sources/base commit 2055dcd for the individual
changes.
2026-06-29 07:43:41 +03:00
vasilito 85a6a7d892 fix: undef _GLIBCXX_USE_C99_STDLIB for all Qt/KF6 via toolchain
GCC <cstdlib> uses C99 stdlib wrappers (strtold etc.) gated by this macro.
relibc declares but doesn't implement strtold. Undef at toolchain level
prevents 'using ::strtold' errors in KF6/Qt C++ builds.
2026-06-29 07:28:25 +03:00
vasilito 9d025116c2 fix: base fork — add missing 'let' for device_3 in hwd acpi.rs 2026-06-29 07:04:09 +03:00
vasilito cfc0ec078e fix: redox-toolchain.cmake — add -include stdlib.h for strtold visibility
GCC <cstdlib> needs ::strtold declared. relibc stdlib.h provides it,
but Qt include chains can pull in <cstdlib> before stdlib.h.
Adding -include stdlib.h at the toolchain level fixes all Qt/KF6 recipes.
2026-06-29 06:51:06 +03:00
vasilito d7ee730975 docs: CachyOS boot analysis reference + captured kernel log
Reference analysis for Red Bear OS integration based on running the
latest CachyOS desktop ISO (28 Jun 2026) under QEMU/KVM. Documents
the hardware-enumeration and kernel-init sequences a reference Linux
distro produces on the i440FX + PIIX machine type that Red Bear OS
also targets, with line-by-line mapping to Red Bear OS subsystems
(pcid, ided, e1000d, vesad, xhcid, hwd/acpid).

- local/docs/CACHYOS-INTEGRATION.md: Cross-cutting analysis
  (executive summary, hardware inventory, ACPI table coverage,
   PCI quirks, boot-phase ordering, init system comparison, action
   items).
- local/docs/boot-logs/cachyos-kernel-20260629-0520.log: Captured
  441-line dmesg-grade log from the CachyOS kernel boot (SeaBIOS
  handover through ACPI, PCI, USB, ATA, network enumeration and
  up to a rootfs shell prompt).
- local/docs/boot-logs/cachyos-boot-20260629-0520.md: Pointer
  document with the capture command and the rationale for the
  indirect-kernel invocation (the QEMU + CachyOS + KVM boot stalled
  at the ISOLINUX EDD probe when run from CD; bypassing with
  -kernel/-initrd and an explicit console=ttyS0 earlyprintk command
  line recovered the full log).

Sources used: https://cachyos.org/ (release info) and the on-disk
ISOLINUX + archiso boot path extracted from
cachyos-desktop-linux-260628.iso.
2026-06-29 04:49:59 +03:00
vasilito e1348228bc relibc: strtold — fix Rust 2024 unsafe block, document trailer 2026-06-29 02:57:57 +03:00
vasilito e6658cc79a fix: kf6-ki18n — force -include stdlib.h for strtold visibility
GCC <cstdlib> does 'using ::strtold;' which requires strtold declared in
global namespace. relibc declares it correctly in stdlib.h, but Qt's
include chain (qchar.h → qglobal.h → ... → cstdlib) pulls in cstdlib
before stdlib.h is fully processed. Adding -include stdlib.h ensures
the C stdlib declarations are in scope before any C++ header.
2026-06-29 02:40:49 +03:00
vasilito cb497b03f8 fix: regenerate qtdeclarative P1 patch (hunk context off by 1)
Old patch had @@ -3,5 — missing trailing context line
'add_subdirectory(qmllint)' that diff -u includes.
Regenerated from actual source.tmp to match fetched tarball.
2026-06-29 02:05:16 +03:00
vasilito 304692a11f build: relibc circular include fix (stddef→cbindgen) + config ignores
relibc (3 commits integrated from upstream, pushed to gitea:redbear-v2):
- 826a984f: stddef.h moved from hand-written C to cbindgen (3be84f4b)
  Creates bits_wchar-t, bits_size-t, bits_null sub-headers.
  Fixes missing wchar_t in inttypes.h that broke xkbcommon.
- 4eabdf20: wchar.h upstream include ordering + stdbool.h POSIX fix
  wint_t before stddef.h; dropped redundant wchar_t redefinition.
  #define bool _Bool replaces non-standard typedef.

Build config (ignores gate):
- libxkbcommon, xkeyboard-config = ignore (X11-only, not needed)
- gcc-native, gcc13 = ignore (native compilers, not needed for ISO)

gettext recipe: autoreconf path fix + disable C++/C#/Java parts.

AGENTS.md: updated relibc Header Circular Includes section with
new commits 826a984f + 4eabdf20 and stddef→cbindgen architecture.
2026-06-29 01:43:25 +03:00
vasilito fd4a40eff3 thermald: drop periodic surface-availability check
The previous commit changed the existence probe from is_dir/exists
(read_dir uses stat) to read_dir.is_ok(), but the second and subsequent
calls to read_dir for /scheme/acpi/thermal still return Err at runtime.
The first discover_zone_dirs call at startup succeeds (it sees 0 zones,
matching the acpid scheme's empty Thermal directory). The periodic
monitor_loop recheck then fails with 'unavailable' even though the
path is in fact present.

The real reason is not fully understood yet, but may relate to
scheme-namespace state after userland init, fd table churn, or
Redox-specific read_dir semantics on empty scheme directories.

The warn-once check is redundant: discover_zone_dirs already runs at
startup, and update_policy() sees the empty state every poll cycle and
re-renders the TUI accordingly. Drop the periodic recheck so the
already-diagnosed empty surface no longer logs a false alarm.
2026-06-28 20:10:45 +03:00
vasilito 24a66ac8dd relibc: suppress cbindgen warnings at build level 2026-06-28 19:28:59 +03:00
vasilito 8caefde681 relibc: no_includes=false for cbindgen type resolution 2026-06-28 19:26:25 +03:00
vasilito d6812dbc34 relibc: fix cbindgen sys_includes for missing types 2026-06-28 19:24:18 +03:00
vasilito b7341caa4d redbear-power: restore PkgW column with compact labels
- Per-CPU table: PkgW column shows 'root' (needs sudo), 'n/a'
  (unsupported), '...' (sampling), or wattage when RAPL working
- Header shows full rapl_status message for context
2026-06-28 18:56:05 +03:00
vasilito 8adc72cd6e base: expose empty /thermal and /power; handle getdents
- acpid scheme: add Thermal and Power as new HandleKind variants,
  register them in the openat match, and add entries to the TopLevel
  getdents list. thermald and redbear-upower probe /scheme/acpi/thermal
  and /scheme/acpi/power via read_dir; an empty directory is the
  correct fallback for desktops and QEMU where there is no ACPI
  _TZ/_PR data to enumerate.

- acpid scheme: also handle getdents on the new Thermal and Power
  variants. Without this, the scheme returned EIO which std::fs::read_dir
  treats as 'the path is not a directory or doesn't exist', and thermald
  emits a false 'thermal surface unavailable' warning every poll cycle.
2026-06-28 18:55:43 +03:00
vasilito b8e8774252 thermald, redbear-upower: probe ACPI surface via read_dir
Both daemons previously checked /scheme/acpi/thermal (thermald) and
/scheme/acpi/power (redbear-upower) existence with Path::exists or
is_dir, which use stat/lstat. On Redox these syscalls can return
errors for scheme paths even when the scheme IS registered, leading
to false 'unavailable' warnings even after the new acpid thermal/
power directories were added.

Use fs::read_dir (which already worked for actual zone enumeration)
as the existence probe instead. The match expression intentionally
calls read_dir to discard the iterator and keep only the Result;
using ? here would break the warn-once pattern.
2026-06-28 18:54:05 +03:00
vasilito dbb7bf74e9 redbear-power: clear PkgW status, remove redundant per-CPU PkgW column
- app.rs: rapl_status field shows 'n/a (run as root)' or
  'n/a (unsupported)' or 'sampling...' depending on state
- render.rs: header PkgW shows rapl_status when unavailable;
  removed per-CPU PkgW column (package power is socket-wide)
2026-06-28 18:51:09 +03:00
vasilito 03fd3a0690 redbear-power: synthetic P-state table from cpuinfo min-max, freq-based index matching
- acpi.rs: fallback creates 6 evenly-spaced P-states from
  cpuinfo_min_freq / cpuinfo_max_freq when scaling_available_frequencies
  is absent (intel_pstate, amd-pstate drivers)
- platform.rs: probe accepts cpuinfo_max_freq as valid PSS source
- app.rs: match current frequency against synthetic P-state table
  to compute current_idx without MSR access
- pss_source label: 'sysfs (cpuinfo min-max)' for intel_pstate
2026-06-28 18:32:24 +03:00
vasilito d2b969eb05 redbear-power: bulletproof cpufreq backend with writability check
- cpufreq.rs: complete rewrite — Backend enum (Redox/Linux), Cpufreq
  struct with self-discovering governor list, probe-based discovery
  on Redox, writability verification by writing current governor
  back. No hardcoded governor names — cycle order follows discovered
  list. Handles intel_pstate (no ondemand), permission-denied,
  and absent cpufreq gracefully.
- app.rs: Cpufreq stored in App instead of Governor enum, eliminates
  per-poll probe overhead. cycle_governor flashes root-required
  when sysfs denies write.
- render.rs, dbus.rs: use cpufreq.active string directly
2026-06-28 18:13:34 +03:00
vasilito ee086ded2d redbear-power: RAPL MSR constants, unit parsing, MSR-based energy reading
- msr.rs: add all Intel RAPL MSR addresses (0x606-0x64D) and AMD Zen
  equivalents (0xC0010299-0xC001029B), RaplUnit struct for unit register
  parsing with energy_to_uj/power_to_w conversion, read_rapl_energy()
  and read_rapl_energy_uj() functions
- acpi.rs: read_rapl_package_energy() now tries MSR first (Intel then
  AMD PKG energy MSRs) with unit-based µJ conversion, falls back to
  Linux powercap sysfs
- local/docs/RAPL-IMPLEMENTATION-PLAN.md: comprehensive 3-phase plan
  based on Linux 7.1 kernel analysis, Intel SDM, Fuchsia RFC-0203
  patterns. Documents P0 blocker: /scheme/sys/msr/ not implemented
  in kernel
2026-06-28 16:55:51 +03:00
vasilito 6da211161c redbear-power: sysfs freq fallback, RAPL package power, compact layout, governor verify, 0 warnings
- Freq/MHz: add read_cpu_freq_khz_sysfs() fallback when MSR unavailable
  (reads /sys/.../scaling_cur_freq + cpuinfo_cur_freq, like htop)
- PkgW: add RAPL powercap reading from /sys/class/powercap/intel-rapl
  with delta-to-watts computation (100ms min, 5s max guard)
- Governor: cycle_governor() + set_governor() now verify writes by
  reading back immediately; revert + flash error if kernel rejected
- Layout: reduce HEADER_LINES 8→7, replace 25-line controls panel with
  1-line key bar (g:%s ↑↓:cpu p/P:±pstate ... q:quit), freeing 24 rows
- Fix 3 unnecessary unsafe blocks in cpuid.rs (intrinsics now safe)
- Narrow #![allow] from 5 broad attrs to dead_code only + targeted
  #[allow(unreachable_patterns)] on key-dispatch match
- 0 warnings (was 53)
2026-06-28 16:29:18 +03:00
vasilito 909cce0f5d cpufreqd, redbear-power: read CPU count from /scheme/sys/cpu
On Redox the kernel's sys:cpu scheme is a single file (kernel/src/scheme/
sys/cpu.rs) whose contents start with 'CPUs: N\n', not a per-CPU directory.
The kernel does not create /dev/cpu/ at all, so the prior read_dir-based
enumeration always fell through to the single-CPU fallback on Redox —
hiding the fact that the kernel had successfully brought up the APs and
reporting only CPU 0 to the governor / power TUI.

Read /scheme/sys/cpu and parse the 'CPUs:' line first; fall back to
/dev/cpu/ for Linux hosts.
2026-06-28 16:26:30 +03:00
vasilito 8ea72c4762 relibc: fix eventfd_t cbindgen warning 2026-06-28 16:21:45 +03:00
vasilito 1eb4df5bfd config: drop unsupported 'before' field from 12_dbus.service
The local init fork's Service struct does not have a 'before' field
(it supports cmd, args, envs, inherit_envs, type only), and the
deny_unknown_fields attribute makes init panic at boot when it parses
'before':

  init: /etc/init.d/12_dbus.service: unknown field 'before', expected
  one of 'cmd', 'args', 'envs', 'inherit_envs', 'type' in 'service'

The 'before = [13_redbear-sessiond.service]' line was redundant
anyway: 13_redbear-sessiond.service already declares
requires_weak = ['12_dbus.service'], which orders it after dbus.

Fix both redbear-mini.toml and redbear-full.toml.
2026-06-28 16:20:32 +03:00
vasilito 3c6f2bf301 relibc: mirror fresh libc to prefix and redoxer toolchain
After cooking relibc, copy the freshly built libc.a and libc.so to both
the prefix toolchain and the redoxer toolchain (the latter is what
'make live' actually consumes for cross-recipe builds).

Without this, recipes that link against the dynamic libc.so see a stale
copy (no eventfd, no __fseterr, ...) and fail with 'undefined reference'
at link time. 'make prefix' does this sync via its sysroot rule, but
'make r.relibc' alone does not — covering both paths prevents the
first recipe that needs a new symbol from breaking the build.
2026-06-28 16:12:48 +03:00
vasilito 7ac4349fd0 relibc: apply eventfd implementation from P3 patches 2026-06-28 11:31:27 +03:00
vasilito e0e548e7e3 relibc: fix eventfd header - add typedef in trailer 2026-06-28 11:19:01 +03:00
vasilito 82cfd4fb65 relibc: update submodule for eventfd header generation 2026-06-28 10:36:16 +03:00
vasilito 29e005e52f build: fix gettext libtool mismatch, libxau automake, pre-cook non-fatal, redox-drm restore
- gettext: use -I${COOKBOOK_HOST_SYSROOT}/share/aclocal instead of
  /usr/share/aclocal so autoreconf picks up the Redox-patched libtool 2.5.4
  macros instead of the host system's libtool 2.6.1, fixing version mismatch
  at build time
- libxau: add ACLOCAL=true AUTOMAKE=true AUTOHEADER=true to make invocations
  to prevent automake regeneration when host autotools version differs from
  what the source expects
- build-redbear.sh: make pre-cook failures non-fatal (warn only) and run with
  COOKBOOK_OFFLINE=false so packages that need source fetching can succeed
- redox-drm: restore source from git history (was deleted in dc6805430);
  update Cargo.toml version 0.1.0 -> 0.2.4 and dependency constraints to
  match current project version
2026-06-28 10:33:41 +03:00
vasilito 57b225071a build: fix python312 COOKBOOK_TOOLCHAIN, switch userutils to local fork, preflight guards
- recipes/dev/python312/recipe.toml: use COOKBOOK_TOOLCHAIN for
  --with-build-python instead of /tmp/python312, which the build system
  never stages. Add [ -x ] guard for clear failure on missing dev-dep.
- recipes/core/userutils/recipe.toml: switch from upstream git URL to
  local fork (local/sources/userutils/) per the local fork model. The
  upstream source opens /scheme/pty/ptmx which the ptyd scheme does not
  recognize; the local fork opens /scheme/pty correctly and avoids the
  getty PTY panic.
- local/scripts/build-preflight.sh: warn when a recipe build script
  references /tmp/<known-package>/, since the cookbook does not stage
  host dev-deps under /tmp/<name>. Points authors at COOKBOOK_TOOLCHAIN.
- local/scripts/build-redbear.sh: replace 'tail -1 || true' on pre-cook
  failures with proper error capture, last-50-lines tail on failure, and
  exit-1. Verify the pkgar exists after a successful cook.
2026-06-28 10:31:50 +03:00
vasilito 91e3830f4c Remove WIP uutils-tar recipe (superseded by recipes/archives/uutils-tar) 2026-06-28 02:03:39 +03:00
vasilito 8af119d1a9 Remove duplicate redbear-netctl-console recipe (nested inside redbear-netctl) 2026-06-28 00:01:47 +03:00
vasilito e4362bbfad redbear-power: surface tab keys in --help and Controls panel
The tab keys (1-9 jump directly, T cycles next) were
always wired in main.rs but not documented anywhere
visible. Operators could not discover how to switch
between the 9 data tabs (Per-CPU / System / Info /
Motherboard / Battery / Sensors / Network / Storage
/ Process) without reading the source.

Two surfaces now surface the tab keys as the FIRST
entries, ahead of governor / P-state / throttle
controls:

1. Controls panel (visible at the bottom of every
   TUI frame): adds a 'Tabs:' line listing the 9
   direct-jump keys with abbreviated tab names, plus
   a [T] cycle line. Implemented in
   render_controls().

2. --help output (HELP_TEXT constant, shown via
   'redbear-power --help' and the in-TUI [?] help
   overlay): adds a TABS: section at the top of the
   INTERACTIVE CONTROLS block, listing all 9 tabs in
   3-row grid + the [T] cycle key.

The keys themselves are unchanged: '1'-'9' for
direct tab jump, 'T' for cycle. No new keybindings
or behaviors added.

Discovered during interactive smoke-testing on the
Linux host: the binary worked perfectly but tab
navigation was a discoverability hole. Fix-only,
no semantic change.

186/186 tests still pass (the controls panel
render is covered by the existing snapshot tests).
2026-06-21 15:57:31 +03:00
vasilito 1f0c0a01c5 redbear-power: doc v1.44 plan (affinity setter feasibility audit)
Adds §68 (v1.44 plan) and revises §67.7 (v1.43
deferred list) to reflect the v1.43 audit findings.

Key corrections captured in the doc:
  - The Redox kernel ALREADY implements
    sched_setaffinity and sched_getaffinity
    (local/sources/kernel/src/syscall/process.rs:322-382).
    Only the relibc POSIX <sched.h> wrapper is missing.
  - The existing P7-pthread-affinity relibc patch
    provides cpu_set_t, cpuset_to_u64, copy_u64_to_cpuset
    — v1.44 can reuse these instead of duplicating.
  - Kernel pid=0 limitation is documented at
    kernel/src/syscall/process.rs:336-338 as a TODO;
    v1.44's UX is honest about this ('pin redbear-power's
    own TUI to this process's CPU list, not the
    highlighted process's').
  - Per-thread CPU% is REJECTED for v1.44 because the
    Redox proc scheme doesn't expose /proc/<pid>/task/<tid>/stat.
    Same trap as v1.41 read_thread_io. Tracked as a kernel
    follow-up, not a redbear-power feature.
  - disk_history cap is REJECTED for v1.44 because the
    natural bound on block device count (~4-8 typical)
    makes the cap moot. Drive-by include it elsewhere.

Implementation plan documented:
  1. relibc patch P12-sched-setaffinity.patch (~110 LoC,
     reusing P7 helpers)
  2. redbear-power affinity.rs module (~30 minutes)
  3. main.rs key binding (capital A) + PID detail
     popup integration (~1.5 hours)
  4. 5-7 tests (round-trip, pid=0 limitation, parse/format,
     integration against /proc/self/status)
  5. Doc update §69 on what shipped

Effort estimate: ~1 working day, end-to-end. The
relibc patch alone is <3 hours given P7 reuse.

Downstream recipe impact audited (LOW):
  - Mesa and xz both wrap sched_getaffinity in
    defensive probes — they go from ENOSYS to
    'current process mask works' (strict improvement,
    no break).

No code changes — planning-only commit.
2026-06-21 15:27:47 +03:00
vasilito 0098147e5c docs(build-system): add v6.1 addendum for cleanup safety + qfeatures.h fix
Document two critical build-system findings:

C-7.1: Ad-hoc cleanup scripts deleted tracked sources
  - Added local/scripts/cleanup-build.sh (git-aware cleanup)
  - Updated AGENTS.md with safe cleanup procedure

C-7.2: qtdeclarative missing qfeatures.h caused division-by-zero
  - Added cmake --install to properly stage generated headers
  - Added explicit QT_FEATURE_quick_shadereffect/draganddrop flags
  - Added safety-net to regenerate qtquick-config.h if empty
2026-06-21 15:26:24 +03:00
vasilito 6a7abe0b87 feat(build-system): add safe cleanup script and update docs
Add local/scripts/cleanup-build.sh - a git-aware cleanup script that
uses 'git ls-files' to whitelist tracked files before deletion.
Prevents the class of cleanup disasters that deleted local recipe
sources and local fork sources.

Update AGENTS.md with the new safe cleanup procedure.
Update CONSOLE-TO-KDE-DESKTOP-PLAN.md to v5.8 with the qtdeclarative
qfeatures.h fix and the new safe cleanup script.
2026-06-21 15:15:57 +03:00
vasilito 1a9d77761e fix(qtdeclarative): properly generate qtquick-config.h features
The qtquick-config.h file was being generated empty by the cmake
build, causing 'division by zero in #if' errors in downstream
consumers (SDDM, KWin) because QT_CONFIG(quick_shadereffect) and
QT_CONFIG(quick_draganddrop) were undefined.

Two fixes:
1. Explicitly enable QT_FEATURE_quick_shadereffect and
   QT_FEATURE_quick_draganddrop in the cmake configuration.
2. Add a safety net that regenerates qtquick-config.h with the
   required feature definitions if cmake produces an empty file.
2026-06-21 15:12:40 +03:00
vasilito f83a059c25 redbear-power: v1.43 history reclaim LRU
The first item from the v1.42 deferred list: a
configurable LRU cap on the per-PID history maps.
On long uptimes with thousands of short-lived procs
(build servers, CI runners), the maps would grow
without bound, eventually consuming significant
memory. v1.43 caps the maps at 500 PIDs by default
and evicts the LRU entry on overflow.

The cap
  - App::max_history_pids: usize (default 500)
  - 0 = disable (reaper still prunes exited PIDs)
  - Shared across the 3 per-PID maps (io_history,
    cpu_history, rss_history). They are always
    populated in lockstep so a per-PID CPU history
    without the corresponding IO history would be
    a 'ghost' entry that confuses the renderer.
  - disk_history is NOT capped (keyed by disk name,
    natural bound on block device count).

LRU tagging
  - New App::pid_last_seen: BTreeMap<u32, u64>
  - New App::refresh_tick: u64 (incremented on every
    update_io_history call)
  - We use a refresh counter, not Frame::count(),
    because the history update happens during
    refresh (not during render). Frame::count would
    tag currently-visible PIDs rather than
    recently-updated PIDs — a different (and
    incorrect) notion.

Eviction algorithm
  1. Increment refresh_tick
  2. Reap exited PIDs from all 3 maps and
     pid_last_seen
  3. If pid_last_seen.len() > cap: sort by tick
     ascending, take the first overflow entries,
     remove from all 3 maps + pid_last_seen
  4. Continue with the existing pipeline

Cost: O(n log n) per refresh, n bounded by 500.
At 500 PIDs: ~4500 comparisons per refresh,
<100µs. Memory budget: ~28 KB at cap, vs
unbounded growth without the cap (~5.5 MB at
100k PIDs).

Tests
  - 3 new tests (eviction removes oldest, cap=0
    disables, no-op under cap).
  - 186/186 tests pass (was 183 in v1.42).

The improvement plan doc is also updated with §67
covering the v1.43 architecture, the cap policy,
the LRU tagging, the eviction algorithm, the
memory budget, and the v1.44 deferred list.
2026-06-21 14:00:02 +03:00
vasilito 0771fa2ff6 redbear-power: v1.42 CPU affinity
The next item from the v1.41 deferred list: read
/proc/<pid>/status:Cpus_allowed_list and display it as
both a single-char row indicator and a full expanded
list in the PID detail popup. htop parity.

Kernel format
  The kernel emits the list as comma-separated ranges:
    "0-3,5,7-11" means CPUs 0, 1, 2, 3, 5, 7, 8, 9,
    10, 11
  Cpus_allowed_list is the HARD affinity mask (settable
  via sched_setaffinity(2)). v1.42 reads it because it
  matches what an operator sees with 'taskset'.

New functions
  - read_cpu_affinity(pid): parses the kernel string
  - parse_cpu_list(s): public, testable parser
  - format_cpu_list(ids): inverse of parse_cpu_list
  - read_cpu_affinity_for_pid(pid): pub wrapper for the
    PID detail popup

Two display modes
  - Process panel row: '*' (subset), ' ' (all CPUs),
    '?' (unknown). Single char so COMM stays visible.
  - PID detail popup: full range string + expanded
    Vec (truncated to 8 items on large machines).

New field on ProcessInfo
  - cpu_affinity: Option<Vec<u32>>

Robustness
  - Whitespace tolerated
  - Out-of-order or duplicate IDs deduped and sorted
  - Non-numeric chunks silently dropped
  - Reversed ranges (start > end) silently dropped
  - Empty input returns empty Vec (popup distinguishes
    'no data' / None vs 'explicitly empty' / Some(empty))

Tests
  - 13 new tests (11 in process.rs for parse/format/
    read, 1 self-affinity test, 1 missing-pid test).
  - 183/183 tests pass (was 170 in v1.41).

The improvement plan doc is also updated with §66
covering the v1.42 architecture, kernel format, the
two display modes, the parse/format inverse pair, and
the v1.43 deferred list.
2026-06-21 13:38:24 +03:00
vasilito 57a3ea6c9e fix(qtdeclarative): use cmake --install to stage qfeatures.h
The qtdeclarative recipe manually copied include files, which missed
the build-time generated qfeatures.h. Without it, downstream consumers
(SDDM, KWin, etc.) hit 'division by zero in #if' errors in qquickitem.h
because QT_CONFIG(quick_shadereffect) and QT_CONFIG(quick_draganddrop)
were undefined, triggering the deliberate 1/0 preprocessor trap.

Fix: use cmake --install to properly install all files, and add a safety
net that copies qfeatures.h from the build tree if cmake --install
does not place it in the install prefix.
2026-06-21 13:35:00 +03:00
vasilito 34e9ec2a05 redbear-power: v1.41 per-thread IO aggregation
The next item from the v1.40 deferred list: walk
/proc/<pid>/task/*/io for every process and sum
read_bytes and write_bytes across all TIDs. Surfaces
'is one thread of this 32-thread process hammering
disk?' which the process total hides.

Linux kernel attribution quirk
  /proc/<pid>/io:read_bytes is the process total,
  NOT the per-thread sum — the kernel attributes all
  IO to the process even when threads initiate it.
  So the two surfaces can match, diverge, or be
  independently None depending on kernel version and
  permission model. We never compare or subtract them.

New fields on ProcessInfo
  - thread_io_read_kb, thread_io_write_kb (summed bytes)
  - thread_io_read_rate_kbs, thread_io_write_rate_kbs
    (delta-based rate via the same compute_rate_kbs
    helper used for the process-total rates)

New sort modes
  - ThreadIo: read+write total
  - ThreadIoR: read only
  - ThreadIoW: write only
  The cycle reaches all 3 via a back-door arm of next()
  that returns to Rss (not Name) to avoid breaking the
  main loop.

New column in Process panel
  T-IO between the per-thread rate and the MEM column.
  Now 12 columns total. PID detail popup gets a
  [thread_io] section that re-reads the task dir on
  open for a current value.

Tests
  - 6 new tests (3 in process.rs for read_thread_io,
    3 for the sort modes + cycle).
  - 170/170 tests pass (was 164 in v1.40).

The improvement plan doc is also updated with §65
covering the v1.41 architecture, the Linux kernel
attribution quirk, the new fields, the sort cycle
back-door, the cost analysis (~500 reads/sec at
typical desktop loads, ~7500 at 128-thread server
loads — well within budget), and the v1.42
deferred list.
2026-06-21 13:19:20 +03:00
vasilito 2f8e35a88a redbear-power: v1.40 persistent session state
The first item from the v1.39 deferred list: the user's
tab, sort mode, sort direction, tree mode, filter, and
fold set now survive a restart of redbear-power.

Architecture
  - New module session.rs (separate from config.rs which
    is read-only system-wide config).
  - config.rs: behavior config (refresh interval, theme,
    keybindings) — read once at startup, never written.
  - session.rs: mutable per-user runtime state — read at
    startup AND written on every tab change and on quit.

Storage
  - $XDG_CONFIG_HOME/redbear-power/session.toml (preferred)
  - ~/.config/redbear-power/session.toml (fallback)
  - Writes are atomic: temp file + rename(). A crash
    between write and rename leaves the prior session
    intact.

Save hooks
  - Every set_tab() call: tab is the high-signal event
    the user explicitly opted into.
  - On graceful quit (q/Esc): captures the final sort,
    filter, and fold set.

Failure modes
  - load() never errors. Missing file = defaults.
    Corrupt file = defaults + one-line warning.
  - save() never errors. Permission denied = eprintln!
    warning. The next launch reads the prior session
    (or defaults) and starts from there.

Tests
  - 6 new tests in session.rs (round-trip, missing-file,
    malformed-toml, atomic-save, default-state, end-to-end
    via App::save_session()).
  - 164/164 tests pass (was 158 in v1.39).

The improvement plan doc is also updated with §64
covering the v1.40 architecture, storage paths, save
policy, failure modes, and the v1.41 deferred list.
2026-06-21 12:18:13 +03:00
vasilito 5bd371c070 redbear-power: v1.39 cursor preservation + T-IO column + process environ
v1.39 lands three htop/btop parity features plus the
audit-fix discipline introduced in v1.37/v1.38:

1. Cursor preservation across sort
   o and i keypresses no longer reset the cursor to row 0.
   The cursor follows the currently-selected PID through the
   re-sort. Implemented as App::remember_and_restore_cursor()
   which walks the post-filter visible list. Three regression
   tests: follows PID, respects filter, falls back when PID
   exits.

2. Per-thread IO rate (T-IO column)
   New ProcessInfo::io_per_thread_rate_kbs() returns the
   aggregate IO rate divided by num_threads, surfacing
   thread-pool pressure that's hidden in the aggregate. A
   32-thread process at 320 KiB/s is the same as a 1-thread
   process at 10 KiB/s in aggregate, but very different
   in operator-relevant 'IO per worker' terms. Returns None
   when num_threads <= 0 (data error, not '0 KiB/s per
   thread' which would mislead the operator). Three unit
   tests cover the divide, the missing-total case, and the
   zero-threads case.

3. Process environ in PID detail
   /proc/<pid>/environ read as NUL-separated KEY=VALUE
   pairs, sorted by key for stable popup rendering.
   Rendered as the first 8 vars in the PID detail popup
   with a '(N variables)' header. htop F7 parity. Three
   unit tests: parse self environ, missing PID, value
   containing '=' (must split on FIRST '=' only).

The improvement plan doc is also updated with sections
56-63 covering v1.32 (sparklines) through v1.39
(per-thread IO + environ) since the doc previously
stopped at v1.31.

Test count: 158/158 pass (was 149 in v1.38.1).
2026-06-21 12:03:12 +03:00