INC-2026-04-04: Investigation

Investigation

Phase 1: Thermal Baseline

paste <(cat /sys/class/thermal/thermal_zone*/type) \
      <(awk '{printf "%.1f°C\n", $1/1000}' /sys/class/thermal/thermal_zone*/temp)
Table 1. Initial readings (18:51 PDT)
Sensor Temperature

x86_pkg_temp (CPU)

86.0°C

acpitz

81.0°C

SEN1/SEN2 (VRM/SSD)

53-54°C

NVIDIA RTX 5090

54°C (idle)

iwlwifi

60°C

Phase 2: Process Analysis

top -b -n1 | awk 'NR>=7 && NR<=12'
Result
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   2140 evanusm+  20   0 2391024  93284  77544 R  96.1   0.1     11,21 waybar
   2084 evanusm+  20   0 1570524 203848 113288 S   4.8   0.3  35:45.76 Hyprland

waybar at 96.1% CPU — single core pinned. 11 minutes 21 seconds of accumulated CPU time.

Phase 3: GPU Verification

nvidia-smi
Result — GPU is innocent
|   0  NVIDIA GeForce RTX 5090     Off |   00000000:01:00.0 Off |                  N/A |
| N/A   54C    P8              7W /   95W |      17MiB /  24463MiB |      0%      Default |

Processes:
|    0   N/A  N/A            2084      G   Hyprland                                  6MiB |

Only Hyprland on GPU at 6 MiB. Firefox and kitty NOT on dGPU (unlike INC-2026-03-27).

Phase 4: Isolation Testing

Systematic elimination to identify root cause:

Test Config CPU Result

Minimal (clock only, minimal CSS)

1 module, no styling

0.0%

Full modules, minimal CSS

All modules, * {font-size:14px}

0.0%

Full modules, full CSS (no animations)

All modules, animations commented

53%

Full modules, full CSS (no transitions)

All modules, transitions + animations off

58%

Full modules, full CSS (no box-shadow)

All modules, box-shadow + animations + transitions off

CSS parse error (broken comments)

Full modules, properly cleaned CSS

Removed box-shadow blocks, fixed syntax, disabled last animation

0.0%

Conclusion: Full modules + minimal CSS = 0%. The CSS itself was the sole cause.

Phase 5: CSS Forensics

The style.css (605 lines, Catppuccin Mocha / Glass Island theme) contained:

Property Count

alpha() function calls

~80+

box-shadow declarations

8 (including multi-line)

border-radius

~20

transition: all

4

Infinite animation:

7 (pulse, glow-pulse, text-flicker, border-glow-cycle, subtle-breathe)

linear-gradient

3

text-shadow

2

Findings

  1. Primary: Multi-line box-shadow with alpha() compositing forced GTK3 into software rendering path for every widget repaint

  2. Contributing: Seven infinite CSS animations triggered constant repaints every frame, each requiring expensive shadow recalculation

  3. Trigger: The degradation was progressive over 1 day 20h uptime — GTK3’s rendering pipeline accumulated overhead until it entered a CPU spin

  4. Correlation: Plugging in AC power likely triggered a battery state class change (.charging), causing a style recalculation cascade on all widgets simultaneously

Root Cause

Technical explanation: GTK3’s CSS engine performs box-shadow rendering in software (CPU), not GPU-accelerated. The waybar theme used 8 box-shadow declarations combined with alpha() transparency compositing and 7 infinite CSS animations. Each animation frame triggered a repaint cycle that required recalculating shadows and alpha blending for every affected widget. Over ~44 hours of uptime, GTK3’s rendering pipeline degraded until the repaint cost exceeded one frame budget, causing a sustained CPU spin at 50-96%.

Why it happened:

  • Immediate cause: GTK3 CSS repaint loop driven by box-shadow + alpha() compositing

  • Contributing factors: 7 infinite CSS animations forcing constant repaints, ~44h uptime without waybar restart

  • Trigger: AC power plug-in caused battery class change (.charging), cascading style recalculation

  • Systemic issues: No awareness that GTK3 CSS box-shadow is CPU-rendered, no performance testing of the theme