ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.
In some desktop applications, a need arises due to which we need to keep the system active for longer durations. For example, during a file download or streaming audio/video. In such cases, we need to prevent the system from entering low-power mode. Else the application might be suspended from further execution. Electron provides us with a built-in powerSaveBlocker module for this very purpose. Using this module, we can control the system behavior and block the system from entering sleep mode. We can also restore the system to its original settings by disabling this power blocker. This tutorial will demonstrate the powerSaveBlocker module in Electron.
We assume that you are familiar with the prerequisites as covered in the above-mentioned link. For Electron to work, node and npm need to be pre-installed in the system.
powerSaveBlocker: The powerSaveBlocker Module is part of the Main Process. To import and use this Module in the Renderer Process, we will be using Electron remote module. For more details on the remote module, Refer this link.
- Project Structure:
Example: We will start by building the Electron Application for the powerSaveBlocker module implementation by following the given steps.
- Step 1: Navigate to an Empty Directory to setup the project, and run the following command,
npm init
To generate the package.json file. Install Electron using npm if it is not installed.
npm install electron --save
This command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the scripts key.
package.json:{ "name": "electron-block", "version": "1.0.0", "description": "Prevent System from Sleep in Electron", "main": "main.js", "scripts": { "start": "electron ." }, "keywords": [ "electron" ], "author": "Radhesh Khanna", "license": "ISC", "dependencies": { "electron": "^8.3.0" } }
- Step 2: Create a main.js file according to the project structure. This file is the Main Process and acts as an entry point into the application. Copy the Boilerplate code for the main.js file as given in the following link. We have modified the code to suit our project needs.
main.js:
const { app, BrowserWindow } = require(
'electron'
)
function
createWindow () {
// Create the browser window.
const win =
new
BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration:
true
}
})
// Load the index.html of the app.
win.loadFile(
'src/index.html'
)
// Open the DevTools.
win.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
// This method is equivalent to 'app.on('ready', function())'
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on(
'window-all-closed'
, () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if
(process.platform !==
'darwin'
) {
app.quit()
}
})
app.on(
'activate'
, () => {
// On macOS it's common to re-create a window in the
// app when the dock icon is clicked and there are no
// other windows open.
if
(BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
// In this file, you can include the rest of your
// app's specific main process code. You can also
// put them in separate files and require them here.
- Step 3: Create the index.html file within the src directory. We will also copy the boilerplate code for the index.html file from the above-mentioned link. We have modified the code to suit our project needs.
index.html:
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
>Hello World!</
title
>
/security#csp-meta-tag -->
<
meta
http-equiv
=
"Content-Security-Policy"
content
=
"script-src 'self' 'unsafe-inline';"
/>
</
head
>
<
body
>
<
h1
>Hello World!</
h1
>
We are using node
<
script
>
document.write(process.versions.node)
</
script
>, Chrome
<
script
>
document.write(process.versions.chrome)
</
script
>, and Electron
<
script
>
document.write(process.versions.electron)
</
script
>.
<
br
><
br
>
<
button
id
=
"enter"
>Prevent Display from Sleeping</
button
>
<
br
><
br
>
<
button
id
=
"disable"
>Disable Blocker</
button
>
<!-- Adding Individual Renderer Process JS File -->
<
script
src
=
"index.js"
></
script
>
</
body
>
</
html
>
Output: At this point, our application is set up and we can launch the application to check the GUI Output. To launch the Electron Application, run the Command.
npm start
- Step 4: The Prevent Display from Sleeping button does not have any functionality associated with it yet.
The powerSaveBlocker.start(type) prevents the system from entering lower-power modes. It takes in the following parameters.
- type: String This value cannot be empty. It represents the type of Blocker that you want to implement. It can assume any of the following two values:
- prevent-app-suspension: This value prevents the application from being suspended. It keeps the System active but the screens can be turned off such as Logoff operation in Windows. This value can be used when streaming audio or downloading files, etc.
- prevent-display-sleep: This value prevents the display from going to sleep. Keeps the System and the screen Active. This value can be used when streaming video, etc.
Note – prevent-display-sleep always takes higher precedence over prevent-app-suspension. In case of multiple Renderer Processes implementing different blockers, the blocker with the higher precedence will always stay in effect until the request has been resolved.
This method returns an Integer representing the blocker ID that has been assigned to the power blocker. The other Instance methods of the powerSaveBlocker module make use of this ID to carry out operations.
Note: The powerSaveBlocker does not monitor the power state changes of the System and is not to be confused with the powerMonitor module.
index.js: Add the following snippet in that file.
const electron = require(
'electron'
)
// Importing powerSaveBlocker Module from remote module
const powerSaveBlocker = electron.remote.powerSaveBlocker;
var
enter = document.getElementById(
'enter'
);
var
id = undefined
enter.addEventListener(
'click'
, () => {
id = powerSaveBlocker.start(
'prevent-display-sleep'
);
console.log(
'Request ID generated - '
, id);
console.log(
'Prevent Display Sleep is Enabled'
)
});
- type: String This value cannot be empty. It represents the type of Blocker that you want to implement. It can assume any of the following two values:
- Step 5: The Disable Blocker button does not have any functionality associated with it yet. The powerSaveBlocker.isStarted(id) and the
powerSaveBlocker.stop(id)
both take in the blocker ID integer value that was returned by the powerSaveBlocker.start() method. The powerSaveBlocker.isStarted() method returns a Boolean value signifying whether the corresponding powerSaveBlocker is started and in effect. For more detailed Information, Refer this link. The powerSaveBlocker.stop() method does not have a Return value. It simply stops the specified powerSaveBlocker in effect which is represented by the blocker ID.
index.js: Add the following snippet in that file.var
disable = document.getElementById(
'disable'
);
disable.addEventListener(
'click'
, () => {
// Checking if ID is undefined or not
if
(id && powerSaveBlocker.isStarted(id)) {
console.log(
'Prevent Display Sleep is Active'
);
powerSaveBlocker.stop(id);
console.log(
'Prevent Display Sleep is successfully disabled'
);
}
else
{
console.log(
'Prevent Display Sleep is not Active'
)
}
});
Output: