Managing display properties

The preceding section described using a built-in Electron API to hook into the some of the operating system components. However, what if the Electron does not provide an API to implement your requirement. You should search for a corresponding npm module in the npm registry. In this section, let's check how we can control the display properties of a machine from your Electron application. In a real-world scenario, it's very rare to have this type of requirement. However, this will give you a detailed description about dealing with machine components. The operating system itself provides a lot of utility functions that can be used to interact with crucial internal components. These utilities can be executed via a terminal or command-line prompt. 

If an operating system provides a utility program and the application user have access to it, then you can easily control that utility using Node.js shell. Let's take a look at the display properties example here. The main challenge with this example is each operating systems has different ways to manage the native hardware and OS components. Also, each platform uses different ways to implement the same functionality, which will not work on another platform. So, you need to implement the functionality for each platform that you are targeting to support. Here, let's start with the Windows platform.

Windows command line provides a command-line utility that can be used to control the power system settings. You can configure computer's hibernate and standby modes. To get more details about powercfg utility, visit https://technet.microsoft.com/en-us/library/cc748940(v=ws.10).aspx.

Running the powercfg -q command will give you the following output in you command-line prompt:

This list down each and every power setting and its GUID. In this example, we need to get these GUIDs in order to manipulate power settings. Create a new JavaScript file called power-config.js and add the following method to it. Here, we are just going to deal with the display brightness. The powercfg tools are quite powerful to deal with a lot of things in the power settings:

function adjustBrightnessWindows(brightness, callback) {
let guid;
let subGroup;
let powerSettings;
}

Node.js' exec method can be used here to execute the powercfg command from our application. This method will give you the output of the command in a buffer, and the end users can consume it as they want. Once the output is finished, the callback function will be called with the desired result. Add the following line to the preceding method:

exec('powercfg -q', (error, stdout, stderror) => {
if(!error) {
let regExp = /([a-z-0-9]+)sD+$/;
let splitOutput = stdout.split('rn');
guid = regExp.exec(splitOutput[0])[1];

for (var i = 0; i < splitOutput.length; i++) {
if(splitOutput[i].match(/(Display)$/)) {
subgroup = regExp.exec(splitOutput[i])[1];
}
else if(splitOutput[i].match(/(Displaysbrightness)$/)) {
//The powerSetting is derived from the output named Display
powerSetting = regExp.exec(splitOutput[i])[1];
}
}
}
});

The preceding code loops each line of the output received from the powercfg command and extracts the GUID, power settings, and subgroup of each item from the output. Once we have the GUID and other information for the display properties, we can adjust the values according to that. Once we have all these values, you can use the following command to adjust the brightness of your machine:

powercfg -SetAcValueIndex  GUID subgroup powerSetting brightness

This command will set the display brightness to the passed value when the power is plugged in. Let's convert this command into the Node.js code:

let command = `powercfg -SetAcValueIndex ${GUID} ${subgroup} ${powerSetting} ${brightness}`;

exec(command,function(err,out,stderror) {
if(err) throw err;
});

Next, add the same brightness settings for DC Power plan settings. The command is almost the same, but the argument that we need to pass has some changes:

let dcCommand = `powercfg -SetDcValueIndex ${guid} ${subgroup} ${powerSetting} ${brightness}`;

exec(dcCommand,function(err,out,stderror) {
if(err) throw err;
});

Here, the code is same, and we execute Windows shell command using the node exec function. The changed values are not yet persisted as the current system setting. We need to do it manually using the following code:

// Set the modified power plan as the current system plan
exec('powercfg -S' + ' ' + GUID, function(err, out, stderror) {
if(err) throw err;
if(callback)
callback();
return true;
});

That's it for setting the display properties in the Windows platform. There are some other ways to manipulate the Windows platform's native properties. You can use something like we have done in this using standard platform utilities. You can create custom native node add-ons using C++. Also, on Windows, you can use the .NET runtime environment features using the Node.js library, Edge.js. The final code for the Windows platform should be as follows:

function windows(brightness, callback) {
let GUID;
let subgroup;
let powerSetting;

exec('powercfg -q', function(error, stdout, stderr) {
if(!error) {
let regExp = /([a-z-0-9]+)sD+$/;
let splitOutput = stdout.split('rn');
GUID = regExp.exec(splitOutput[0])[1];

for(let i = 0; i<splitOutput.length; i++) {
if(splitOutput[i].match(/(Display)$/)) {
subgroup = regExp.exec(splitOutput[i])[1];
} else if(splitOutput[i].match(/(Displaysbrightness)$/))
{
powerSetting = regExp.exec(splitOutput[i])[1];
}
}

let command = `powercfg -SetAcValueIndex ${GUID} ${subgroup}
${powerSetting} ${brightness}`;
exec(command, function(err, out, stderror) {
if(err) throw err;
let dcCommand = `powercfg -SetDcValueIndex ${GUID}
${subgroup} ${powerSetting} ${brightness}`;
exec(dcCommand, function(err, stdout, stderr) {
if(err) throw err;
exec('powercfg -S' + ' ' + GUID, function(err, out,
stderror) {
if(err) throw err;
if(callback) callback();
return true;
});
});
});
} else{
throw error;
}
});
}

The powercfg utility provides a number of other features. You can use this utility in the same manner that we have used above. Next, let's add the same functionality to target the Linux machine. As we are implementing a custom functionality that does not support natively by the Electron, we need to implement it for each platform that we are going to target.

Add the following function to the code to manipulate the display properties in the Linux platform:

function linux(brightness, callback) {
// Enumerate the backlight devices...
fs.readdir('/sys/class/backlight', function(err, brightnessDevices) {
if(err) {
console.error('Error while listing brightness devices. Maybe you need superuser privileges to run this script?');
throw err;
}

let devicePath = '/sys/class/backlight/' + brightnessDevices[0];
// Read the maximum for the first device
fs.readFile(devicePath + '/max_brightness', function(err, maxBrightness) {
maxBrightness = parseInt(maxBrightness, 10);
if(err) {
console.error('Error while reading maximum brightness. Maybe you need superuser privileges to run this script?');
throw err;
}

// Turn percent into the actual value we need
let brightnessValue = Math.floor(brightness / 100 * maxBrightness);

// Write out new value
fs.createWriteStream(devicePath + '/brightness')
.on('end', callback)
.write(new Buffer(brightnessValue.toString()));
});
});
}

Screen brightness is tricky to control. The brightness of the screen backlight is adjusted by setting the power level of the backlight LEDs or cathode. The power level can be often controlled using the ACPI kernel module for video. An interface to this module is provided via the folder is sysfs at sys/class/backlight. In a Linux machine, most of the system configurations can be changed using filesystem module of Node.js. As the platform provides the configurations in simple files with admin rights, you need to read the current configuration and write it back with the new values.

In this example, we read the backlight configuration from the /sys/class/backlight directory using the Node.js fs module and write the new value in the same manner.

For macOS, let's use a third-party npm module called osx-brightness. Add it to the project using npm:

npm install --save osx-brightness

This is a small library that provides access to the display brightness properties. You can change the current settings value with the following code:

const osxBrightness = require('osx-brightness');
function mac() {
osxBrightness.set(0.75).then(() => {
console.log('Changed brightness to 75%');
});
}

The preceding code increases the display brightness by 75 percent. Now, we have the code for three major platforms for the same feature. Let's combine it all together and plug it into the Electron renderer process. 

Add the following method to the file and export it to be accessed from other node modules, as follows:

const os = require('os');

function adjustBrightness(brightness, callback) {
switch (os.platform()) {
case 'darwin':
mac(brightness/100, callback);
break;
case 'linux':
linux(brightness, callback);
break;
case 'win32':
windows(brightness, callback);
break;
default:
throw new Error('OS is not recognized or is supported');
break;
}
}

module.exports = adjustBrightness;

This simply recognizes the current operating system and executes corresponding methods. The next step is to attach this method to the renderer process. The module can be imported into the renderer process or the rendered page using standard Node.js require method. As we have the Node.js context available inside the web page and this code is purely based on the Node.js APIs, you can execute this from both main process and renderer process.

Add a slider field into the HTML page, and add the change event to the field that will change the display brightness; the HTML looks as follows:

<!DOCTYPE html />
<html>
<head>
<title>Electron power config manager</title>
<script type="text/javascript">
const powerConfig = require('./power-config');
window.onload = function() {
let slider = document.getElementById('slider');
slider.onchange = (e) => {
powerConfig(slider.value, () => {
console.log('Brightness changed to ' + slider.value);
});
};
}
</script>
</head>
<body>

<label for="slider">Change the brightness</label>
<input type="range" id="slider" />

</body>
</html>

The display brightness can be adjusted by moving the input range. In this section, we discussed manipulating native operating system components from an Electron application. We haven't discussed anything special about the Electron. Instead, we went through the practical example of operating system integration. The similar methodology can be used if you need to implement any additional features or functionality in your Electron application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.21.47