Skip to content

a11y: high-contrast toggle can produce split theme state (dual writer) #1346

@modelmiser

Description

@modelmiser

Both cosmic-applet-a11y (app.rs:182-228) and cosmic-settings accessibility page (mod.rs:350-396) write theme config files independently when toggling high contrast. The code is identical in both — a spawned thread calls set_hc(true) then set_hc(false) (dark theme, then light theme), writing ThemeBuilder and CosmicTheme entries sequentially.

Problem

  1. No coordination between writers. If the user toggles high contrast from the applet while the settings page is open (or vice versa), both threads write the same files concurrently with no file locking or transaction.

  2. Non-atomic sequential writes. Each toggle writes dark theme first, then light theme. A crash or concurrent write between the two steps leaves dark in high-contrast mode but light in normal mode (or vice versa).

  3. Optimistic UI update. Both the applet (line 180) and the settings page (line 348) set self.high_contrast = Some(enabled) before the write thread runs. If the write fails, the UI shows high-contrast enabled but the theme files don't match.

Expected behavior

Toggling high contrast from either the applet or settings should always produce a consistent theme state — both dark and light variants either in high-contrast or not, regardless of timing or concurrent toggles.

The dual-writer pattern creates a race window: concurrent writes without coordination + sequential dark-then-light per writer means interleaving can leave one variant switched and the other not. (Identified from code review; the race window is narrow but architecturally present.)

Related

#1179 — the applet doesn't update its toggle when settings changes high contrast. Same root cause (two independent writers with no coordination), different symptom (state sync vs. concurrent write corruption). A single-writer fix would address both.

Possible approaches

  • Single writer: only one of the two should write, the other should trigger it via a shared mechanism (D-Bus, cosmic-config, or Wayland protocol)
  • Atomic writes: write both theme variants in a single transaction (cosmic-config would need to support this)
  • File locking: advisory lock on the theme config directory during writes

Not proposing a specific fix — this is a design decision for the maintainers.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions