Created
February 23, 2024 04:54
-
-
Save selfire1/e8d1839cc993b9636d39d3792bc02b67 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env zx | |
// yabai message | |
const ym = async (arg) => await $`yabai -m ${arg.split(" ")}`; | |
const hideAllApps = async () => { | |
await $`osascript -e 'tell application "System Events" to set visible of every process whose visible is true to false'`; | |
}; | |
const laptop = 1; | |
const external = 2; | |
const config = { | |
kitty: { | |
display: external, | |
index: 2, | |
}, | |
Arc: { | |
display: external, | |
index: 1, | |
}, | |
Slack: { | |
display: laptop, | |
index: 2, | |
}, | |
ClickUp: { | |
display: laptop, | |
index: 1, | |
}, | |
}; | |
const activateApps = async (appNames) => { | |
appNames.forEach(async (app) => { | |
await $`osascript -e 'tell application "${app}" to activate'`; | |
}); | |
}; | |
const getAppsByDisplaySorted = () => { | |
// Sorting based on 'display' and then 'index' | |
const arr = []; | |
let entries = Object.entries(config); | |
entries = entries.sort((a, b) => a[1].display - b[1].display); | |
entries.forEach(([key, value]) => { | |
const item = { name: key, idx: value.index }; | |
if (arr.length < value.display) { | |
arr.push([item]); | |
return; | |
} | |
arr[value.display - 1].push(item); | |
}); | |
return arr.map((el) => el.sort((a, b) => a.idx - b.idx).map((el) => el.name)); | |
}; | |
const getAppWindowId = async (app) => { | |
const output = | |
await $`yabai -m query --windows | jq '.[] | select(.app == "${app}").id'`; | |
return output.stdout.trim().replaceAll("\n", ""); | |
}; | |
const setSpacesToLayout = async (allSpaces, index, layout) => { | |
const spaces = allSpaces.filter((el) => el.index === index); | |
spaces.forEach(async (el) => { | |
await ym(`space ${el.index} --layout ${layout}`); | |
}); | |
}; | |
const moveWindowFurthestInDirection = async (windowId, direction) => { | |
for (let i = 0; i < 5; i++) { | |
try { | |
await ym(`window ${windowId} --warp ${direction}`); | |
} catch (e) { | |
break; | |
} | |
} | |
}; | |
const moveAppsIntoLocation = async (apps) => { | |
await apps.forEach(async (appsOnThisDisplay, idx) => { | |
// reverse so that the app with the first index ends in the top spot | |
const displayIndex = idx + 1; | |
const reversed = appsOnThisDisplay.reverse(); | |
await reversed.forEach(async (app) => { | |
const appWindowId = await getAppWindowId(app); | |
await ym(`window ${appWindowId} --display ${displayIndex}`); | |
if (displayIndex === external) { | |
await moveWindowFurthestInDirection(appWindowId, "west"); | |
} | |
}); | |
}); | |
}; | |
await hideAllApps(); | |
await activateApps(Object.keys(config)); | |
const spacesRaw = await ym("query --spaces"); | |
const spaces = JSON.parse(spacesRaw); | |
await setSpacesToLayout(spaces, laptop, "stack"); | |
await setSpacesToLayout(spaces, external, "bsp"); | |
const sortedApps = getAppsByDisplaySorted(); | |
await moveAppsIntoLocation(sortedApps); | |
await ym("display --focus last"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment