fix: peak banner color, popup positioning, window icon, timedelta days #6

Merged
bjoern merged 1 commit from fix/ui-polish into main 2026-06-28 19:38:50 +02:00
Member

UI polish: 4 fixes

1. Peak banner background color (green → correct blue/amber)

The stylesheet used hex+alpha suffix (#3b82f61a), which Qt's CSS parser doesn't support — it was falling back to a default green. Switched to proper rgba() notation:

  • Peak: rgba(245, 158, 11, 0.2) (amber tint)
  • Off-peak: rgba(59, 130, 246, 0.15) (blue tint)

2. Popup positioned near tray (was center-screen)

On Wayland, tray icon clicks arrive via D-Bus (StatusNotifierItem), not as mouse events. So QCursor.pos() returns a stale position at screen center. Now uses self._tray.geometry() to get the actual tray icon position as the anchor, with a fallback to bottom-right corner if the geometry isn't available.

3. Window icon in taskbar

UsagePanel and QApplication now both call setWindowIcon(), so the taskbar shows the Z icon instead of a generic Wayland/Qt placeholder.

4. Timedelta shows days

_format_timedelta now extracts days: weekly reset shows as 6d 16h instead of 160h. Drops zero-value components but always shows at least one unit.

49 tests still passing.

## UI polish: 4 fixes ### 1. Peak banner background color (green → correct blue/amber) The stylesheet used hex+alpha suffix (`#3b82f61a`), which Qt's CSS parser doesn't support — it was falling back to a default green. Switched to proper `rgba()` notation: - Peak: `rgba(245, 158, 11, 0.2)` (amber tint) - Off-peak: `rgba(59, 130, 246, 0.15)` (blue tint) ### 2. Popup positioned near tray (was center-screen) On Wayland, tray icon clicks arrive via D-Bus (StatusNotifierItem), not as mouse events. So `QCursor.pos()` returns a stale position at screen center. Now uses `self._tray.geometry()` to get the actual tray icon position as the anchor, with a fallback to bottom-right corner if the geometry isn't available. ### 3. Window icon in taskbar `UsagePanel` and `QApplication` now both call `setWindowIcon()`, so the taskbar shows the Z icon instead of a generic Wayland/Qt placeholder. ### 4. Timedelta shows days `_format_timedelta` now extracts days: weekly reset shows as `6d 16h` instead of `160h`. Drops zero-value components but always shows at least one unit. 49 tests still passing.
fix: peak banner readability, popup positioning, window icon, timedelta
All checks were successful
CI / test (pull_request) Successful in 20s
49cab160e4
1. Peak banner background color: use rgba() instead of hex+alpha suffix.
   The old format (#3b82f61a) was misinterpreted by Qt's stylesheet
   parser, resulting in a green background. Now uses proper rgba().

2. Popup positioned near tray icon via tray.geometry() instead of
   QCursor.pos(). On Wayland, tray clicks arrive via D-Bus, so
   QCursor.pos() returns a stale/center-screen position. Now uses
   the tray icon's own geometry as the anchor point, with fallback
   to bottom-right corner.

3. Window icon set on both QApplication and UsagePanel, so the
   taskbar shows the Z icon instead of a generic placeholder.

4. _format_timedelta now shows days: '6d 16h 0m' instead of '160h 0m'.
   Drops zero-value components except always shows at least one.
Author
Member

🤖 Hermes automated review: no blocking issues found

Reviewed the full diff (1 file, +34/−13) for head 49cab160 against base cca3c916. This is a clean, well-reasoned set of UI fixes. All four changes are correct:

  • Peak banner color (main.py:406,416): The rgba() values correctly correspond to the existing hex constants — rgba(245, 158, 11, 0.2) = COLOR_WARNING (#f59e0b) and rgba(59, 130, 246, 0.15) = COLOR_NORMAL (#3b82f6). Qt's CSS parser indeed doesn't support 8-digit hex+alpha, so this is the right fix.
  • Popup positioning (main.py:551-576): Using self._tray.geometry() as the anchor is the correct API for QSystemTrayIcon. The fallback chain (tray geo → cursor → bottom-right of primary screen) is sound, and QPoint/QRect are properly imported (line 11). Screen-bounds clamping is preserved.
  • Window icon (main.py:212,660): _icon_for_state exists (line 97); both calls are valid.
  • _format_timedelta (main.py:439-452): Traced edge cases — 0s"0m", 1d exact→"1d", 23h"23h", 1d 1h"1d 1h". The "always shows at least one unit" guarantee holds (the or not parts guard). Correct.

🟡 Minor (non-blocking)

  • main.py:406,416 — rgba values are now magic numbers that duplicate COLOR_WARNING/COLOR_NORMAL. If those hex constants change, the rgba literals won't track. A brief comment (e.g. # matches COLOR_WARNING) would help future maintainers. Not worth blocking — Qt stylesheets don't cleanly support interpolating constants into rgba().
  • main.py:440 — docstring examples are slightly imprecise: """Format a timedelta as 'Xd Yh Zm' or 'Yh Zm' or 'Zm'.""" lists three combined forms, but the code drops individual zero components, so "1d 1m" (hours=0 skipped) is also possible. Cosmetic only.

Verification

  • CI/CD: A Forgejo Actions workflow (.forgejo/workflows/ci.yml) exists for pull_request, but no status/coverage comment has appeared yet for head 49cab160 (PR opened ~minutes ago). Ran locally: pytest -q49 passed in 0.32s (.venv with PySide6 deps already present). No regressions.

Note: this is a PR conversation comment — not a formal Forgejo review approval (the MCP integration cannot create approval states or inline diff comments).


Automated daily review. I never merge PRs.

## 🤖 Hermes automated review: no blocking issues found Reviewed the full diff (1 file, +34/−13) for head `49cab160` against base `cca3c916`. This is a clean, well-reasoned set of UI fixes. All four changes are correct: - **Peak banner color** (`main.py:406,416`): The `rgba()` values correctly correspond to the existing hex constants — `rgba(245, 158, 11, 0.2)` = `COLOR_WARNING` (`#f59e0b`) and `rgba(59, 130, 246, 0.15)` = `COLOR_NORMAL` (`#3b82f6`). Qt's CSS parser indeed doesn't support 8-digit hex+alpha, so this is the right fix. - **Popup positioning** (`main.py:551-576`): Using `self._tray.geometry()` as the anchor is the correct API for `QSystemTrayIcon`. The fallback chain (tray geo → cursor → bottom-right of primary screen) is sound, and `QPoint`/`QRect` are properly imported (line 11). Screen-bounds clamping is preserved. - **Window icon** (`main.py:212,660`): `_icon_for_state` exists (line 97); both calls are valid. - **`_format_timedelta`** (`main.py:439-452`): Traced edge cases — `0s`→`"0m"`, `1d` exact→`"1d"`, `23h`→`"23h"`, `1d 1h`→`"1d 1h"`. The "always shows at least one unit" guarantee holds (the `or not parts` guard). Correct. ### 🟡 Minor (non-blocking) - **`main.py:406,416` — rgba values are now magic numbers** that duplicate `COLOR_WARNING`/`COLOR_NORMAL`. If those hex constants change, the rgba literals won't track. A brief comment (e.g. `# matches COLOR_WARNING`) would help future maintainers. Not worth blocking — Qt stylesheets don't cleanly support interpolating constants into `rgba()`. - **`main.py:440` — docstring examples are slightly imprecise**: `"""Format a timedelta as 'Xd Yh Zm' or 'Yh Zm' or 'Zm'."""` lists three combined forms, but the code drops *individual* zero components, so `"1d 1m"` (hours=0 skipped) is also possible. Cosmetic only. ### ✅ Verification - **CI/CD:** A Forgejo Actions workflow (`.forgejo/workflows/ci.yml`) exists for `pull_request`, but no status/coverage comment has appeared yet for head `49cab160` (PR opened ~minutes ago). **Ran locally:** `pytest -q` → **49 passed in 0.32s** (`.venv` with PySide6 deps already present). No regressions. *Note: this is a PR conversation comment — not a formal Forgejo review approval (the MCP integration cannot create approval states or inline diff comments).* --- *Automated daily review. I never merge PRs.*
bjoern merged commit d23356096e into main 2026-06-28 19:38:50 +02:00
bjoern deleted branch fix/ui-polish 2026-06-28 19:38:50 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/zai-tray-checker!6
No description provided.