nixos-config/modules/home-manager/ricing/awesomewm/dotfiles/ui/bar/mods/task.lua
2024-07-12 18:19:30 +09:00

398 lines
9.3 KiB
Lua

local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local wibox = require("wibox")
local gears = require("gears")
local Gio = require("lgi").Gio
local helpers = require("helpers")
local beautiful = require("beautiful")
local getIcon = require("mods.getIcon")
local layout = wibox.layout.fixed.horizontal
local flexlayout = wibox.layout.flex.horizontal
local inspect = require("mods.inspect")
local M = {
metadata = {
{
count = 0,
pinned = true,
icon = getIcon(nil, "firefox", "firefox"),
id = 1,
clients = {},
class = "firefox",
exec = "firefox",
name = "firefox",
},
{
count = 0,
pinned = true,
icon = getIcon(nil, "org.wezfurlong.wezterm", "org.wezfurlong.wezterm"),
id = 2,
clients = {},
class = "org.wezfurlong.wezterm",
exec = "wezterm",
name = "wezterm",
},
{
count = 0,
pinned = true,
icon = getIcon(nil, "discord", "discord"),
id = 3,
clients = {},
class = "discord",
exec = "discord",
name = "discord",
},
{
count = 0,
pinned = true,
icon = getIcon(nil, "spotify", "spotify"),
id = 4,
clients = {},
class = "spotify",
exec = "spotify",
name = "spotify",
},
{
count = 0,
pinned = true,
icon = getIcon(nil, "steam", "steam"),
id = 4,
clients = {},
class = "steam",
exec = "steam",
name = "steam",
},
},
entries = {},
classes = { "firefox", "org.wezfurlong.wezterm", "discord", "spotify", "steam" }
}
M.widget = wibox.widget {
layout = layout,
spacing = 10,
}
M.popupWidget = wibox.widget {
layout = wibox.layout.fixed.vertical,
spacing = 10,
}
M.popup = awful.popup {
minimum_width = 240,
widget = wibox.container.background,
visible = false,
shape = helpers.rrect(5),
ontop = true,
bg = beautiful.bg
}
M.popup:setup {
widget = wibox.container.margin,
margins = 10,
M.popupWidget,
}
local removeDup = function(arr)
local hash = {}
local res = {}
for _, v in ipairs(arr) do
if (not hash[v]) then
res[#res + 1] = v -- you could print here instead of saving to result table if you wanted
hash[v] = true
end
end
return res
end
function M:getExecutable(class)
local class_1 = class:gsub("[%-]", "")
local class_2 = class:gsub("[%-]", ".")
local class_3 = class:match("(.-)-") or class
class_3 = class_3:match("(.-)%.") or class_3
class_3 = class_3:match("(.-)%s+") or class_3
local apps = Gio.AppInfo.get_all()
local possible_icon_names = { class, class_3, class_2, class_1 }
for _, app in ipairs(apps) do
local id = app:get_id():lower()
for _, possible_icon_name in ipairs(possible_icon_names) do
if id and id:find(possible_icon_name, 1, true) then
return app:get_executable()
end
end
end
return class:lower()
end
function M:showMenu(data)
local clients = data.clients
self.popup.x = mouse.coords().x - 80
self.popup.y = 1080 - 70 - (50 * (#clients + 2))
self.popupWidget:reset()
for i, j in ipairs(clients) do
local widget = wibox.widget {
{
{
{
{
markup = j.name,
font = beautiful.font .. " 12",
height = 16,
widget = wibox.widget.textbox,
},
widget = wibox.container.constraint,
width = 180,
height = 16,
},
nil,
{
markup = helpers.colorizeText("󰅖", beautiful.red),
font = beautiful.icon .. " 16",
widget = wibox.widget.textbox,
buttons = {
awful.button({}, 1, function()
j:kill()
self.popup.visible = false
end)
},
},
layout = wibox.layout.align.horizontal
},
widget = wibox.container.margin,
margins = 7,
},
buttons = {
awful.button({}, 1, function()
if j.minimized then
j.minimized = false
client.focus = j
else
j.minimized = true
end
self.popup.visible = false
end)
},
widget = wibox.container.background,
shape = helpers.rrect(4),
bg = j.minimized and beautiful.fg .. '22' or beautiful.mbg
}
M.popupWidget:connect_signal("mouse::leave", function()
self.popup.visible = false
end)
self.popupWidget:add(widget)
end
local addNew = wibox.widget {
{
{
{
{
markup = "Open New Window",
font = beautiful.font .. " 12",
widget = wibox.widget.textbox,
},
widget = wibox.container.constraint,
width = 180,
},
nil,
nil,
layout = wibox.layout.align.horizontal
},
widget = wibox.container.margin,
margins = 7,
},
buttons = {
awful.button({}, 1, function()
awful.spawn.with_shell(data.exec)
end)
},
widget = wibox.container.background,
shape = helpers.rrect(4),
bg = beautiful.mbg
}
local closeAll = wibox.widget {
{
{
{
{
markup = "Close All",
font = beautiful.font .. " 12",
widget = wibox.widget.textbox,
},
widget = wibox.container.constraint,
width = 180,
},
nil,
nil,
layout = wibox.layout.align.horizontal
},
widget = wibox.container.margin,
margins = 7,
},
buttons = {
awful.button({}, 1, function()
for i, j in ipairs(clients) do
j:kill()
end
end)
},
widget = wibox.container.background,
shape = helpers.rrect(4),
bg = beautiful.mbg
}
self.popupWidget:add(addNew)
self.popupWidget:add(closeAll)
self.popup.visible = true
end
function M:genMetadata()
local clients = mouse.screen.selected_tag and mouse.screen.selected_tag:clients() or {}
for _, j in pairs(self.metadata) do
j.count = 0
j.clients = {}
end
for _, c in ipairs(clients) do
local icon = getIcon(c, c.class, c.class)
local class = string.lower(c.class or "default")
local exe = self:getExecutable(c.class)
if helpers.inTable(self.classes, class) then
for _, j in pairs(self.metadata) do
if j.class:lower() == class:lower() then
table.insert(j.clients, c)
j.count = j.count + 1
end
end
else
table.insert(self.classes, class)
local toInsert = {
count = 1,
pinned = false,
icon = icon,
id = #self.classes + 1,
clients = { c },
class = class,
exec = exe,
name = c.name,
}
table.insert(self.metadata, toInsert)
end
for _, j in pairs(self.metadata) do
j.clients = removeDup(j.clients)
end
end
table.sort(self.metadata, function(a, b) return a.id < b.id end)
end
local function getMinimized(clients)
local a = 0
for i, j in ipairs(clients) do
if j.minimized then
a = a + 1
end
end
return a
end
function M:genIcons()
self:genMetadata()
self.widget:reset()
print(inspect(self.metadata))
for i, j in ipairs(self.metadata) do
if j.pinned == true or j.count > 0 then
local minimized = getMinimized(j.clients)
local bg = beautiful.bg
if client.focus then
if client.focus.class:lower() == j.class then
bg = beautiful.fg .. "22"
elseif j.count > 0 then
bg = beautiful.fg .. "33"
end
elseif minimized > 0 then
bg = beautiful.fg .. "33"
end
local widget = wibox.widget {
{
{
widget = wibox.widget.imagebox,
image = j.icon,
forced_height = 35,
forced_width = 35,
clip_shape = helpers.rrect(100),
resize = true,
},
widget = wibox.container.margin,
margins = 3,
},
shape = helpers.rrect(10),
widget = wibox.container.background,
bg = bg,
}
widget:buttons(gears.table.join(
awful.button({}, 1, function()
if j.count == 0 then
awful.spawn.with_shell(j.exec)
elseif j.count == 1 then
if j.clients[j.count].minimized then
j.clients[j.count].minimized = false
client.focus = j.clients[j.count]
else
j.clients[j.count].minimized = true
end
else
self:showMenu(j)
end
end),
awful.button({}, 3, function()
self:showMenu(j)
end)
))
self.widget:add(widget)
end
end
end
client.connect_signal(
"focus",
function()
M:genIcons()
end
)
client.connect_signal(
"property::minimized",
function()
M:genIcons()
end
)
client.connect_signal(
"property::maximized",
function()
M:genIcons()
end
)
client.connect_signal(
"manage",
function()
M:genIcons()
M.popup.visible = false
end
)
client.connect_signal(
"unmanage",
function()
M:genIcons()
M.popup.visible = false
end
)
tag.connect_signal("property::selected", function()
M:genIcons()
M.popup.visible = false
end)
M:genIcons()
return M