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

456 lines
13 KiB
Lua

local awful = require("awful")
local helpers = require("helpers")
local wibox = require("wibox")
local gears = require("gears")
local popup = require("ui.desktop.popup")
local json = require("mods.json")
local beautiful = require("beautiful")
local data = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/settings.json")
local inspect = require("mods.inspect")
local dpi = beautiful.xresources.apply_dpi
local appicons = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/settings.json").iconTheme .. "/"
local foldericons = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/settings.json").iconTheme .."/places/"
local grid = wibox.widget {
forced_num_rows = 14,
forced_num_cols = 19,
orientation = "horizontal",
layout = wibox.layout.grid
}
local manual = wibox.layout {
layout = wibox.layout.manual
}
local icons = {
["lua"] = "lua",
["py"] = "python",
["rs"] = "rust",
["html"] = "html",
["c"] = "c",
["c++"] = "c++",
["js"] = "javascript",
["hs"] = "haskell",
['go'] = "go",
["php"] = "php",
["rb"] = "ruby",
["md"] = "markdown",
["ts"] = "typescript",
["scss"] = "sass",
["sass"] = "sass",
["java"] = "java",
}
local desktopdisplay = wibox {
visible = data.showDesktopIcons,
ontop = false,
bg = beautiful.bg .. '00',
type = "desktop",
screen = s,
widget = wibox.widget {
{
grid,
margins = dpi(20),
widget = wibox.container.margin
},
manual,
layout = wibox.layout.stack
}
}
awful.placement.maximize(desktopdisplay)
local function gen()
local shortcuts = {}
local folders = {}
local files = {}
local entries = {}
table.insert(entries,
{ icon = appicons .. "places/trashcan_empty.svg", label = "Trash", exec = "nemo trash:/", type = "general" })
-- table.insert(entries,
-- {
-- icon = gears.filesystem.get_configuration_dir() .. "theme/assets/tsukkisaidmetoaddthis.png",
-- label = beautiful.user:lower(),
-- exec = "nemo /home/" .. beautiful.user:lower(),
-- type = "general"
-- })
for entry in io.popen([[ls ~/Desktop | sed '']]):lines() do
local label = entry
local exec = nil
local icon = appicons .. "mimetypes/text-x-generic.svg"
local ext = label:match("^.+(%..+)$")
if ext == ".desktop" then
for line in io.popen("cat ~/Desktop/'" .. entry .. "'"):lines() do
if line:match("Name=") and label == entry then
label = line:gsub("Name=", "")
end
if line:match("Exec=") and exec == nil then
local cmd = line:gsub("Exec=", "")
exec = cmd
end
if line:match("CustomIcon=") then
icon = line:gsub("CustomIcon=", "")
elseif line:match("Icon=") then
icon = appicons .. "apps/" .. line:gsub("Icon=", "") .. ".svg"
end
end
table.insert(entries, { icon = icon, label = label, exec = exec, type = "shortcut" })
elseif os.execute("cd ~/Desktop/'" .. entry .. "'") then
icon = foldericons .. "/folder.svg"
exec = "nemo" .. " Desktop/'" .. entry .. "'"
table.insert(entries, { icon = icon, label = label, exec = exec, type = "folder" })
elseif os.execute("wc -c < ~/Desktop/'" .. entry .. "'") then
icon = appicons .. "mimetypes/application-x-zerosize.svg"
exec = "wezterm -e nvim" .. " ~/Desktop/'" .. entry .. "'"
if string.match(entry, "%.") then
local extenstion = helpers.split(entry, ".")
extenstion = extenstion[#extenstion]
if extenstion == "jpg" or extenstion == "jpeg" or extenstion == "tiff" or extenstion == "png" or extenstion == "webp" or extenstion == "svg" then
if extenstion == "jpg" then
icon = appicons .. "mimetypes/jpg.svg"
else
icon = appicons .. "mimetypes/image-" .. extenstion .. ".svg"
end
exec = "feh '~/Desktop/" .. entry .. "'"
elseif extenstion == "mp4" or extenstion == "avif" or extenstion == "webm" or extenstion == "mkv" or extenstion == "mov" then
icon = appicons .. "mimetypes/media-video.svg"
elseif extenstion == "mp3" or extenstion == "wav" or extenstion == "flac" or extenstion == "aiff" then
icon = appicons .. "mimetypes/media-audio.svg"
elseif icons[extenstion] ~= nil then
icon = appicons .. "mimetypes/text-x-" .. icons[extenstion] .. ".svg"
end
end
table.insert(entries, { icon = icon, label = label, exec = exec, type = 'file' })
else
exec = "xdg-open " .. os.getenv("HOME") .. "/Desktop/'" .. label .. "'"
table.insert(entries, { icon = icon, label = label, exec = exec, type = 'file' })
end
end
return entries
end
local function save()
layout = {}
for i, widget in ipairs(grid.children) do
local pos = grid:get_widget_position(widget)
layout[i] = {
row = pos.row,
col = pos.col,
widget = {
icon = widget.icon,
label = widget.label,
exec = widget.exec,
type = widget.type,
}
}
end
local w = assert(io.open(".cache/awesome/json/desktop.json", "w"))
w:write(json.encode(layout, nil, { pretty = true, indent = " ", align_keys = false, array_newline = true }))
w:close()
end
local function gridindexat(y, x)
local margin = dpi(30)
local cellwidth, cellheight = dpi(115), dpi(105)
local row = math.ceil((y - margin) / cellheight)
row = math.min(row, 8)
row = math.max(row, 1)
local col = math.ceil((x - margin) / cellwidth)
col = math.min(col, 16)
col = math.max(col, 1)
return row, col
end
local function createicon(icon, label, exec, ty)
local widget = wibox.widget {
{
{
{
image = icon,
halign = "center",
widget = wibox.widget.imagebox
},
strategy = "exact",
width = dpi(50),
height = dpi(40),
widget = wibox.container.constraint
},
{
{
{
markup = helpers.colorizeText(label, beautiful.fg),
valign = "top",
font = beautiful.sans .. " 11",
align = "center",
widget = wibox.widget.textbox
},
margins = dpi(5),
widget = wibox.container.margin
},
strategy = "max",
width = dpi(100),
height = dpi(50),
widget = wibox.container.constraint
},
spacing = dpi(5),
layout = wibox.layout.fixed.vertical
},
icon = icon,
label = label,
exec = exec,
type = ty,
forced_width = dpi(115),
forced_height = dpi(105),
margins = dpi(10),
widget = wibox.container.margin
}
local iconmenu = awful.menu({
items = {
{ "Open", exec },
{ "Delete", function()
awful.spawn.with_shell("rm -rf " .. os.getenv("HOME") .. "/Desktop/'" .. label .. "'")
end },
}
})
awesome.connect_signal("iconmenu::hide", function()
iconmenu:hide()
end)
widget:connect_signal("button::press", function(_, _, _, button)
if not mousegrabber.isrunning() then
local heldwidget = wibox.widget {
{
{
image = icon,
opacity = 0.5,
halign = "center",
widget = wibox.widget.imagebox
},
strategy = "exact",
width = dpi(50),
height = dpi(50),
widget = wibox.container.constraint
},
{
{
{
text = label,
opacity = 0.5,
valign = "top",
align = "center",
widget = wibox.widget.textbox
},
margins = dpi(5),
widget = wibox.container.margin
},
strategy = "max",
width = dpi(100),
height = dpi(50),
widget = wibox.container.constraint
},
forced_height = dpi(105),
forced_width = dpi(100),
spacing = dpi(5),
visible = false,
layout = wibox.layout.fixed.vertical
}
local startpos = mouse.coords()
heldwidget.point = { x = startpos.x, y = startpos.y }
local oldpos = grid:get_widget_position(widget)
manual:add(heldwidget)
mousegrabber.run(function(mouse)
if (math.abs(mouse.x - startpos.x) > 10 or
math.abs(mouse.y - startpos.y) > 10) and
mouse.buttons[1] then
grid:remove(widget)
heldwidget.visible = true
manual:move_widget(heldwidget, {
x = mouse.x - dpi(50),
y = mouse.y - dpi(50)
})
end
if not mouse.buttons[1] then
if button == 1 then
if heldwidget.visible then
heldwidget.visible = false
local newrow, newcol = gridindexat(
mouse.y,
mouse.x
)
if not grid:get_widgets_at(newrow, newcol) then
grid:add_widget_at(widget, newrow, newcol)
save()
else
local d = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/desktop.json")
local elem
for _, j in ipairs(d) do
if j.row == newrow and j.col == newcol then
elem = j
break
end
end
if elem.widget.exec:find("nemo Desktop") then
if exec ~= "Trash" then
os.execute("mv ~/Desktop/'" .. label .. "' ~/Desktop/'" .. elem.widget.label .. "'/'" .. label .. "'")
end
elseif elem.widget.exec:find("nemo trash:/") then
if exec ~= "Trash" then
os.execute("trash ~/Desktop/'" .. label .. "'")
end
else
grid:add_widget_at(widget, oldpos.row, oldpos.col)
end
end
else
awful.spawn.with_shell(exec)
manual:reset()
end
mousegrabber.stop()
elseif button == 3 then
awesome.emit_signal("iconmenu::hide")
iconmenu:toggle()
mousegrabber.stop()
end
end
return mouse.buttons[1]
end, "hand2")
end
end)
return widget
end
local function load()
local layoutfile = gears.filesystem.get_cache_dir() .. 'json/desktop.json'
if not gears.filesystem.file_readable(layoutfile) then
local entries = gen()
for _, entry in ipairs(entries) do
grid:add(createicon(entry.icon, entry.label, entry.exec, entry.type))
end
save()
return
end
local awmmenu = {
{ "Restart", awesome.restart }
}
local createmenu = {
{ "File", function()
local filename = "New File"
local filepath = os.getenv("HOME") .. "/Desktop/" .. filename
local i = 1
while gears.filesystem.file_readable(filepath) do
filename = "New File " .. "(" .. i .. ")"
filepath = os.getenv("HOME") .. "/Desktop/" .. filename
i = i + 1
end
awful.spawn.with_shell("touch '" .. filepath .. "'")
end },
{ "Folder", function()
local foldername = "New Folder"
local folderpath = os.getenv("HOME") .. "/Desktop/" .. foldername
local i = 1
while gears.filesystem.dir_readable(folderpath) do
foldername = "New Folder " .. "(" .. i .. ")"
folderpath = os.getenv("HOME") .. "/Desktop/" .. foldername
i = i + 1
end
gears.filesystem.make_directories(folderpath)
end }
}
manual:buttons {
awful.button({}, 1, function()
awesome.emit_signal("iconmenu::hide")
awesome.emit_signal("close::menu")
end),
awful.button({}, 3, function()
if mouse.current_widgets[4] == manual then
awesome.emit_signal("iconmenu::hide")
awesome.emit_signal("toggle::menu")
end
end)
}
local r = assert(io.open(".cache/awesome/json/desktop.json", "rb"))
local t = r:read("*all")
r:close()
local layout = json.decode(t)
for _, entry in ipairs(layout) do
grid:add_widget_at(createicon(entry.widget.icon, entry.widget.label, entry.widget.exec, entry.type), entry.row,
entry.col)
end
end
load()
awesome.connect_signal("signal::desktop", function(type)
local entries = gen()
local check = false
if type == add then
for _, entry in ipairs(entries) do
for _, widget in ipairs(grid.children) do
if entry.label == widget.label then
check = true
end
end
if check == false then
grid:add(createicon(entry.icon, entry.label, entry.exec, entry.type))
end
check = false
end
end
if type == remove then
for _, widget in ipairs(grid.children) do
for _, entry in ipairs(entries) do
if entry.label == widget.label then
check = true
end
end
if check == false then
grid:remove(widget)
end
check = false
end
end
save()
end)
local subscribe = [[
bash -c "
while (inotifywait -m -e close_write -e delete -e create -e moved_from $HOME/Desktop/ -q) do echo; done
"]]
awful.spawn.easy_async_with_shell(
"ps x | grep \"inotifywait -m -e close_write -e delete -e create -e moved_from $HOME/Desktop/ -q\" | awk '{print $1}' | xargs kill",
function()
awful.spawn.with_line_callback(subscribe, {
stdout = function(l)
awesome.emit_signal("signal::desktop")
end
})
end)