sway-tools
Version:
Some tools and a library for controlling sway
106 lines (86 loc) • 2.25 kB
text/typescript
import { Sway } from '..';
import child_process = require('child_process');
import * as lodash from 'lodash';
import { TreeNode } from '../interfaces/tree.interface';
type Entry = {
id: number;
workspace: string;
appName: string;
appTitle: string;
};
function getAppName(window: TreeNode) {
if (typeof window.app_id === 'string') {
const name = window.app_id.split('.').pop();
if (typeof name === 'string') {
return name;
}
}
if (typeof window.window_properties !== 'undefined') {
return window.window_properties.class;
}
return '???';
}
async function main() {
const sway = new Sway();
const tree = (await sway.getTree()).nodes.flatMap((node) => node.nodes);
const items: Entry[] = [];
for (const workspace of tree) {
const windows = workspace.nodes.flatMap((node) => {
if (node.nodes.length > 0) {
return node.nodes;
} else {
return node;
}
});
for (const window of windows) {
items.push({
id: window.id,
workspace: workspace.name,
appTitle: window.name,
appName: getAppName(window),
});
}
}
const maxWorkspaceLength = items
.map((item) => item.workspace.length)
.reduce((prev, curr) => {
if (prev >= curr) {
return prev;
} else {
return curr;
}
});
const maxAppTitleLength = items
.map((item) => item.appName.length)
.reduce((prev, curr) => {
if (prev >= curr) {
return prev;
} else {
return curr;
}
});
const dmenu = lodash
.sortBy(items, ['appName'])
.map(
(item) =>
`${item.workspace.padEnd(maxWorkspaceLength)} ${item.appName.padEnd(
maxAppTitleLength,
)} ${item.appTitle} (${item.id})`,
)
.join('\n');
const rofi = child_process.exec(
'rofi -dmenu -i -p "Select a Window" -format',
);
rofi.stdin.write(dmenu);
rofi.stdin.end();
let output = '';
for await (const chunk of rofi.stdout) {
output += chunk;
}
const idMatch = output.trim().match(/\([0-9]+\)$/);
if (idMatch !== null) {
const id = idMatch[0].slice(1, -1);
child_process.execSync(`swaymsg "[con_id=${id}] focus"`);
}
}
void main();