Files
cthulhu/docs/superpowers/specs/2026-04-05-sounds-tab-design.md
2026-04-05 20:48:41 -04:00

6.8 KiB

Sounds Tab Design

Date: 2026-04-05

Context

Cthulhu currently stores several non-speech sound settings in the general settings file, but the preferences dialog does not present them coherently:

  • The General tab contains an inline Sound section for backend, theme, and role-sound presentation.
  • The progress-bar beep checkbox lives in the General tab's progress-bar section.
  • soundVolume exists in settings and the user's active profile, but there is no UI control for it.
  • enableSound, playSoundForRole, playSoundForState, playSoundForPositionInSet, and playSoundForValue exist as persisted settings but are not currently exposed in the dialog.
  • progressBarBeepInterval exists in runtime defaults but is not part of the normal persisted general-settings key list.

The result is that sound-related behavior is split across the dialog and some active settings cannot be inspected or changed from the UI.

Goals

  • Add a dedicated Sounds preferences tab.
  • Move currently exposed sound-related controls out of General and into Sounds.
  • Move the progress-bar beep option into Sounds while leaving the rest of the progress-bar section in General.
  • Expose currently hidden sound-related settings in the UI.
  • Add a UI control for soundVolume.
  • Expose and persist progressBarBeepInterval.
  • Preserve the existing settings model and save format.
  • Avoid clobbering unrelated settings when saving preferences.

Non-Goals

  • No refactor of the broader preferences architecture.
  • No changes to sound playback implementation outside what is needed to load and save settings correctly.
  • No new settings schema beyond persisting the existing hidden progressBarBeepInterval.
  • No dynamic enable/disable logic for sound controls in this pass.

Design Summary

Add a new notebook page labeled Sounds and make it the single home for non-speech sound configuration. Remove the inline Sound frame from General. Keep the existing progress-bar speech/braille controls and shared progress-bar behavior controls in General, but move beep-specific controls into Sounds.

The new tab will use existing settings keys wherever possible and will save through the existing prefsDict and settings-manager flow.

Sounds Tab Layout

The Sounds tab will contain three sections.

Output

  • enableSound checkbox
  • soundVolume slider
  • soundSink combo box

soundVolume should be represented by a native GtkScale and persisted back to the existing floating-point soundVolume setting. The control should initialize from prefsDict.get("soundVolume", settings.soundVolume).

For this implementation, the slider should match the stored setting directly rather than introducing a new percentage representation. That keeps the implementation small and avoids conversion-only complexity in a settings path that already exists.

Presentation

  • soundTheme combo box
  • roleSoundPresentation combo box
  • playSoundForRole checkbox
  • playSoundForState checkbox
  • playSoundForPositionInSet checkbox
  • playSoundForValue checkbox

These controls will expose already-existing settings and use the same prefsDict update pattern already used by the current dialog.

Alerts

  • beepProgressBarUpdates checkbox
  • progressBarBeepInterval spin button

This section controls only beep-based progress-bar alerts. The label should make it clear that the interval is beep-specific, not the general progress-bar announcement interval.

General Tab Changes

Keep these controls in General:

  • speakProgressBarUpdates
  • brailleProgressBarUpdates
  • progressBarUpdateInterval
  • progressBarVerbosity
  • ignoreStatusBarProgressBars

Remove these from General:

  • the inline Sound frame
  • beepProgressBarUpdates

This preserves the current organization for general progress-bar announcement behavior while moving sound-only concerns into the new tab.

Settings and Persistence

Existing Keys Reused

The new UI will continue to use the existing settings keys:

  • enableSound
  • soundVolume
  • soundSink
  • soundTheme
  • roleSoundPresentation
  • playSoundForRole
  • playSoundForState
  • playSoundForPositionInSet
  • playSoundForValue
  • beepProgressBarUpdates

Persisted Hidden Key

Add progressBarBeepInterval to the persisted general-settings key list so it round-trips through:

  • defaults in settings.py
  • settings-manager general settings
  • TOML backend save/load
  • prefsDict in the preferences dialog

This avoids the current mismatch where beep interval exists as a runtime default but is not part of the normal persisted general-settings path.

Save Behavior

The implementation should continue to update individual keys in prefsDict and then rely on the existing general-settings save flow. No bulk replacement of the whole settings structure should be introduced.

This is specifically intended to avoid accidental overwrites of unrelated settings already present in user-settings.toml.

Default Values

  • Keep progressBarUpdateInterval = 10 as the default for speech and braille progress-bar updates.
  • Keep progressBarBeepInterval = 0 as the default for beep-based progress-bar updates.
  • Keep soundVolume = 0.5 as the existing default unless the user explicitly changes it.

The new UI should reflect these values accurately on load.

Accessibility

Use native GTK controls and follow the existing preferences-dialog patterns:

  • every label must be associated with its control via mnemonic_widget
  • checkboxes should use the existing checkButtonToggled convention when possible
  • combo boxes should keep proper label-for / labelled-by relationships
  • no custom-drawn controls
  • no keyboard traps

The new tab should be fully reachable with standard tab navigation.

Implementation Notes

Expected files to change:

  • src/cthulhu/cthulhu-setup.ui
  • src/cthulhu/cthulhu_gui_prefs.py
  • src/cthulhu/settings.py

Implementation should:

  • add the new notebook page and move or recreate the relevant widgets there
  • initialize and save the new sound controls using existing dialog patterns
  • add explicit handling for soundVolume
  • add explicit handling for progressBarBeepInterval
  • keep all unrelated preference behavior unchanged

Verification

The implementation should be considered complete only after all of the following are checked:

  1. The preferences dialog opens and the new Sounds tab is present.
  2. Existing sound settings load into the correct controls.
  3. Changing sound settings updates prefsDict without breaking unrelated settings.
  4. Saving preferences preserves unrelated keys in user-settings.toml.
  5. progressBarBeepInterval is written and reloaded correctly.
  6. The General tab still handles speech/braille progress-bar settings correctly.
  7. Touched Python files pass compile checks.
  8. Manual verification confirms keyboard navigation and label association remain intact.