Skip to content

feat(viewer): add "Prefer dark mode" setting for web page assets#3050

Merged
vpetersson merged 3 commits into
masterfrom
feat/prefer-dark-mode-setting
Jun 10, 2026
Merged

feat(viewer): add "Prefer dark mode" setting for web page assets#3050
vpetersson merged 3 commits into
masterfrom
feat/prefer-dark-mode-setting

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Issues Fixed

No associated issue. Adds a requested Prefer dark mode setting that instructs the Qt webview to render web page assets in dark mode.

Description

Adds a "Prefer dark mode" toggle to Settings. The dark-mode realization lives in the C++ webview, which is where it belongs; Python only owns the setting and passes the preference down.

  • Webview (src/anthias_webview/src/main.cpp) — new applyDarkModePreference() reads the ANTHIAS_PREFER_DARK_MODE env var and injects --blink-settings=forceDarkModeEnabled=true into QTWEBENGINE_CHROMIUM_FLAGS before QtWebEngine boots its Chromium context. Using the Blink switch keeps one code path across Qt5 (Pi 1-4) and Qt6 (Pi 5/x86) with no version macro — it sets the same flag QWebEngineSettings::ForceDarkMode toggles on Qt 6.7+. Dark-aware sites use their own dark theme (prefers-color-scheme: dark); the rest are auto-darkened.
  • Viewer_build_webview_env() exports the env var on every board; a toggle triggers a webview respawn (reusing the existing rotation-bounce handoff) so it takes effect immediately.
  • Server — wired through the settings page, page_context, the form POST, and the v2 device_settings API (GET + PATCH).

Validated on a Pi 5 testbed (full integrated stack):

Setting AnthiasViewer env Chromium renderers with --blink-settings=forceDarkModeEnabled=true
on ANTHIAS_PREFER_DARK_MODE=1 2 (type=renderer)
off unset 0 (renderer still present, just not dark)

The webview C++ change was also compile-checked against the real Qt6 WebEngine headers (g++ -Wall -Wextra, clean).

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices. (Pi 5 testbed: deployed the full arm64 viewer image and verified the setting→env→Chromium flag chain on/off.)
  • I have tested my changes for x86 devices. (x86 testbed was unavailable; the webview was compile-checked on native amd64 but not runtime-tested on an x86 device.)
  • I added a documentation for the changes I have made (when necessary). (The setting carries an inline UI hint; no separate docs needed.)

🤖 Generated with Claude Code

Adds a "Prefer dark mode" toggle in Settings that instructs the Qt
webview to render web page assets dark. The C++ webview owns the
realization: applyDarkModePreference() reads ANTHIAS_PREFER_DARK_MODE
and injects --blink-settings=forceDarkModeEnabled=true into Chromium
before QtWebEngine inits, working uniformly across Qt5 (Pi 1-4) and
Qt6 (Pi 5/x86) without a version macro.

Python owns the setting: the viewer exports the env var per board in
_build_webview_env() and respawns the webview when the operator toggles
the setting (reusing the rotation-bounce handoff). Wired through the
settings page, page_context, the form POST, and the v2 device-settings
API.

Validated on a Pi 5 testbed: with the setting on, AnthiasViewer's env
carries ANTHIAS_PREFER_DARK_MODE=1 and the QtWebEngine renderer
processes run with --blink-settings=forceDarkModeEnabled=true; with it
off, neither is present.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner June 10, 2026 15:02
@vpetersson vpetersson self-assigned this Jun 10, 2026
@vpetersson vpetersson requested a review from Copilot June 10, 2026 15:02
@sonarqubecloud

Copy link
Copy Markdown

PIL's getdata() is untyped, so sum(list(...)) was Any and the
-> float return tripped mypy's no-any-return. Annotate the list as
list[int].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an operator-facing “Prefer dark mode” setting that flows from the server settings UI/API → viewer env → QtWebEngine/Chromium startup flags so web-page assets can render in dark mode.

Changes:

  • Add prefer_dark_mode to server defaults, settings page POST handling, page context, and v2 device_settings API (GET/PATCH + serializers).
  • Viewer exports ANTHIAS_PREFER_DARK_MODE when enabled and triggers a webview respawn on live toggles (reusing the existing bounce mechanism).
  • Webview C++ reads ANTHIAS_PREFER_DARK_MODE early and injects --blink-settings=forceDarkModeEnabled=true; adds tests for viewer env behavior and a Chromium-level integration check.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_webview_dark_mode.py New Playwright/Pillow integration test asserting Chromium force-dark behavior via screenshot luminance.
tests/test_viewer.py Adds unit coverage for viewer env export/removal and reload bounce behavior on dark-mode toggles.
tests/test_settings.py Extends settings parsing/default tests for prefer_dark_mode.
src/anthias_webview/src/main.cpp Adds applyDarkModePreference() to inject the Blink force-dark switch at startup.
src/anthias_viewer/init.py Adds prefer_dark_mode env plumbing + reload-time respawn logic.
src/anthias_server/settings.py Adds prefer_dark_mode default setting.
src/anthias_server/app/views.py Wires prefer_dark_mode through settings form save handling.
src/anthias_server/app/templates/settings.html Adds the “Prefer dark mode” toggle to the settings UI.
src/anthias_server/app/page_context.py Includes prefer_dark_mode in settings page context.
src/anthias_server/api/views/v2.py Includes prefer_dark_mode in v2 device settings GET and PATCH.
src/anthias_server/api/tests/test_v2_endpoints.py Updates v2 endpoint tests to expect/validate prefer_dark_mode.
src/anthias_server/api/serializers/v2.py Adds prefer_dark_mode to v2 settings serializers (read + patch).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/anthias_webview/src/main.cpp
Comment thread tests/test_webview_dark_mode.py Outdated
- main.cpp: merge forceDarkModeEnabled into an existing
  --blink-settings switch instead of appending a duplicate (Chromium
  keeps only the last occurrence, so a second switch would silently
  drop any Blink settings already set); no-op if already requested.
- test_webview_dark_mode: launch via the suite's browser_type /
  browser_type_launch_args fixtures so the conftest --no-sandbox
  override (and any future launch config) is inherited rather than
  hardcoded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@vpetersson vpetersson merged commit d323bf1 into master Jun 10, 2026
9 checks passed
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.

2 participants