* feat!: add W Engine plugin * feat!: add en translation * fix: rm useless line * feat!: add preview window in a pannel * fix: rm no dependencies tools * feat!: update thumbnail with new image * feat: add screen choose with selector and add id check for warn string command folder * docs: add dependencies on toml and read me * fix: rm pkill and use kill * feat!: add multiple path check, default output, select where set wallpaper * feat!: rm debug notif * docs: add new action documentation * feat!: add new service for good restart (pkill all instance linux-wallpaper and rm all tmp file created by w engine) * feat!: add check if pid is a linux-wallpaper instance * docs: add depedencie and new entries * feat!: support personnal path with json load * docs: add docs for custom path * feat!: use new api function for show all wallpaper * fix: rm useless notify
263 lines
6.4 KiB
Luau
263 lines
6.4 KiB
Luau
--!nonstrict
|
|
-- W-Engine panel — picks a Wallpaper Engine workshop item and applies it via
|
|
-- linux-wallpaperengine.
|
|
|
|
-- Local variable
|
|
|
|
wallpaperPath = {"~/.steam/steam/steamapps/workshop/content/431960/",
|
|
"~/.local/share/Steam/steamapps/workshop/content/431960/",
|
|
"~/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content/431960/",
|
|
"~/snap/steam/common/.local/share/Steam/steamapps/workshop/content/431960/",
|
|
"~/snap/steam/common/.local/share/steam/steamapps/workshop/content/431960/"}
|
|
wallpaperPathSelected = nil
|
|
|
|
local pickSlots = {}
|
|
local columns = 4
|
|
local previewWidth = 180
|
|
local previewHeight = 100
|
|
|
|
local outputFinalList = {}
|
|
local outputSelectedName = nil
|
|
local lastOutputUse = nil
|
|
|
|
local pidList: { killSystem } = {}
|
|
|
|
-- load personnal path
|
|
|
|
local dir = noctalia.pluginDataDir()
|
|
local path = dir .. "/data.json"
|
|
local raw = noctalia.readFile(path)
|
|
if raw then
|
|
local data = noctalia.json.decode(raw)
|
|
if data and data.personnalPath then
|
|
for _, p in ipairs(data.personnalPath) do
|
|
table.insert(wallpaperPath, p)
|
|
end
|
|
end
|
|
end
|
|
|
|
--
|
|
type Wallpaper = {
|
|
nb: string,
|
|
name: string,
|
|
preview: string,
|
|
}
|
|
|
|
type killSystem = {
|
|
pid: number,
|
|
output: string,
|
|
}
|
|
|
|
function tr(key, subst)
|
|
if subst then
|
|
return noctalia.tr(key, subst)
|
|
end
|
|
return noctalia.tr(key)
|
|
end
|
|
|
|
function takeWallpaper()
|
|
local wallpaper: { Wallpaper } = {}
|
|
|
|
for count = 1, #wallpaperPath, 1 do
|
|
if noctalia.listDir(wallpaperPath[count]) then
|
|
wallpaperPathSelected = wallpaperPath[count]
|
|
end
|
|
end
|
|
|
|
local entries, err = noctalia.listDir(wallpaperPathSelected)
|
|
if not entries then
|
|
warn(err or "impossible de lister")
|
|
noctalia.notify(tr("panel.title"), tr("panel.list_failed"))
|
|
return wallpaper
|
|
end
|
|
for _, entryName in entries do
|
|
|
|
if not tonumber(entryName) then -- test if is a id
|
|
continue
|
|
end
|
|
|
|
local content, readErr = noctalia.readFile(wallpaperPathSelected .. entryName .. "/project.json")
|
|
if content then
|
|
local value = noctalia.json.decode(content)
|
|
local name = value.title or entryName
|
|
local preview = value.preview or "no preview"
|
|
table.insert(wallpaper, {
|
|
nb = entryName,
|
|
name = name,
|
|
preview = preview,
|
|
})
|
|
else
|
|
noctalia.notify(tr("panel.title"), tr("panel.missing_project_json", { name = entryName }))
|
|
end
|
|
end
|
|
return wallpaper
|
|
end
|
|
|
|
function trim(s) -- personnal trim
|
|
return (s:gsub("^%s+", ""):gsub("%s+$", ""))
|
|
end
|
|
|
|
function isValidPid(screen, pid)
|
|
local path = "/tmp/w-engine-" .. screen .. ".pid"
|
|
if noctalia.fileExists(path) then
|
|
local fileTmp = noctalia.readFile(path)
|
|
if not fileTmp then
|
|
return false
|
|
end
|
|
local file = trim(fileTmp)
|
|
if file == pid then
|
|
|
|
local check = "/proc/" .. pid .. "/cmdline"
|
|
local checkContentTmp = noctalia.readFile(check)
|
|
if not checkContentTmp then
|
|
return false
|
|
end
|
|
local checkContent = trim(checkContentTmp)
|
|
local match = "^linux%-wallpaperengine"
|
|
if checkContent:match(match) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function getStoredPid(screen)
|
|
for _, entry in ipairs(pidList) do
|
|
if entry.output == screen then
|
|
if isValidPid(screen, entry.pid) then
|
|
return entry.pid
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function setStoredPid(screen, pid)
|
|
for _, entry in ipairs(pidList) do
|
|
if entry.output == screen then
|
|
entry.pid = pid
|
|
return
|
|
end
|
|
end
|
|
table.insert(pidList, { pid = pid, output = screen })
|
|
end
|
|
|
|
|
|
function launchWallpaper(screen, id, pidFile)
|
|
local cmd = "setsid linux-wallpaperengine --screen-root " .. screen .. " " .. id
|
|
.. " > /dev/null 2>&1 & echo $! > " .. pidFile
|
|
|
|
noctalia.runAsync(cmd, function(result)
|
|
local pidContent = noctalia.readFile(pidFile)
|
|
if pidContent then
|
|
local pid = trim(pidContent)
|
|
setStoredPid(screen, pid)
|
|
end
|
|
end, 5000)
|
|
end
|
|
|
|
function loadWallpaper(id)
|
|
lastOutputUse = outputSelectedName or takeOutput()
|
|
local pidFile = "/tmp/w-engine-" .. lastOutputUse .. ".pid"
|
|
local oldPid = getStoredPid(lastOutputUse) -- here
|
|
if oldPid then
|
|
noctalia.runAsync("kill " .. oldPid, function() -- here
|
|
launchWallpaper(lastOutputUse, id, pidFile)
|
|
end, 3000)
|
|
else
|
|
launchWallpaper(lastOutputUse, id, pidFile)
|
|
end
|
|
end
|
|
|
|
function onPickAt(slot)
|
|
local id = pickSlots[slot]
|
|
if id ~= nil then
|
|
loadWallpaper(id)
|
|
noctalia.notify(tr("panel.title"), tr("panel.apply", { id = id }))
|
|
end
|
|
end
|
|
|
|
local function render()
|
|
pickSlots = {}
|
|
local tiles = {}
|
|
local list = takeWallpaper()
|
|
for count = 1, #list, 1 do
|
|
local data = list[count]
|
|
local slotIndex = count - 1
|
|
pickSlots[slotIndex] = data.nb
|
|
table.insert(tiles, ui.column({ gap = 4, key = data.nb, align = "center" }, {
|
|
ui.image({
|
|
path = wallpaperPathSelected .. data.nb .. "/" .. data.preview,
|
|
width = previewWidth,
|
|
height = previewHeight,
|
|
fit = "cover",
|
|
radius = 8,
|
|
onClick = function()
|
|
loadWallpaper(pickSlots[slotIndex])
|
|
noctalia.notify(tr("panel.title"), tr("panel.apply", { id = pickSlots[slotIndex] }))
|
|
end,
|
|
}),
|
|
ui.label({
|
|
text = data.name,
|
|
fontSize = 11,
|
|
maxLines = 1,
|
|
maxWidth = 120,
|
|
textAlign = "center",
|
|
}),
|
|
}))
|
|
end
|
|
local rows = {}
|
|
local row = {}
|
|
for i, tile in ipairs(tiles) do
|
|
table.insert(row, tile)
|
|
if #row == columns or i == #tiles then
|
|
table.insert(rows, ui.row({ gap = 12, align = "start" }, row))
|
|
row = {}
|
|
end
|
|
end
|
|
panel.render(ui.column({ flexGrow = 1, gap = 16 }, {
|
|
ui.row({ align = "center", justify = "space_between", gap = 8 }, {
|
|
ui.label({ text = tr("panel.title"), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }),
|
|
ui.select({ options = getOutput(), onChange = "outputSelected" }),
|
|
ui.button({ glyph = "close", onClick = "onCloseClicked" }),
|
|
}),
|
|
ui.scroll({ gap = 12, align = "stretch", flexGrow = 1 }, rows),
|
|
}))
|
|
end
|
|
|
|
function takeOutput()
|
|
local output = noctalia.outputs()
|
|
for _, outputF in ipairs(output) do
|
|
return outputF.name
|
|
end
|
|
end
|
|
|
|
function outputSelected(index, label)
|
|
if type(label) == "string" and label ~= "" then
|
|
outputSelectedName = label
|
|
noctalia.notify("Output change :", outputSelectedName)
|
|
end
|
|
end
|
|
|
|
function getOutput()
|
|
outputFinalList = {}
|
|
local outputsList = noctalia.outputs()
|
|
if not outputsList then
|
|
return
|
|
end
|
|
for _, output in ipairs(outputsList) do
|
|
noctalia.log(output.name)
|
|
table.insert(outputFinalList, output.name)
|
|
end
|
|
return outputFinalList
|
|
end
|
|
|
|
function onOpen(_context)
|
|
outputSelectedName = takeOutput()
|
|
render()
|
|
end
|
|
|
|
function onCloseClicked()
|
|
panel.close()
|
|
end |