Files
switchmon/swm.js
Thomas Ruoff 9160bd1c82 major refactoring - well almost a rewrite
* changed the output of --list command to be more sane
* use promises and simplify API of swm.js
* simplify swm.js a bit
2019-11-15 00:25:31 +01:00

131 lines
3.3 KiB
JavaScript

'use strict';
const xrandrParse = require('xrandr-parse');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function getDevices() {
const { stdout } = await exec('xrandr');
return xrandrParse(stdout);
}
function sortDeviceKeys(devices) {
return (keyA, keyB) => {
const aConnected = devices[keyA].connected;
const bConnected = devices[keyB].connected;
if (!aConnected && bConnected) {
return 1;
}
if (aConnected && !bConnected) {
return -1;
}
return 0;
};
}
function getSelectedAndConnectedDevices(selectedDevices, devices) {
const selectedAndConnected = selectedDevices.filter(deviceKey => {
if (!devices[deviceKey]) {
throw new Error(`${deviceKey} is not a valid monitor`);
}
return devices[deviceKey].connected;
});
if (selectedDevices.length && !selectedAndConnected.length) {
throw new Error('Non of the given monitors are connected, aborting...');
}
return selectedAndConnected;
}
function getXrandrOptions(
deviceKeys,
devices,
positionParameter = '--right-of'
) {
return deviceKeys.reduce((acc, deviceKey, currentIndex) => {
const device = devices[deviceKey];
const monitorOptions = [`--output ${deviceKey}`];
monitorOptions.push('--auto');
if (currentIndex > 0 && device.connected) {
monitorOptions.push(
`${positionParameter} ${deviceKeys[currentIndex - 1]}`
);
}
return [acc, ...monitorOptions].join(' ');
}, '');
}
async function generateXrandrOptions(
selectedDevices = [],
positionParameter = '--right-of'
) {
const devices = await getDevices();
const selectedAndConnected = getSelectedAndConnectedDevices(
selectedDevices,
devices
);
if (selectedDevices.length && !selectedAndConnected.length) {
throw new Error('Non of the given monitors are connected, aborting...');
}
console.log(
'Switching on',
selectedAndConnected.length
? selectedAndConnected.join(', ')
: 'all connected monitors'
);
const orderedDeviceKeys = [
...selectedAndConnected,
...Object.keys(devices)
.filter(key => !selectedAndConnected.includes(key))
.sort(sortDeviceKeys(devices))
];
const xrandrOptions = getXrandrOptions(
orderedDeviceKeys,
devices,
positionParameter
);
return xrandrOptions;
}
async function printDevices() {
const devices = await getDevices();
const connectedMonitors = Object.keys(devices).filter(
key => devices[key].connected
);
const disconnectedMonitors = Object.keys(devices).filter(
key => !devices[key].connected
);
console.log(`Connected Monitors: ${connectedMonitors.join(', ')}`);
console.log(`Disconnected Monitors: ${disconnectedMonitors.join(', ')}`);
}
async function activate(selectedMonitors, postCmd) {
const xrandrOptions = await generateXrandrOptions(selectedMonitors);
await exec(`xrandr ${xrandrOptions}`);
if (postCmd) {
await exec(postCmd);
}
}
module.exports.printDevices = printDevices;
module.exports.activate = activate;