Skip to content

Theme system conflates app appearance (Light/Dark) with terminal color scheme — custom Ghostty colors are silently overridden #3523

Description

@austinywang

Problem

The cmux theme picker (Settings > Appearance > Theme: Light / Dark / System) conflates two orthogonal concepts:

  1. App chrome appearance — whether the sidebar, window frame, and UI elements render in light or dark mode (NSApp.appearance)
  2. Terminal color scheme — the Ghostty theme that sets background, foreground, and palette colors inside the terminal

When a user selects "Dark" or "Light", cmux writes theme = light:X,dark:Y to config.ghostty (the managed Ghostty config). This Ghostty theme silently overrides all user-defined terminal colorsbackground, foreground, palette, etc. — in the user's own config file. There is no "Custom" or "None" option to opt out.

Why this is wrong

A user may want:

  • Dark chrome (sidebar/UI) but their own custom terminal colors
  • Light chrome but a dark terminal color scheme
  • Any combination where the app appearance is independent of the terminal palette

There is no way to achieve this today. Selecting any non-System appearance permanently clobbers the user's custom Ghostty color config.

Root cause (architectural)

config.ghostty is cmux's managed Ghostty config, written on every appearance change. The theme picker writes theme = light:X,dark:Y unconditionally, with no escape hatch. The user's config file cannot override this because Ghostty's theme directive has higher specificity for color values.

Correct architecture

These must become two separate, independent controls:

1. App Appearance (Light / Dark / System)

  • Controls NSApp.appearance only
  • Does NOT write any theme = to config.ghostty
  • Does NOT change terminal colors at all

2. Terminal Theme (separate picker)

  • Options: named Ghostty themes (Andromeda, Apple Classic, …) plus a "Custom" option
  • "Custom" = cmux writes nothing to the theme field; user's own Ghostty color config is respected in full
  • When a named theme is selected: cmux writes theme = <name> (unconditional, not light/dark split) OR theme = light:X,dark:Y if the user wants adaptive themes
  • Default: "Custom" (no override)

Migration

  • Existing users who have a theme set keep it
  • New installs default to "Custom" terminal theme + "System" app appearance
  • The managed zone in config.ghostty for theme is only written when the user explicitly picks a named theme

Related

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions