Repository: electron/electron
Pull request: fix: white window flicker on window creation

#### Description of Change

Refs CL:6245732
Closes https://github.com/electron/electron/issues/46924
Closes https://github.com/electron/electron/issues/35362
Closes https://github.com/electron/electron/issues/45625

Fixes an issue where the window flickers with either a light or dark color before loading the desired background color if one is set. This happened mostly as a result of transparency-related handling.

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Fixed an issue where the window flickers with either a light or dark color before loading the desired background color.


Changed files:
filename: shell/browser/native_window_views.cc
patch: @@ -37,6 +37,7 @@
 #include "shell/common/options_switches.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
+#include "ui/compositor/compositor.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/native_widget_types.h"
@@ -1224,6 +1225,7 @@ void NativeWindowViews::SetBackgroundColor(SkColor background_color) {
     DeleteObject((HBRUSH)previous_brush);
   InvalidateRect(GetAcceleratedWidget(), nullptr, 1);
 #endif
+  GetWidget()->GetCompositor()->SetBackgroundColor(background_color);
 }
 
 void NativeWindowViews::SetHasShadow(bool has_shadow) {

filename: shell/browser/ui/win/electron_desktop_window_tree_host_win.cc
patch: @@ -23,6 +23,20 @@ ElectronDesktopWindowTreeHostWin::ElectronDesktopWindowTreeHostWin(
 
 ElectronDesktopWindowTreeHostWin::~ElectronDesktopWindowTreeHostWin() = default;
 
+bool ElectronDesktopWindowTreeHostWin::ShouldUpdateWindowTransparency() const {
+  // If transparency is updated for an opaque window before widget init is
+  // completed, the window flickers white before the background color is applied
+  // and we don't want that. We do, however, want translucent windows to be
+  // properly transparent, so ensure it gets updated in that case.
+  if (!widget_init_done_ && !native_window_view_->IsTranslucent())
+    return false;
+  return views::DesktopWindowTreeHostWin::ShouldUpdateWindowTransparency();
+}
+
+void ElectronDesktopWindowTreeHostWin::OnWidgetInitDone() {
+  widget_init_done_ = true;
+}
+
 bool ElectronDesktopWindowTreeHostWin::PreHandleMSG(UINT message,
                                                     WPARAM w_param,
                                                     LPARAM l_param,

filename: shell/browser/ui/win/electron_desktop_window_tree_host_win.h
patch: @@ -31,6 +31,8 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
 
  protected:
   // views::DesktopWindowTreeHostWin:
+  void OnWidgetInitDone() override;
+  bool ShouldUpdateWindowTransparency() const override;
   bool PreHandleMSG(UINT message,
                     WPARAM w_param,
                     LPARAM l_param,
@@ -51,6 +53,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
  private:
   raw_ptr<NativeWindowViews> native_window_view_;  // weak ref
   std::optional<bool> force_should_paint_as_active_;
+  bool widget_init_done_ = false;
 };
 
 }  // namespace electron