Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default window background color #861

Closed
yongkangchen opened this issue Nov 25, 2014 · 43 comments
Closed

default window background color #861

yongkangchen opened this issue Nov 25, 2014 · 43 comments

Comments

@yongkangchen
Copy link

display

I run a quick start demo, and set index.html background:

<!DOCTYPE html>
<html style="background: #232323">
  <head>
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using node.js <script>document.write(process.version)</script>
    and atom-shell <script>document.write(process.versions['atom-shell'])</script>.
  </body>
</html>

There is a flash when start application. Is there any way to set the default window background color?

@zcbenz
Copy link
Contributor

zcbenz commented Nov 25, 2014

There is no way to set native window's background color for now, usually you can work around the flash by creating a hidden window on startup and show it after the page has done loading.

@yongkangchen
Copy link
Author

I submit this issue for try to improve user experience of start atom at: atom/atom#4269 (comment)

@yongkangchen
Copy link
Author

As you say, usually can creating a hidden window on startup. But this lead to a bad user experience that user can not see window or loading and have a strong slow feeling.

@yongkangchen
Copy link
Author

@zcbenz BTW, Just curious, why there must be a setTimeout about 40ms to work around the flash? which lead a simple page to start about 300ms?
This is my code:

  var startTime = Date.now();
  mainWindow = new BrowserWindow({width: 800, height: 600, show: false});
  // and load the index.html of the app.
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
  mainWindow.webContents.on('did-finish-load', function() {
    setTimeout(function(){
      mainWindow.show();
      console.error(Date.now() - startTime);  
    }, 40);
  });

@bpasero
Copy link
Contributor

bpasero commented Mar 28, 2015

+1 for a way to set the native background color for the reasons of faster perceived app startup.

@oneezy
Copy link

oneezy commented Apr 29, 2015

+1, yes. I'm glad that when I googled "Atom Default Background", this was the first page I found.

Nice to know that others are thinking along the same lines ;)

User Experience is where it's at!

@tommoor
Copy link
Contributor

tommoor commented Jul 25, 2015

The background color also shows through when resizing a window as flashes of white around the edge, this is very obvious if your app's background isn't white. @zcbenz any thoughts on where this issue stands in priority - I noticed that it also affects Atom Editor 😉

@frankhale
Copy link
Contributor

Similar issue on CEF https://code.google.com/p/chromiumembedded/issues/detail?id=1161

Old Chromium issue: https://code.google.com/p/chromium/issues/detail?id=361235

Some old Chromium commits for this issue: https://codereview.chromium.org/124553002/

What follows below is a naive attempt to hand jam libchromiumcontent to change that god awful white background color...

This isn't a complete answer to this issue but for people that may want to get their hands dirty I have successfully changed the background color of the Electron window for Windows by editing the native_window_views.cc file. In the NativeWindowViews constructor I added the following:

At line 320 where #if defined(OS_WIN) is defined I added this:

HBRUSH brush = ::CreateSolidBrush(RGB(255, 0, 0));
::SetClassLongPtr(GetAcceleratedWidget(), GCLP_HBRBACKGROUND, (LONG)brush);

This changes the background to red. Now when I start Electron's default app and resize it I see a red background as the Chrome content window tries to keep up with the resize.

If this works for some people a command line switch could be exposed to allow this to be changed. I think that'd be the simplest way to hack this in for those wanting to get their hands dirty. And for those providing their own custom binaries that don't mind having hacks in.

If anyone is willing could you investigate similar ways to do this for Linux/Mac maybe even within the native_window_views.cc.

Aside from doing this in Electron's code it can also be done from Chromium if need be. I'm sure similar techniques can be employed.

Additionally, Electron's default app loads too fast on my machine so I cannot see a red background as the app is loading. Does anyone have a sample Electron app that can simulate a very slow loading app that can cause the Chromium content window to load slowly so the background shows like in the animated gif above?

EDIT 1:

Actually my hack doesn't work totally, I just checked my own app (instead of the Electron default app). I suspect this will need to be patched in Chromium because the content window will still show white while the Electron window will be changed.

I'm investigating Chromium's code: chromium\src\ui\gfx\win\window_impl.cc as a test to see if this is where the change needs to happen. There are similar files for Linux and Mac.

EDIT 2:

Changing this in chromium\src\ui\gfx\win\window_impl.cc seems to be out of the question, doesn't work. I'm looking at chromium\src\content\browser\renderer_host\render_widget_host_view_base.cc now. I don't know if this will be it either. Throw me a bone guys, LOL!

EDIT 3:

chromium\src\content\browser\renderer_host\render_widget_host_view_base.cc doesn't seem to work either. I'll try again tomorrow. We have to isolate exactly which window the content window is and then set the background color there. This is fun! LOL!

EDIT 4:

I've had some minor success with heavy handed libchromiumcontent hacking but it doesn't seem to be as cut and dry as it sounds. If anyone wants details please let me know.

@frankhale
Copy link
Contributor

