180 lines
6 KiB
Lua
180 lines
6 KiB
Lua
local constants = require 'constants'
|
|
local settings = require 'config.settings'
|
|
local utils = require 'utils'
|
|
|
|
local spaces = {}
|
|
local paddings = {}
|
|
local focusedWorkspace = nil
|
|
|
|
local swapWatcher = sbar.add('item', {
|
|
drawing = false,
|
|
updates = true,
|
|
})
|
|
|
|
local currentWorkspaceWatcher = sbar.add('item', {
|
|
drawing = false,
|
|
updates = true,
|
|
})
|
|
|
|
-- Modify this file with Visual Studio Code - at least vim does have problems with the icons
|
|
-- copy "Icons" from the nerd fonts cheat sheet and replace icon and name accordingly below
|
|
-- https://www.nerdfonts.com/cheat-sheet
|
|
local spaceConfigs <const> = {
|
|
['1'] = { icon = '', name = 'Main' },
|
|
['2'] = { icon = ' ', name = 'Dev' },
|
|
['3'] = { icon = '', name = 'AI' },
|
|
['4'] = { icon = '', name = '' },
|
|
['5'] = { icon = '', name = 'Misc' },
|
|
['6'] = { icon = '', name = 'Library' },
|
|
['7'] = { icon = '', name = 'Music' },
|
|
['8'] = { icon = '', name = 'Mail' },
|
|
['9'] = { icon = '', name = 'Chat' },
|
|
['10'] = { icon = '', name = 'Browser' },
|
|
['t'] = { icon = '', name = 'Meeting' },
|
|
}
|
|
|
|
-- Track which workspaces have windows
|
|
local workspaceHasWindows = {}
|
|
|
|
local updateWorkspaceVisibility = utils.coro.async(function()
|
|
local output = utils.coro.await(utils.coro.exec(constants.aerospace_cmd .. " list-windows --all --format '%{workspace}'"))
|
|
|
|
-- Reset all
|
|
for ws, _ in pairs(workspaceHasWindows) do
|
|
workspaceHasWindows[ws] = false
|
|
end
|
|
|
|
-- Mark workspaces that have windows
|
|
if output then
|
|
for ws in output:gmatch '[^\r\n]+' do
|
|
workspaceHasWindows[ws] = true
|
|
end
|
|
end
|
|
|
|
-- Update visibility for each space
|
|
for workspaceName, _ in pairs(spaceConfigs) do
|
|
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
|
local space = spaces[spaceName]
|
|
local padding = paddings[spaceName]
|
|
|
|
if space then
|
|
local hasWindows = workspaceHasWindows[workspaceName] == true
|
|
local isFocused = focusedWorkspace == workspaceName
|
|
local shouldShow = hasWindows or isFocused
|
|
|
|
space:set { drawing = shouldShow }
|
|
if padding then padding:set { drawing = shouldShow } end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function selectCurrentWorkspace(focusedWorkspaceName)
|
|
focusedWorkspace = focusedWorkspaceName
|
|
|
|
for workspaceName, _ in pairs(spaceConfigs) do
|
|
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
|
local item = spaces[spaceName]
|
|
local padding = paddings[spaceName]
|
|
if item ~= nil then
|
|
local isSelected = workspaceName == focusedWorkspaceName
|
|
local hasWindows = workspaceHasWindows[workspaceName] == true
|
|
local shouldShow = hasWindows or isSelected
|
|
|
|
-- Show/hide based on windows or focus
|
|
item:set {
|
|
drawing = shouldShow,
|
|
icon = { color = isSelected and settings.colors.bg1 or settings.colors.white },
|
|
label = { color = isSelected and settings.colors.bg1 or settings.colors.white },
|
|
background = { color = isSelected and settings.colors.white or settings.colors.bg1 },
|
|
}
|
|
if padding then padding:set { drawing = shouldShow } end
|
|
end
|
|
end
|
|
|
|
updateWorkspaceVisibility()
|
|
sbar.trigger(constants.events.UPDATE_WINDOWS)
|
|
end
|
|
|
|
local findAndSelectCurrentWorkspace = utils.coro.async(function()
|
|
local focusedWorkspaceOutput = utils.coro.await(utils.coro.exec(constants.aerospace.GET_CURRENT_WORKSPACE))
|
|
if focusedWorkspaceOutput then
|
|
local focusedWorkspaceName = focusedWorkspaceOutput:match '[^\r\n]+'
|
|
selectCurrentWorkspace(focusedWorkspaceName)
|
|
end
|
|
end)
|
|
|
|
local function addWorkspaceItem(workspaceName)
|
|
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
|
local spaceConfig = spaceConfigs[workspaceName]
|
|
|
|
-- Skip workspaces without a config entry
|
|
if not spaceConfig then return end
|
|
|
|
local hasIcon = spaceConfig.icon and spaceConfig.icon ~= ''
|
|
local hasName = spaceConfig.name and spaceConfig.name ~= ''
|
|
local icon = hasIcon and spaceConfig.icon or workspaceName
|
|
local name = hasName and spaceConfig.name or workspaceName
|
|
local useBold = not hasIcon
|
|
local fontStyle = useBold and settings.fonts.styles.bold or settings.fonts.styles.regular
|
|
local iconFont = settings.fonts.text .. ':' .. fontStyle .. ':' .. settings.dimens.text.icon
|
|
|
|
spaces[spaceName] = sbar.add('item', spaceName, {
|
|
drawing = false, -- start hidden, will show if has windows or is focused
|
|
label = {
|
|
width = 0,
|
|
padding_left = 0,
|
|
string = name,
|
|
y_offset = 1,
|
|
},
|
|
icon = {
|
|
string = icon,
|
|
font = iconFont,
|
|
color = settings.colors.white,
|
|
y_offset = 1,
|
|
},
|
|
background = {
|
|
color = settings.colors.bg1,
|
|
},
|
|
click_script = constants.aerospace_cmd .. ' workspace ' .. workspaceName,
|
|
})
|
|
|
|
spaces[spaceName]:subscribe('mouse.entered', function(env)
|
|
sbar.animate('tanh', 30, function() spaces[spaceName]:set { label = { width = 'dynamic' } } end)
|
|
end)
|
|
|
|
spaces[spaceName]:subscribe('mouse.exited', function(env)
|
|
sbar.animate('tanh', 30, function() spaces[spaceName]:set { label = { width = 0 } } end)
|
|
end)
|
|
|
|
paddings[spaceName] = sbar.add('item', spaceName .. '.padding', {
|
|
drawing = false,
|
|
width = settings.dimens.padding.label,
|
|
})
|
|
end
|
|
|
|
local createWorkspaces = utils.coro.async(function()
|
|
local workspacesOutput = utils.coro.await(utils.coro.exec(constants.aerospace.LIST_ALL_WORKSPACES))
|
|
if workspacesOutput then
|
|
for workspaceName in workspacesOutput:gmatch '[^\r\n]+' do
|
|
addWorkspaceItem(workspaceName)
|
|
end
|
|
end
|
|
|
|
findAndSelectCurrentWorkspace()
|
|
end)
|
|
|
|
swapWatcher:subscribe(constants.events.SWAP_MENU_AND_SPACES, function(env)
|
|
local isShowingSpaces = env.isShowingMenu == 'off' and true or false
|
|
if isShowingSpaces then
|
|
updateWorkspaceVisibility()
|
|
else
|
|
sbar.set('/' .. constants.items.SPACES .. '\\..*/', { drawing = false })
|
|
end
|
|
end)
|
|
|
|
currentWorkspaceWatcher:subscribe(constants.events.AEROSPACE_WORKSPACE_CHANGED, function(env) selectCurrentWorkspace(env.FOCUSED_WORKSPACE) end)
|
|
|
|
-- Also update on window changes
|
|
currentWorkspaceWatcher:subscribe('front_app_switched', function(env) updateWorkspaceVisibility() end)
|
|
|
|
createWorkspaces()
|