Skip to content

Error display surface, theming, and a bug-hunting pass - #15

Merged
dahui merged 13 commits into
mainfrom
feat/error-display-dialog
Jul 29, 2026
Merged

Error display surface, theming, and a bug-hunting pass#15
dahui merged 13 commits into
mainfrom
feat/error-display-dialog

Conversation

@dahui

@dahui dahui commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Error display surface, theming support, and the bug-hunting pass that followed it.
Targets v1.3.0, a minor bump, since it adds capability as well as fixing things.

Requires z13ctl v1.2.1 or newer. The fan-curve floor mirrors a rule the daemon
enforces from that version. Against an older daemon the drawer still works; the
floor just is not drawn.

What this adds

  • An error surface. Every daemon call reported failures only to the journal, so
    a rejected request looked exactly like a button that did nothing — which is how
    the custom-TDP permission failure went unnoticed for weeks (z13ctl#14). One error
    bar now serves all four views in both backends.
  • A themeable error colour, with a palette-matched value for each of the 15
    built-in themes. Existing theme.toml files are unaffected; an omitted key
    inherits the default.
  • A fan-floor-aware curve editor. Above 75 W sustained the daemon rejects any
    point below 80% duty and refuses a fan reset. The editor draws the floor, clamps
    drags to it, and disables Reset Fans with a tooltip pointing at Reset TDP.
  • Advanced-mode auto-detection, so applied power limits the basic slider cannot
    represent are never misreported.

Worth reviewing closely

  • internal/daemonapi.Send* signals "daemon not running" with
    handled=false and a nil error. All thirteen call sites read only err, so
    with the daemon stopped every operation took its success path: Save TDP cleared
    the error bar, logged "custom TDP saved", and left the typed values on screen.
    daemon.Err takes a call's results directly so a site cannot read one and forget
    the other, and its contract test dials a temp XDG_RUNTIME_DIR to pin the api
    convention rather than trusting a doc comment.
  • Gamepad grab orderingshow/hide issued grab and release from separate
    goroutines with no ordering. A grab landing after a hide left every controller
    exclusively grabbed with nothing on screen. SetGrabbed(seq, grab) now drops
    superseded requests, sequenced from the GTK thread.
  • Window.visible is an atomic.Bool — it was read from the gamepad reader's
    goroutine while written on the GTK thread. internal/gui is excluded from
    go test -race, so this class of race cannot be reported here and has to be made
    impossible instead.
  • CSS/Cairo split — the fan curve chart is painted, not styled, so it read
    neither the @z13-* tokens nor the gamescope scaling. Both now come from
    Backend.Scale() and Window.colors.

Testing

Logic moved out of internal/gui, which needs CGO and GTK4 headers and so cannot
be unit tested at all. Ten pure packages now cover TDP and fan rules, daemon result
handling, focus navigation, gamepad auto-repeat, colour conversion, lighting state,
UI scaling, argument parsing, log filtering and toggle debouncing — 96.6% coverage.

Several fixes here were found by writing those tests, including a fan-curve constraint cascade that collapsed points onto the minimum temperature, and a Limits invariant the tests asserted but the code never enforced.

CI is new in this branch: tests, race detector, dependency tidiness, gofmt,
golangci-lint and a full build on every push and PR. Previously nothing ran
automatically.

Verified on hardware

Error bar, fan curve editing including the high-TDP floor, TDP basic/advanced
behaviour, profile switching, and gamepad navigation in both Wayland and gamescope.

@dahui
dahui merged commit 5fcd32e into main Jul 29, 2026
2 checks passed
@dahui
dahui deleted the feat/error-display-dialog branch July 29, 2026 23:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant