Skip to content

feat(ui): Transparent Background#246

Draft
m4r1vs wants to merge 2 commits intomodem-dev:mainfrom
m4r1vs:transparent-bg
Draft

feat(ui): Transparent Background#246
m4r1vs wants to merge 2 commits intomodem-dev:mainfrom
m4r1vs:transparent-bg

Conversation

@m4r1vs
Copy link
Copy Markdown

@m4r1vs m4r1vs commented May 8, 2026

Screenshot 2026-05-08 at 02 31 56

Currently depends on #241 but it's not difficult to separate if it's not getting merged.

closes #245

@m4r1vs m4r1vs force-pushed the transparent-bg branch from de96c59 to ce03fd6 Compare May 8, 2026 00:33
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 8, 2026

Greptile Summary

This PR adds transparent background support and automatic light/dark theme switching based on system preferences. It introduces transparent_bg, theme_light, and theme_dark config options, a macOS defaults read system-theme detector used when stdin is redirected, and a "Follow system" entry in the theme menu.

  • New transparentBg state in App.tsx strips background/panel colors from the active theme at render time, but the useState fallback is ?? true while every other default in the codebase is false, so any code path that omits initialTransparentBg will start in transparent mode unintentionally.
  • blendHex now accepts undefined for the background color and silently falls back to #000000; when transparent mode is active on a light terminal this will produce visually incorrect blended colors.
  • resolveTheme(\"auto\", null) resolves to the dark theme because null !== \"light\", which may surprise callers in contexts where the theme mode is unknown rather than explicitly dark.

Confidence Score: 3/5

The transparent-bg default is inverted in App.tsx, causing the UI to start in transparent mode in any bootstrap path that leaves the field unset.

The inverted ?? true fallback in App.tsx is the opposite of every other default in the codebase and will silently activate transparent mode for any caller that omits initialTransparentBg. The blendHex black-fallback and the resolveTheme("auto", null) dark-fallback are lower-impact but represent additional correctness gaps.

src/ui/App.tsx (inverted default), src/ui/lib/color.ts (black fallback in blendHex), src/ui/themes.ts (null themeMode resolution)

Important Files Changed

Filename Overview
src/ui/App.tsx Adds transparent background support, auto theme switching, and system theme-mode tracking — contains inverted transparentBg default (?? true instead of ?? false).
src/ui/lib/color.ts Accepts undefined bg in blendHex but falls back to #000000, which produces incorrect blended colors when transparent mode is active on light terminals.
src/ui/themes.ts Adds "auto" theme resolution and makes background/panel color fields optional for transparent mode; resolveTheme("auto", null) silently falls through to dark theme.
src/core/config.ts Adds themeLight, themeDark, and transparentBg config fields with consistent defaults and merging logic.
src/core/terminal.ts Adds detectSystemThemeMode() using macOS defaults read to determine light/dark preference when stdin is redirected.
src/core/loaders.ts Propagates new theme and transparency bootstrap fields; correctly defaults initialTransparentBg to false.
src/ui/lib/appMenus.ts Adds "Follow system" menu entry with toggle logic; both themeId and activeThemeId are threaded through to support auto vs. resolved display.
src/core/types.ts Extends CommonOptions, PersistedViewPreferences, and AppBootstrap with new transparent-bg and light/dark theme fields.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User Config / CLI flags] -->|themeLight, themeDark, transparentBg| B[config.ts mergeOptions]
    B --> C[loadAppBootstrap]
    C -->|initialThemeMode| D{usesPipedPatchInput?}
    D -->|yes| E[detectSystemThemeMode\nmacOS only]
    D -->|no| F[renderer.themeMode\nfrom terminal]
    E --> G[App.tsx useState]
    F --> G
    G --> H{themeId === 'auto'?}
    H -->|yes| I[resolveTheme with\nsystemThemeMode +\nthemeLight/themeDark]
    H -->|no| J[resolveTheme with\nexplicit themeId]
    I --> K{transparentBg?}
    J --> K
    K -->|true| L[Strip background/panel\nfields from theme]
    K -->|false| M[Use theme as-is]
    L --> N[Render UI]
    M --> N
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
src/ui/App.tsx:122
**Transparent-bg default is inverted vs. every other layer**

The `useState` fallback here uses `?? true`, but every other definition of this option — `DEFAULT_VIEW_PREFERENCES.transparentBg`, the `config.ts` merge/resolution logic, `loadAppBootstrap`'s `input.options.transparentBg ?? false`, and the README example — all default to `false`. Any code path that constructs an `AppBootstrap` without explicitly setting `initialTransparentBg` (e.g., unit tests or shallow mounts) will incorrectly start in transparent mode instead of opaque mode.

```suggestion
  const [transparentBg, _setTransparentBg] = useState(bootstrap.initialTransparentBg ?? false);
```

### Issue 2 of 3
src/ui/lib/color.ts:20-21
**Transparent-bg blends toward black regardless of terminal background**

When `transparentBg` is enabled the theme fields `background`, `panel`, `panelAlt`, `contextBg`, `contextContentBg`, and `lineNumberBg` are set to `undefined`. Any caller that passes one of those fields to `blendHex` will now blend the foreground color toward `#000000` (hardcoded fallback). On a light terminal this produces a perceptually wrong result — text that should appear slightly lightened ends up darkened toward black instead. Blending should either be skipped when `bg` is `undefined`, or the caller should guard against it.

### Issue 3 of 3
src/ui/themes.ts:290-296
**`resolveTheme("auto", null)` silently resolves to the dark theme**

When `themeMode` is `null` (unknown) and the requested theme is `"auto"`, the expression `themeMode === "light" ? themeLight : themeDark` evaluates to `themeDark` because `null !== "light"`. This means any caller that passes `null` will always receive the dark-mode fallback when `"auto"` is requested, even in contexts where the correct fallback should be light or neutral. A three-way check (`themeMode === "dark" ? themeDark : themeLight`) or an explicit `null` case would be safer.

Reviews (1): Last reviewed commit: "feat(ui): transparent background" | Re-trigger Greptile

Comment thread src/ui/App.tsx
Comment thread src/ui/lib/color.ts
Comment thread src/ui/themes.ts
@m4r1vs m4r1vs force-pushed the transparent-bg branch from ce03fd6 to 00719cd Compare May 8, 2026 00:46
@m4r1vs m4r1vs force-pushed the transparent-bg branch from 00719cd to 78e448d Compare May 8, 2026 00:54
@m4r1vs m4r1vs marked this pull request as draft May 8, 2026 13:29
@m4r1vs m4r1vs changed the title WIP: feat(ui): Transparent Background feat(ui): Transparent Background May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

allow transparent background

1 participant