Skip to content

feat: add user-selectable color theme (system, light, dark)#2260

Merged
wkentaro merged 3 commits into
mainfrom
feat/color-theme
Jun 28, 2026
Merged

feat: add user-selectable color theme (system, light, dark)#2260
wkentaro merged 3 commits into
mainfrom
feat/color-theme

Conversation

@wkentaro

Copy link
Copy Markdown
Owner

Summary

  • Adds a Color theme setting (System default / Light / Dark) at the top of Settings → General. The default is System default, which follows the OS appearance live.
  • Applies the theme via QStyleHints.setColorScheme, letting the pinned Fusion style generate the palette; removes the previous unconditional force-light override in __main__.py.
  • Makes the 26 monochrome toolbar icons palette-aware: authored with fill="currentColor" and tinted to the active palette text color by a QIconEngine at paint time (HiDPI-correct). The 5 semantic accent icons (blue folders/save, red trash/file-x) stay fixed.
  • Re-themes the running app on colorSchemeChanged (both a settings change and a live OS switch): re-tints icons, re-resolves palette-referencing stylesheets, repaints. Also moves hardcoded chrome to the palette (#FFFFCC AI-button highlight, black canvas crosshair).

Why

labelme previously forced a light palette because dark mode produced invisible icons (most toolbar glyphs were a fixed dark gray). Qt 6.8's setColorScheme lets the native style produce both palettes with no extra stylesheet, so the remaining work is making icons follow the palette, solved with the template-image pattern (one monochrome source, tinted at render). This bumps the PySide6 floor to >=6.8. Alternatives considered are recorded in docs/adr/0005-color-theme.md.

Test plan

  • tests added: tests/unit/utils/qt_test.py (engine tints to palette; monochrome re-tints, accent stays fixed) and tests/unit/_config/_schema_test.py (enum choice labels)
  • uv run pytest — 692 passed
  • uv run ruff check and uv run ty check — clean
  • manual: switched System/Light/Dark live (no restart) and on an OS appearance flip; verified toolbars, icons, docks, crosshair, and the settings dialog all re-theme on screen

@wkentaro wkentaro self-assigned this Jun 28, 2026
@wkentaro wkentaro force-pushed the feat/color-theme branch 3 times, most recently from 342875e to f313e60 Compare June 28, 2026 09:53
@wkentaro wkentaro added this to the v7.0.0 milestone Jun 28, 2026
@wkentaro

Copy link
Copy Markdown
Owner Author

This was generated by AI during PR processing.

Verdict: recommend-merge

Full finalize tick:

  • Rebase: skipped. main gained 0 commits since the merge-base; branch is current, merge state CLEAN/MERGEABLE.

  • Review gate (report-only /code-review, high effort): no reachable correctness bug. Three low-severity items only (none blocking):

    1. _utils/qt.py scheme_by_theme is Final but snake_case; sibling code (BG_ALPHA, _ICONS_DIR) uses Final+UPPER_CASE. Cosmetic.
    2. _config/__init__.py _validate_config_item validates validate_label/shape_color against allowed values but not color_theme; a typo'd value silently falls back to system instead of raising. apply_color_theme handles it gracefully, so no crash, but it's inconsistent with the two sibling enum keys.
    3. _TintedSvgIconEngine.cacheKey() hashes only the Normal-mode tint. Latent only: a palette change touching the Disabled group without Normal could serve a stale disabled-icon color. The actual feature (setColorScheme) always changes both groups together and _retheme clears QPixmapCache, so the theme picker never triggers this.

    These are nits below the /review-fix escalation bar, so the full reviewer loop and a CI-retriggering force-push were skipped. Left for your discretion rather than filed as tracker issues.

  • Recommit: no-op. History is already 3 clean logical commits (refactor icons → feat → docs ADR), in correct order.

  • Verify: offscreen smoke passed: apply_color_theme applies system/light/dark (and falls back gracefully on a bad value), and new_icon renders a non-null tinted SVG pixmap.

  • CI: all checks green (lint + tests on ubuntu/macos/windows × 3.11/3.14, cla). No push this tick, so existing green is authoritative.

@wkentaro wkentaro added the recommend-merge pr: Agent finalized and endorses it: review and merge label Jun 28, 2026
@wkentaro wkentaro merged commit f64a9c3 into main Jun 28, 2026
8 checks passed
@wkentaro wkentaro deleted the feat/color-theme branch June 28, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

recommend-merge pr: Agent finalized and endorses it: review and merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant