mirror of
https://github.com/tomru/switchmon.git
synced 2026-03-03 06:27:23 +01:00
* changed the output of --list command to be more sane * use promises and simplify API of swm.js * simplify swm.js a bit
131 lines
3.3 KiB
JavaScript
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;
|