After some testing I decided not to use the windows that Electron creates by default. I decided to create my own titlebar, with Windows-style control buttons. There are many tutorial guides on the internet. I was inspired by a Ronnie Dutta project.
Update the dependencies
A little note before starting with this post. I’m not starting from scratch but I still use my el3um4s/memento-svelte-electron-typescript template. At first, as usual, I make sure I have all the dependencies updated to the latest version:
npm run check-updates
Create a window without a titlebar
First I create a window without a titlebar by setting the
frame property to
Add basic styles
For aesthetic reasons I add some basic styles to the
The only odd class is
overflow-y-hidden. It is used to hide the scrollbar from the Electron window. I’ll be using a custom scrollbar attached to the main section of the page.
When I start the app (with
npm run dev) I get a window like this:
What’s the problem? A window without a titlebar has no close buttons and cannot be moved. It’s time to add a custom titlebar.
Add a custom titlebar
Doing some testing the best way seems to be to create a component
src/frontend/Componentes/MainWithTitlebar.svelte in which to insert both the titlebar and the main section of the page.
I write the basic code:
Then I add the component to
Obviously this does not cause any visible changes. I need to add some styles to my component:
I set the header height to 32px using Tailwind’s
h-8 class and set the underlying page height accordingly:
It is not enough to set a titlebar to be able to move a window. Fortunately, Electron allows you to enable this possibility quite easily. Just add the CSS style
Add window control buttons
Now the window can move. But I also want to be able to close, minimize and zoom it. I need some buttons:
I set the button area as
no-drag to make it easier to click on the buttons. And speaking of buttons, in the code above I used some writing but maybe it’s better to use icons. Tailwind allows you to easily use heroicons icons. I take advantage of it and create some Svelte components to display the icons. This, for example, is the
After creating the icons I insert them in the titlebar:
Add the title to the window
There can be several ways to add the title to a window. A simple way is this:
Customize the scrollbar
Electron shows the Chrome scrollbar by default. I can change its style with some CSS code:
This is the result:
Nothing happens if I click on the buttons, also because I haven’t added any functions. I resolve immediately:
Obviously the functions must be filled with code. What can I use? I need to use a specific API. I create the
Register the new API on
Finally I allow the main Electron window to use the API. I edit the
This allows me to go back to the component I’m working on (
MainWithTitlebar.svelte) and add the missing functions:
Now I can use the various buttons to minimize, maximize and close the window.
Reset the window size
However, there is an anomalous behaviour. When I maximize the window I would like to replace the
maximize icon with another one. And maybe when I click I can restore the original window size.
To achieve this I can take advantage of the
<svelte:window> element. By inserting it into my Svelte component I can intercept some events related to the window without leaving the component itself.
Why do I have to do this? Because I haven’t found an easier way to tell when the window is full screen. Then I have to use a trick: I check the size of the window. If the window is at least as big as the screen then I assume it is maximized. Otherwise no.
$: marks a statement as reactive: this greatly simplifies the necessary code.
Now I just have to add the function:
That’s all. Finally some useful links:
- the project on GitHub: el3um4s/memento-svelte-electron-typescript
- my Patreon: patreon.com/el3um4s