Summary
Android Dynamic Widgets do not reliably re-render when the system light/dark scheme changes. The reload is triggered every time, but the widget only re-fetches its bundle and re-renders on some toggles. Reproduced on origin/main (24accaf), so this predates #261 and #262.
Environment
Pixel_8_API_35 emulator, example app, AndroidClientDemoWidget pinned, Metro serving the widget bundle (verified with a 200 on the bundle URL).
- Toggled with
adb shell cmd uimode night yes|no, 15 s between toggles, home screen screenshot after each.
Observation
| Toggle |
App state |
Expected scheme |
Observed scheme |
Re-render (metro fetch in logcat) |
| no → yes |
background |
dark |
light |
no |
| yes → no |
background |
light |
light |
yes |
| no → yes |
background |
dark |
light |
no |
| yes → no |
background |
light |
light |
no |
| no → yes |
foreground |
dark |
dark |
yes |
| yes → no |
foreground |
light |
dark |
no |
On every toggle logcat shows VoltraWidgetManager: reloadClientWidgets followed by VoltraWidgetReceiver: Triggered update on registered widget 'AndroidClientDemoWidget' (1 instances), so the configuration callback and the Glance update() call both run. Only two of the six toggles produced a VoltraClientGlanceWidget: [perf] metro fetch line and a changed scheme: / time: row on the widget. Payload-driven widgets were unaffected throughout.
Likely cause
VoltraClientGlanceWidget.provideGlance does the bundle fetch and evaluation, and Content builds the env (including colorScheme) from context.resources.configuration. When Glance already has a live session for the widget, update() recomposes provideContent without re-running provideGlance, and the session's context can still carry the previous configuration, so the env is rebuilt with the stale scheme. Whether a session is alive at the moment of the toggle depends on timing, which matches the intermittent pattern above.
Suggested direction
Force a fresh composition on scheme change rather than relying on update() alone, for example by keying the composition on the night-mode bit (Glance state or a props revision, the way runtime props updates already do via advanceDynamicWidgetPropsRevision), or by reading the scheme from a freshly obtained application configuration instead of the session context.
Found while smoke testing #261 and #262; not introduced by them.
Summary
Android Dynamic Widgets do not reliably re-render when the system light/dark scheme changes. The reload is triggered every time, but the widget only re-fetches its bundle and re-renders on some toggles. Reproduced on
origin/main(24accaf), so this predates #261 and #262.Environment
Pixel_8_API_35emulator, example app,AndroidClientDemoWidgetpinned, Metro serving the widget bundle (verified with a 200 on the bundle URL).adb shell cmd uimode night yes|no, 15 s between toggles, home screen screenshot after each.Observation
metro fetchin logcat)On every toggle logcat shows
VoltraWidgetManager: reloadClientWidgetsfollowed byVoltraWidgetReceiver: Triggered update on registered widget 'AndroidClientDemoWidget' (1 instances), so the configuration callback and the Glanceupdate()call both run. Only two of the six toggles produced aVoltraClientGlanceWidget: [perf] metro fetchline and a changedscheme:/time:row on the widget. Payload-driven widgets were unaffected throughout.Likely cause
VoltraClientGlanceWidget.provideGlancedoes the bundle fetch and evaluation, andContentbuilds the env (includingcolorScheme) fromcontext.resources.configuration. When Glance already has a live session for the widget,update()recomposesprovideContentwithout re-runningprovideGlance, and the session's context can still carry the previous configuration, so the env is rebuilt with the stale scheme. Whether a session is alive at the moment of the toggle depends on timing, which matches the intermittent pattern above.Suggested direction
Force a fresh composition on scheme change rather than relying on
update()alone, for example by keying the composition on the night-mode bit (Glance state or a props revision, the way runtime props updates already do viaadvanceDynamicWidgetPropsRevision), or by reading the scheme from a freshly obtained application configuration instead of the session context.Found while smoke testing #261 and #262; not introduced by them.