I got this bright idea to call insertCSS on the browser window before loadUrl but that doesn't work because apparently webContents is not initialized or if it is the insertCSS is ignored. This can be best illustrated by just commenting out your LoadUrl in your main.js and what you'll see is a nice white background. You can open Dev tools and see a whole lot of nothing in any of the tabs. No ability to inspect the underlying content if there is any (which I suspect there isn't).

I can certainly hand jam libchromiumcontent to make the background any color but this doesn't work universally (yet as I have not isolated every place the background of the window is set, there are a lot), for instance when resizing a page that has a webview you'll still see a white background. I've spent 8 hours today looking into this. LOL!

Additionally I've updated my last post to this issue and added some corresponding Chromium and CEF patches.

For those wanting to try their luck at this, this site is invaluable for searching Chromium's code:

https://code.google.com/p/chromium/codesearch

Update 1:

Okay so I finally had some success with resizing webviews and possibly other elements and getting rid of the white background. I hard coded the background_color_ to be SK_ColorBLACK in chromium/src/cc/layers/layer.cc in libchromiumcontent and now the white is replaced with black.

Here is some progress, in my case I need a black background. The flash at the beginning is not a white background even though it may look like it. I've inspected the individual frames of the gif as the window opened up. This is all hard coded into libchromiumcontent now so nothing able to be exposed yet to Electron.

Getting this far required changing a few files to get all the white backgrounds changed. I'm still working on this and am adding a command line switch override to libchromiumcontent. Hopefully I can document all of the involved files soon but this is still a work in progress.

NOTE: To be honest I'm having a tough time reproducing this on a clean libchromiumcontent. I've changed so much today that I don't know every file I've changed. It's going to take a little more work to figure this out unfortunately.

electron-resize-no-white

Update 2:

Just to recap this issue as far as Chromium goes. One hurdle to solve this is that Chromium hard codes Sk_ColorWHITE for a lot of backgrounds in the various components. Plus there are other areas of the code that don't use the SkColor.h. There is also at least one other header file that defines base colors used.

Take some of what I wrote above with a grain of salt, in other words what I wrote is not fully correct and I will try to provide some clarity soon. Yesterday I changed so much code in libchromiumcontent that I totally lost track of all my changes and now cannot reproduce what I have in my animated gif above. I'm working on it though. What I'm attempting to do in the short term as far as Electron goes is expose a new command line switch to override the base background color. This is the path of least resistance as far as an API goes and allows me to focus on the problem which is that god awful white background color. LOL!

@ervumlens
Copy link

@frankhale That's fantastic and incredibly encouraging. 🏆 Thanks for running with it even this far.

@frozeman
Copy link

+1 for this, would be very nice if we could set the default bg color!

@frankhale
Copy link
Contributor

There are multiple issues going on here. I've been looking at this for quite a long time. This particular comment isn't going to talk about the white window on app load although I am still looking into that one and have spent 10's of hours on it. This comment is a continuation of that. In my app I use a webview and the webview creates an object inside of it within a shadow-root. This object is white and when resizing will expose that gawd awful white window as the webview object tries to keep up with the resize. This object cannot be styled so you cannot just set it's background color, similarly I have not been able to select this object using jQuery. Seems the shadow-root is well.... shadowed, LOL!

On a whim I was like lets just make that object inside the webview an iframe instead of an object because I could then set it's background color to whatever I wanted. So I hacked web-view.coffee to do that. Everything still seems to function correctly, I can set the background color of that iframe inside the webview, pass along the webview src and all is well. Now resizing the window will show the color I want instead of the nasty white. Here is where I need a sanity check. Is there a specific reason the object inside the webview is an object? I mean, I made it an iframe and my app functions perfectly fine. It's not violating the sandboxing, eg. It's not getting node integration because of this change. It's still safely tucked away in that shadow-root inside the webview for which I have not enabled node-integration. No errors in the console, functionality is the same. Life is good. Is this insane? Can anyone comment on this?

Just to clarify a point, I did not actually set the iframe's background color, I set the webview's background color which the iframe inherits.

UPDATE #1: By doing what I mentioned above you lose webview's custom API's. eg. preload doesn't work, no events get fired etc... This may or may not be desirable for your app.

@frankhale
Copy link
Contributor

In native_window_views.cc in the constructor I think we should provide a way to set an initial background color eg, through perhaps an option in the browser window creation.

At the end of the constructor I have put the following as an illustration. This gets us some of the way there but does not address the white window flash when everything is loading up. This does appear to help alleviate the white on resize issue. We'll need a way for users to specify their own custom color though. We'll need a way to translate a nice hex color string to the appropriate value for passing to this function. Additionally this uses Chrome code so should work on Linux and Mac. I only tested on Windows.

// Here we just hard code the background to black to see if we can gain some control over the 
// elusive white window showing on resize. 
web_view_->set_background(views::Background::CreateSolidBackground(0xFF000000));

There are still some white issues remaining but I'm hoping to track down the rest of them soon.

@frankhale
Copy link
Contributor

Here is something more concrete and usable. This doesn't solve the initial white window background but will help alleviate the issue once everything loads. This also won't solve the white background behind a webview because the webview uses the object tag and you cannot set the background color using CSS styling. I'm still working on the two issues I just mentioned.

Add to native_window_views.cc NativeWindowViews constructor (I added it at the bottom)

  auto command_line = base::CommandLine::ForCurrentProcess();
  auto base_background_color = command_line->GetSwitchValueNative(switches::kSetBaseBackgroundColor);
  if(!base_background_color.empty()) {
    auto color = std::stoul(base_background_color, nullptr, 0);    
    web_view_->set_background(views::Background::CreateSolidBackground(color));
  }

Caveat: No error checking yet for the color coming in.

Add to option_switches.h

extern const char kSetBaseBackgroundColor[];

Add to options_switches.cc

const char kSetBaseBackgroundColor[] = "set-base-background-color";

Color format looks like this:

electron.exe --set-base-background-color=0xFF000000

The initial FF is for alpha transparency.

@bpasero
Copy link
Contributor

bpasero commented Sep 15, 2015

Nice progress! Setting the color through the exe would not really work for us though. We would need to set the background color right before the browser window, so having it as option in the constructor would be ideal!

@gabriel
Copy link
Contributor

gabriel commented Jan 20, 2016

Here is a PR for backgroundColor support on mac: #4161

@jordwalke
Copy link

@gabriel - Does that pull request (4146) make Atom (and other electron apps) capable of setting the fill color when resizing? Or is there something else still missing?

@erusev
Copy link

erusev commented Mar 11, 2016

@gabriel I'd very much like to know that as well, thanks.

@frankhale
Copy link
Contributor

@jordwalke, Sorry I was riffing off of the white background on window resize issue.

@frankhale
Copy link
Contributor

@erusev, yes I would agree with this.

@erusev
Copy link

erusev commented Mar 11, 2016

@frankhale Did you have a chance to see the PR of @gabriel and find out if it helps for any of these issues and more specifically - the initial white screen and the white flickering on resize?

@frankhale
Copy link
Contributor

@erusev, I am not a Mac user. This PR states in the title it's for Mac. Does it work on non Mac systems?

@erusev
Copy link

erusev commented Mar 11, 2016

@frankhale It seems to be Mac specific, indeed, I did not know that you're not a Mac user.

feross added a commit to webtorrent/webtorrent-desktop that referenced this issue Mar 27, 2016
We got the window to run less JS but now it’s shown by the main process
too soon! This fixes that with a setTimeout.

Perhaps when this issue is fixed
(electron/electron#861) we can remove the timeout.
@atmosuwiryo
Copy link

It is flickering on resize and change tab.
We are using node 5.10.0,
Chromium 49.0.2623.75,
and Electron 0.37.7.
electron

Can't find workaround yet. :(

mathiasvr pushed a commit to mathiasvr/webtorrent-desktop that referenced this issue May 26, 2016
We got the window to run less JS but now it’s shown by the main process
too soon! This fixes that with a setTimeout.

Perhaps when this issue is fixed
(electron/electron#861) we can remove the timeout.
@mrtdeh
Copy link

mrtdeh commented May 28, 2016

Hi i founded the best answer:
set transparent:true in main.js and run your electron app....

@dmythro
Copy link

dmythro commented Jun 10, 2016

@mrtdeh, also tried first, but have problems with shadow then with frameless window.

@Hum4n01d
Copy link

Hum4n01d commented Nov 8, 2016

Hey guys, I found this and solved the issue: http://www.christianengvall.se/electron-white-screen-app-startup/

@riseremi
Copy link

@Hum4n01d thank you!

@matthiasg
Copy link

with electron 1.6.4 i still get a white splash on windows 10. Is this supposed to be solved ?

@coreyman
Copy link

So using @Hum4n01d 's solution I can not seem to set the background-color to transparent. Wanted to put a drop shadow on one of my windows.

@Aceix
Copy link

Aceix commented Aug 11, 2017

BrowserWindow now has a property, 'backgroundColor' for setting a background color before rendering the page

@ErickRodrCodes
Copy link

@Aceix that work pearls. When resizing an transparent window, it left a ugly white render. applying the backgroundColor parameter to BrowserWindow solved the issue

@wis
Copy link

wis commented Jan 19, 2018

use the backgroundColor property on BrowserWindow, I set it to '#00FFFFFF' (top white top transparency) worked wonders for my app's use case.
but using the show property with the 'ready-to-show' event is a better way for most apps.

@matthiasg
Copy link

matthiasg commented Jan 31, 2018

This is not working though with kiosk mode or when maximizing

EDIT: only solution so far is to create the window in the desired size already (using e.g const {width, height} = electron.screen.getPrimaryDisplay().workAreaSize)

@Ph0enixKM
Copy link

win.setBackgroundColor("#222");

That's it guys... 😄

@programmin1
Copy link

Even on a wellknown Electron app like VS Code the bug pops up once in awhile where there is nothing in the window but transparent view of what is behind it.

@felixturner
Copy link

Still seeing a white flash on startup with electron 15 / macos. Setting backgroundColor does not help.

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

No branches or pull requests