Skip to content

fix(desktop): eliminate white flash on window resize#1380

Open
timmske wants to merge 1 commit intopingdotgg:mainfrom
timmske:fix/white-flash-on-resize
Open

fix(desktop): eliminate white flash on window resize#1380
timmske wants to merge 1 commit intopingdotgg:mainfrom
timmske:fix/white-flash-on-resize

Conversation

@timmske
Copy link

@timmske timmske commented Mar 24, 2026

What changed

Set BrowserWindow.backgroundColor to match the active theme so Electron paints the correct surface color while the renderer catches up during resize.

  • Read nativeTheme.shouldUseDarkColors at window creation to pick the initial background (#161616 dark, #ffffff light)
  • Update all windows via setBackgroundColor when the user switches themes
  • Add a synchronous <script> in index.html <head> that applies the stored theme background and .dark class before first paint

Why

The BrowserWindow had no backgroundColor set. During resize Electron briefly exposes unpainted native window area, which defaults to white — producing the flash reported in #1349.

Screenshots

Before: white flash visible during resize (see video in #1349)
After: background matches theme, no flash during resize

Checklist

  • PR is small and focused (30 lines, 2 files)
  • Changes and rationale clearly explained
  • bun fmt passes
  • bun lint passes (0 warnings, 0 errors)
  • bun typecheck passes (7/7)
  • bun run test — server test failures are pre-existing on main

Closes #1349


Note

Low Risk
Small, UI-only theming changes limited to Electron window creation/theme switching and an inline web boot script; minimal logic and no security/data-path impact.

Overview
Eliminates the white flash during Electron window resize by setting and maintaining BrowserWindow.backgroundColor to match the active theme. The desktop main process now derives the background from nativeTheme.shouldUseDarkColors at window creation and updates all open windows via setBackgroundColor when desktop:set-theme is invoked.

Adds shared theme constants (THEME_BG_DARK/THEME_BG_LIGHT) exported from @t3tools/shared/theme, and adds a synchronous <head> script in apps/web/index.html that applies the .dark class before first paint based on stored theme preference/system color scheme.

Written by Cursor Bugbot for commit 4fbbeca. This will update automatically on new commits. Configure here.

Note

Fix white flash on window resize by setting native background color to match theme

  • Sets backgroundColor on new BrowserWindow instances using a themeBackgroundColor() helper so the native window background matches the active theme from first paint.
  • Updates all existing windows' background color when the theme changes via the SET_THEME_CHANNEL IPC handler.
  • Adds an inline script in index.html that applies the dark class to documentElement before first paint, preventing a flash of unstyled content on load.
  • Exports THEME_BG_DARK (#161616) and THEME_BG_LIGHT (#ffffff) from a new @t3tools/shared/theme subpath as the source of truth for these colors.

Macroscope summarized 4fbbeca.

@coderabbitai
Copy link

coderabbitai bot commented Mar 24, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fa6773e2-2fbb-4418-87d8-c7186ac516fe

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Mar 24, 2026
Comment on lines +1230 to +1234
// Background colors that match the app's CSS theme tokens.
// Dark: color-mix(in srgb, neutral-950 95%, white) ≈ #161616
// Light: white
const THEME_BG_DARK = "#161616";
const THEME_BG_LIGHT = "#ffffff";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not particularly a fan of duplicating the colors here, especially for an easy-to-miss bug like this one. We should have a single-source-of-truth somewhere and import it both places.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point — updated. The colors now live in a single @t3tools/shared/theme module that the desktop main process imports. The index.html inline script no longer carries any color literals; it just applies the .dark class so the CSS custom properties resolve correctly.

Set BrowserWindow.backgroundColor to match the active theme so Electron
paints the correct color while the renderer catches up during resize.

- Add @t3tools/shared/theme as single source of truth for the native
  window background colors (#161616 dark, #ffffff light).
- Read nativeTheme.shouldUseDarkColors at window creation to pick the
  initial background.
- Update all windows via setBackgroundColor when the user switches themes.
- Add a synchronous <script> in index.html <head> that applies the .dark
  class before first paint so CSS custom properties resolve correctly.

Closes pingdotgg#1349
@timmske timmske force-pushed the fix/white-flash-on-resize branch from 7225859 to 4fbbeca Compare March 25, 2026 08:06
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

const bg = themeBackgroundColor();
for (const win of BrowserWindow.getAllWindows()) {
win.setBackgroundColor(bg);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale background color when OS theme changes

Medium Severity

When the app is set to "system" theme, OS-level dark/light mode changes update the renderer (via prefers-color-scheme media query) but never call setBackgroundColor on the BrowserWindow. The SET_THEME_CHANNEL handler only fires when the user explicitly changes the theme in the UI. Without a nativeTheme.on('updated') listener, the window background becomes stale after an OS theme change, causing the same wrong-color flash on resize that this PR aims to fix.

Additional Locations (1)
Fix in Cursor Fix in Web

* so resizing never flashes a mismatched color.
*/
export const THEME_BG_DARK = "#161616";
export const THEME_BG_LIGHT = "#ffffff";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded colors duplicate CSS tokens risking drift

Low Severity

THEME_BG_DARK (#161616) is a manually computed approximation of the CSS color-mix(in srgb, neutral-950 95%, white) token in index.css. There is no single source of truth — if the CSS value changes (different base color, different percentage, different color space), this constant silently becomes wrong and the BrowserWindow background will flash a mismatched color during resize. This was also flagged by a reviewer.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: when the screen is resized in t3 code, a white flask appears

2 participants