This post will cover how to fix the electron white screen app startup. If you start the electron tutorial app you can see it flashes white and then loads the css setting the correct color. The electron API currently allows two ways of fixing this.
This is what the the tutorial app looks like when it starts before applying this fix.
Electron - flashing white on startup
Setting backgroundColor
One way is to let the app flash before load, but setting the white color to something else. In this case it would be #312450. This is a setting on the BrowserWindow and in our tutorial app we set it on line 13 in main.js.
If this works well with your app this is a good alternative because it will appear to load your app faster than the other one we will look at now. If your app has more than one background color, like the tutorial app does (the menu background and the main container background), setting the startup background color is not enough. But this is a matter of taste, there is no right or wrong. This is what the official docs say:
"Note that even for apps that use ready-to-show event, it is still recommended to set backgroundColor to make app feel more native."
ready-to-show event
This technique waits for the event ready-to-show to fire. When that happens we take care of showing the window. But before doing that we need to tell the mainWindow to not show when we init a new BrowserWindow.
Now we need to tell it to show on the ready-to-show event. Put these lines in the function createWindow in main.js.
I had a few piano songs recorded in Reason. But i wanted to copy the midi from Reason to Logic because that’s the software I use to record things now.
Last time I used Reason was when version 3 was released. So it was quite a long time ago. Could it have been around 2006? However… my first thought was to get hold of Reason 3 somehow and see if i could manually copy the midi tracks. Turns out that wasn’t needed at all.
Reason 9
Propellerhead has made Reason 9 available to use as a trial for 30 days. So i installed the trial version and tried to open my old recordings. And thankfully it worked well! Even if i used some plugins or instruments that didn’t exist in the new version i could still see that the song was there, but i couldn’t listen to it. If you get this window when opening your song you can just close it.
Missing sounds
Next click the File menu and select Export midi file… and save it where ever you like.
File export midi
Logic
Now open up a new project in Logic and go to File-> import -> Midi file and select the midi file you just exported from Reason.
File import midi
Logic will add the tracks for you. You will get a question about the tempo of the song. i choose not to import the tempo. Not sure why though… i’m a developer… not a producer… don’t ask me those hard questions!
Now it’s time to look at the Electron frameless window functionality. Using a frameless window removes the menu and menubar in your app. The electron documentation defines it as:
"A frameless window is a window that has no [chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome), the parts of the window, like toolbars, that are not a part of the web page."
Alternatives
There are two alternatives to choose between. Either remove the frame for all three platforms using frame: false when initializing the browserwindow in main.js. Or you can use titleBarStyle: ‘hidden’. This alternative is only for macOS. Lets look at them both.
If you remove the frame around your app, the user also looses the ability to move the application around on the desktop. So we need to give that functionality back to the user. We do that with draggable regions. But more on that later.
Frame:false
This removes all the chrome around the application on all platforms. Then it is up to you to handle how the application closes, minimizes and maximizes. Electron provides api’s for this. so you can add buttons and style them the way you like. and then hook them up to the correct handler. Look at the BrowserWindow class and the methods called minimize, maximize, unmaximize, and close. For macOS you don’t use maximize, instead you use setFullScreen.
This is what the Electron tutorial app would look like when setting frame:false
Electron frame false
titleBarStyle Hidden
This is the macOS only alternative. It removes the titlebar but leaves the stop light buttons.
Using this setting the app would look like this on macOS from Yosemite(10.10) and newer. On Windows and Linux there will be no change at all.
Electron titlebar hidden
I like the option to remove the titlebar on macOS and leaving it as is on Linux and Windows. So i’m going for the titleBarStyle: ‘hidden’ setting.
Hidden-inset
There is also a titleBarStyle: ‘hidden-inset’. The docs explain it like this:
"results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge."
Draggable region
As said earlier, when using frameless window the user looses the ability to drag your application around the desktop. Let’s fix that. Electron handles this with css.
To make the whole window draggable you can set -webkit-app-region: drag on the body element. To do that in the electron tutorial app open up assets/sass/base/_page.scss and add this to the body.
This makes our window draggable again. But it makes it a little to much draggable. For example the buttons will be draggable and the user won’t be able to click them. We’ll fix this with -webkit-app-region: no-drag; open up assets/sass/components/_button.scss and that property to button, textarea and input types submit, reset, button and text.
If you implement your own titlebar and the user tries to move your app by dragging it the text in the titlebar may become selected. And we don’t want that. we can set this with -webkit-user-select: none; The electron tutorial app uses h1 as some kind of titlebar. Let’s remove the users ability to select headers.
Open up assets/sass/base/_typography.scss and go down to line 57 where you add this:
It’s time to implement an electron app navigation in the Electron tutorial app. Not the main kind of menubar but a left menu kind. For this step some use react or some other framework. But i wanted to keep it simple so this tutorial does not use a UI framework. This is the way the navigation is implemented in the Electron api demos application.
The name of the app is now called Electron tutorial app instead of electron hello world as it was before. I thought that name suits it better since it’s not only a hello world from now on. To get the source code of this application as it looks at the end of this tutorial you can download it from github.
1. Adding a design
First off the app looks pretty dull and does not have a menu. Since the design is out of scope for the tutorial we will use a template from HTML5up called hyperspace. Go ahead and download it.
Electron tutorial app - dull look
Once you’ve downloaded and unpacked hyperspace, copy the folder called assets into the root folder of our electron app. Then copy this HTML-markup into our index.html.
This is the hyperspace markup but with two differences
Internet explorer specific css has been removed. Electron uses chromium.
The import of jquery at the bottom has been changed
The media query that show the menu in hyperspace is defined to be over 1280 pixels. So go into our main.js file and go to line 13 and make it look like this:
We change the startup width to 1281, the startup height to 800 and setting the minWidth and minHeight to the same values. You can read more about the BrowserWindow Class and it’s properties at the official documentation.
Hyperspace is a single page layout. So it works as it is now. But that’s not what i’m going for. If you scroll the main window you can see all the pages in our app. And if you click on a menu item you will be scrolled down to that section. An app with a lot of menu items will create a lot of markup in index.html this way. In this step we’ll make all the menu items load it’s own .html file with the markup we want.
2.1 Extract sections
Create a new folder called sections and add four new files to it that are called: getintouch.html, welcome.html, whatwedo.html and whoweare.html
The contents in these files are the different sections you can find in index.html at this point. But when they are extracted i also wrap a template tag around the sections. They will be used in the javascript later on. I’ve also deleted the fade-in classes on the sections because the didn’t work that well. They also got new id’s.
getintouch.html
welcome.html
whatwedo.html
whoweare.html
2.2 Empty index.html wrapper
Now the sections are extracted into their own respective files we can empty the div with the id wrapper in index.html. This is not the full index.html, only what the wrapper looks like. the HTML above and under should be left as is.
index.hml
3. Preparing the menu and importing sections
3.1 data-section
In index.html there is a navigation in the sidebar section. Update the anchor tags to look like this:
We’ve added a data-section attribute with the value of the file names that we created in step 2. We’ll later use this when loading the sections with javascript.
3.2 Importing section html files
Update the head-section in index.html to look like below. We use import so that chromium can load the contents before we need to use them in our javascript. You can read more about how the rel=”import” works on html5rocks.
4. Making the menu do something
Add a new script to the assets/js folder called menu.js and import in in index.html with the require function.
And now to the contents of menu.js:
Lets go trough it. Start by looking in the init() function. This function will run when the document is loaded. It calls importSectionsToDOM(), setMenuOnClickEvent() and showStartSection().
importSectionsToDom()
This function loads all the rel=”imports” that we added to the head section in index.html and adds it to the div with id #wrapper in index.html.
setMenuOnClickEvent()
This function adds an eventlistener and looks for events where the data attribute section is set. If it is it calls hideAllSections() and showSection(event). More on these soon.
showStartSection()
We need to show a section when the app is started the first time. That is what this function does. Line 36 make sure that the first menu item is clicken, 37 and 38 makes the start section show.
hideAllSections()
This function is called before a new sections is shown. As the name hints it hides all the other sections so they are not in the way of the one that is about to show.
showSection(event)
If the user has clicked a menu item this function will be called on line 24. it takes the id of the section to be shown and uses jquerys show to display it.
This makes our menu work. But the hyperspace template needs some updates to make it work better.
5. Updating hyperspace to work with our menu
Hyperspace uses sass so we’ll continue to do that. If you don’t want to do that. you can do the changes directly to assets/css/main.css or just download the css from the repo and replace the your own file with it.
5.1 Adding config.rb
Add this content to a file and name it config.rb to get the correct paths to sass files. Save it in the same directory as index.html
5.2 Updating some styles
open the file assets/sass/components/_section.scss and add this:
Next go into assets/sass/layout/_intro.scss and change #intro to .intro and add .inner:
5.3 Updating hyperspace javascripts
Hyperspace uses scrollex on some pages, that does not work to well now when we split the sections to separate files. open up assets/js/main.js then go to line 149 and comment out that function all the way to line line 185:
Thats it for this short(oh my satan it’s to long!) tutorial.