Implementation
The MainWindow class constructor expects an object as first parameter. In order to make our window transparent, we need to provide the transparent
and frame
property to true and false respectively:
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({
width: 800,
height: 600,
transparent:true,
frame: false
})
win.show()
Tipically, if the transparent windows is meant to be the unique and initial, then you should make the changes in the main.js file:
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
transparent: true,
frame:false
})
// and load the index.html of the app.
mainWindow.loadURL(`file://${__dirname}/index.html`)
// Open the DevTools.
//mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
That should make already your window transparent. Set as content of your index.html
file the following markup:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Transparent Window</title>
</head>
<body>
<div>
<img src="http://ourcodeworld.com/resources/img/ocw-empty.png" width="300" height="300"/>
</div>
</body>
</html>
and execute the project using npm start
, your app will look like:
As you can see, the window is totally transparent and you can see VSCode at the background.
Limitations
- You can not click through the transparent area. We are going to introduce an API to set window shape to solve this, see the issue for details.
- Transparent windows are not resizable. Setting
resizable
totrue
may make a transparent window stop working on some platforms. - The
blur
filter only applies to the web page, so there is no way to apply blur effect to the content below the window (i.e. other applications open on the user's system). - On Windows operating systems, transparent windows will not work when DWM is disabled.
- On Linux users have to put
--enable-transparent-visuals --disable-gpu
in the command line to disable GPU and allow ARGB to make transparent window, this is caused by an upstream bug that alpha channel doesn't work on some NVidia drivers on Linux. - On Mac the native window shadow will not be shown on a transparent window.
Important notes
If the developer tools area is visible, the window won't be transparent anymore. If it's hidden or it's not shown then the transparent effect will be kept.
As probably no one wants a static window that can't be moved, allow the drag feature to an element by using CSS:
.draggable-area{
-webkit-app-region: drag;
}
By adding the draggable-area
class to any element, it will allow the user to drag the entire window from that point. On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas.
Example
The following document will make a very simple transparent window with a couple of button actions and a draggable area:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Transparent Window</title>
<style>
.draggable-area{
width:300px;
height:300px;
background-color:blue;
color:white;
-webkit-app-region: drag;
}
</style>
</head>
<body>
<div>
<img src="http://ourcodeworld.com/resources/img/ocw-empty.png" width="300" height="300"/>
<div>
<input type="button" id="close" value="Close app"/>
<input type="button" id="devtools" value="Open DEV Tools"/>
<div class="draggable-area">
Drag the window here
</div>
</div>
</div>
<script>
var app = require('electron').remote;
// Close app
document.getElementById("close").addEventListener("click", () => {
app.BrowserWindow.getFocusedWindow().close();
}, false);
// Close app
document.getElementById("devtools").addEventListener("click", () => {
app.BrowserWindow.getFocusedWindow().openDevTools();
}, false);
</script>
</body>
</html>
The previous markup should generate an app like:
Have fun !