[osd].enabled and dismiss_ms are validated but never read — OSDs always run with a hardcoded 2000ms #14

Closed
opened 2026-09-05 01:37:16 +08:00 by Breadway · 1 comment
Owner

What's broken

Same class of bug as the [panel].sections issue (companion issue, same root cause). docs/shell-themes.md documents [osd]:

enabled — which OSDs are active... dismiss_ms — how long a shown OSD lingers... Changing enabled forces a restart (the watcher threads start at launch). dismiss_ms applies to the next OSD.

bread-theme's resolve_osd() (bread-ecosystem/bread-theme/src/shell/manifest.rs:855) validates enabled against OSD_KINDS and dismiss_ms (must be ≥ 1), landing on ShellTheme::osd().

ShellTheme::osd() is never called anywhere in breadbar (zero matches outside bread-theme/src):

  • osd::spawn() (src/osd.rs:85) unconditionally spawns both volume_watcher and brightness_watcher threads — [osd].enabled has no effect; you cannot disable either OSD kind via theme.toml.
  • The dismiss delay is hardcoded: gtk4::glib::timeout_future(Duration::from_millis(2000)).await at src/osd.rs:271. [osd].dismiss_ms is parsed and validated but never substituted in — it happens to match the schema default (2000), which is presumably why this has gone unnoticed.

Impact

Same as the panel issue: theme.toml can declare [osd] enabled = ["volume"] dismiss_ms = 5000, bread-theme diagnose passes, and breadbar's behavior is byte-identical to not setting it at all.

Fix

  • Gate volume_watcher/brightness_watcher spawn in osd::spawn() on theme::shell_theme().osd().enabled.
  • Replace the hardcoded 2000 at src/osd.rs:271 with theme::shell_theme().osd().dismiss_ms.
  • dismiss_ms is documented as live ("applies to the next OSD") so no restart wiring needed there; enabled needs the same restart-detection breadbar already has for other structural changes (see the sibling panel.sections issue for needs_restart()).
## What's broken Same class of bug as the `[panel].sections` issue (companion issue, same root cause). `docs/shell-themes.md` documents `[osd]`: > `enabled` — which OSDs are active... `dismiss_ms` — how long a shown OSD lingers... **Changing `enabled` forces a restart** (the watcher threads start at launch). `dismiss_ms` applies to the next OSD. `bread-theme`'s `resolve_osd()` (bread-ecosystem/bread-theme/src/shell/manifest.rs:855) validates `enabled` against `OSD_KINDS` and `dismiss_ms` (must be ≥ 1), landing on `ShellTheme::osd()`. `ShellTheme::osd()` is **never called anywhere in breadbar** (zero matches outside `bread-theme/src`): - `osd::spawn()` (`src/osd.rs:85`) unconditionally spawns both `volume_watcher` and `brightness_watcher` threads — `[osd].enabled` has no effect; you cannot disable either OSD kind via theme.toml. - The dismiss delay is hardcoded: `gtk4::glib::timeout_future(Duration::from_millis(2000)).await` at `src/osd.rs:271`. `[osd].dismiss_ms` is parsed and validated but never substituted in — it happens to match the schema default (2000), which is presumably why this has gone unnoticed. ## Impact Same as the panel issue: `theme.toml` can declare `[osd] enabled = ["volume"] dismiss_ms = 5000`, `bread-theme diagnose` passes, and breadbar's behavior is byte-identical to not setting it at all. ## Fix - Gate `volume_watcher`/`brightness_watcher` spawn in `osd::spawn()` on `theme::shell_theme().osd().enabled`. - Replace the hardcoded `2000` at `src/osd.rs:271` with `theme::shell_theme().osd().dismiss_ms`. - `dismiss_ms` is documented as live ("applies to the next OSD") so no restart wiring needed there; `enabled` needs the same restart-detection breadbar already has for other structural changes (see the sibling panel.sections issue for `needs_restart()`).
Author
Owner

Same false alarm as BAR-13 — stale local clone. Also fixed by PR #12 (bd3d5b4, merged 2026-09-04): osd::spawn now takes enabled kinds gating the watcher threads, and dismiss_ms replaces the hardcoded 2000ms constant. Verified against origin/main (083ae51). Closing.

Same false alarm as BAR-13 — stale local clone. Also fixed by PR #12 (`bd3d5b4`, merged 2026-09-04): `osd::spawn` now takes enabled kinds gating the watcher threads, and `dismiss_ms` replaces the hardcoded 2000ms constant. Verified against `origin/main` (083ae51). Closing.
Sign in to join this conversation.
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
Breadway/breadbar#14
No description provided.