From 08c4d52480d92403d797ece92e827fe026746ca7 Mon Sep 17 00:00:00 2001 From: Yessiest Date: Sat, 27 May 2023 18:57:46 +0400 Subject: [PATCH] Button to reload xdg cache + licensing stuff --- libs/awmtk2.lua | 8 +- libs/digger.lua | 8 ++ libs/imagemagick_blur.lua | 7 ++ libs/xdg_data.lua | 137 +++++++++++++++++++++++++ modules/macros.lua | 7 ++ modules/rules_stub.lua | 7 ++ modules/tiling.lua | 7 ++ modules/xdg_data.lua | 99 ++---------------- widgets/base/layout.lua | 7 ++ widgets/rootmenu/controls.lua | 51 +++++++++ widgets/supermenu/applications-tab.lua | 7 ++ 11 files changed, 252 insertions(+), 93 deletions(-) create mode 100644 libs/xdg_data.lua diff --git a/libs/awmtk2.lua b/libs/awmtk2.lua index 56c0b20..e4bf819 100644 --- a/libs/awmtk2.lua +++ b/libs/awmtk2.lua @@ -1,10 +1,10 @@ --- this file is part of reno desktop. +-- This file is part of Reno desktop. -- --- reno desktop is free software: you can redistribute it and/or modify it under the terms of the gnu general public license as published by the free software foundation, either version 3 of the license, or (at your option) any later version. +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -- --- reno desktop is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. see the gnu general public license for more details. +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -- --- you should have received a copy of the gnu general public license along with reno desktop. if not, see . +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . -- renotk (formerly awmtk2) - template/granular styling library for reno local wibox = require("wibox") local gears = require("gears") diff --git a/libs/digger.lua b/libs/digger.lua index 5570d67..06bf502 100644 --- a/libs/digger.lua +++ b/libs/digger.lua @@ -1,3 +1,11 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . + -- Since it would seem that get_widget_by_id is still an open issue (https://github.com/awesomeWM/awesome/issues/2945, https://github.com/awesomeWM/awesome/issues/2181), this abomination is the nuclear solution to finding **ALL** widgets that don't get indexed because they are separated by an already instantiated widget. If you use this, please, use it carefully. Don't call it more than you really need, cache the results if you have to. -- Hypothetically, if there occurs such a thing as widget cycle, this will get stuck. Also it's very expensive. return function(widget, id) diff --git a/libs/imagemagick_blur.lua b/libs/imagemagick_blur.lua index 5244d78..dcd292c 100644 --- a/libs/imagemagick_blur.lua +++ b/libs/imagemagick_blur.lua @@ -1,3 +1,10 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . -- If possible, try to blur the image and return its path via callback. Relies on ImageMagick local awful = require("awful") return function(image_path,callback) diff --git a/libs/xdg_data.lua b/libs/xdg_data.lua new file mode 100644 index 0000000..9e5e8fb --- /dev/null +++ b/libs/xdg_data.lua @@ -0,0 +1,137 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . +-- Asynchronous XDG data aggregator (library) +local menu_utils = require("menubar.utils") +local awful = require("awful") +local gears = require("gears") +local json = require("dkjson") +local lib = {} + +function lib.init_xdg_struct() + -- Global xdg data struct + local xdg = { + directory_integrity = {}, + directory_listings = {}, + apps = {}, + categories = { + Other = { + icon = "applications-other", + apps = {} + }, + Wine = { + icon = "wine", + apps = {} + } + } + } + return xdg +end + +function lib.load_xdg_cache() + -- Load cached applications + local cache_file = io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","r") + local cache + if cache_file then + cache = json.decode(cache_file:read("*a")) + cache_file:close() + end + return cache +end + +function lib.add_categories(xdg, categories) + -- Add missing category entries as defined by awesome + for _,v in pairs(categories) do + xdg.categories[v.app_type] = { + name = v.name, + icon = v.icon_name, + apps = {} + } + end +end + +function lib.async_process_dirs(xdg, dirs, cache, on_dir_done) + -- Asynchronous scanning process + for _,v in pairs(dirs) do + xdg.directory_listings[v] = {} + awful.spawn.with_line_callback("find "..tostring(v).." -maxdepth 1 -name *.desktop",{ + stdout = function(line) + -- Assume the cache is valid for a listed file + if cache and cache.directory_listings[v][line] then + xdg.directory_listings[v][line] = true + xdg.apps[line] = cache.apps[line] + xdg.categories[cache.apps[line].category].apps[line] = cache.apps[line] + return + end + local data = menu_utils.parse_desktop_file(line) + if data.NoDisplay then + return + end + local appdata = { + name = data.Name, + category = "Other", + exec = data.Exec, + icon = (data.Icon and menu_utils.lookup_icon(data.Icon)), + description = data.Comment + } + -- Match first available cateogry for sorting + for _,vv in pairs(data.Categories or {"Other"}) do + if xdg.categories[vv] then + appdata.category = vv + break + end + -- Oh how do I love those Wine applications and their categories + if vv:match("^Wine") then + appdata.category = "Wine" + break + end + end + -- Open terminal apps in the terminal (duh) + if data.Terminal then + appdata.exec = global.terminal.." -e "..appdata.exec + end + -- Just for you, Wine - special case because you're being a shit + if (appdata.exec and appdata.exec:find("%W?wine ")) then + appdata.category = "Wine" + end + xdg.apps[line] = appdata + xdg.categories[appdata.category].apps[line] = appdata + -- Add the file to the listing of cached ones + xdg.directory_listings[v][line] = true + end, + output_done = function(...) on_dir_done(v,...) end + }) + end +end + +function lib.generate_meta_patch(xdg) + local patch = {apps = {}} + for k,v in pairs(xdg.apps) do + patch.apps[k] = {} + for kk,vv in pairs(v) do + patch.apps[k][kk] = vv + end + patch.apps[k].name = nil + patch.apps[k].category = nil + patch.apps[k].exec = nil + patch.apps[k].icon = nil + patch.apps[k].description = nil + end + return patch +end + +function lib.apply_meta_patch(xdg,patch) + for k,v in pairs(patch.apps) do + if xdg.apps[k] then + for kk,vv in pairs(v) do + xdg.apps[k][kk] = vv + end + end + end +end + +return lib diff --git a/modules/macros.lua b/modules/macros.lua index f83a0ca..29beef4 100644 --- a/modules/macros.lua +++ b/modules/macros.lua @@ -1,3 +1,10 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") local gears = require("gears") local ask = require("asckey") diff --git a/modules/rules_stub.lua b/modules/rules_stub.lua index 6c2f16c..ae1d402 100644 --- a/modules/rules_stub.lua +++ b/modules/rules_stub.lua @@ -1,3 +1,10 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") local gears = require("gears") awful.rules.rules = gears.table.join(awful.rules.rules, { diff --git a/modules/tiling.lua b/modules/tiling.lua index 5362601..4cee301 100644 --- a/modules/tiling.lua +++ b/modules/tiling.lua @@ -1,3 +1,10 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") awful.layout.layouts = { diff --git a/modules/xdg_data.lua b/modules/xdg_data.lua index 218ebae..0f381b9 100644 --- a/modules/xdg_data.lua +++ b/modules/xdg_data.lua @@ -6,13 +6,11 @@ -- -- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . -- Asynchronous XDG data aggregator -local start_human = os.time() -local start_computer = os.clock() local menu_utils = require("menubar.utils") local menu_gen = require("menubar.menu_gen") -local awful = require("awful") local gears = require("gears") local json = require("dkjson") +local lib = require("xdg_data") menu_utils.wm_name = "" -- Directories to scan for .desktop files @@ -27,95 +25,18 @@ end) -- Global xdg data struct -_G.xdg = { - directory_integrity = {}, - directory_listings = {}, - apps = {}, - categories = { - Other = { - icon = "applications-other", - apps = {} - }, - Wine = { - icon = "wine", - apps = {} - } - } -} - +_G.xdg = lib.init_xdg_struct() -- Load cached applications -local cache_file = io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","r") -local cache -if cache_file then - cache = json.decode(cache_file:read("*a")) - cache_file:close() -end - +local cache = lib.load_xdg_cache() -- Add missing category entries as defined by awesome -for _,v in pairs(menu_gen.all_categories) do - xdg.categories[v.app_type] = { - name = v.name, - icon = v.icon_name, - apps = {} - } -end - +lib.add_categories(xdg,menu_gen.all_categories) -- Asynchronous scanning process -for _,v in pairs(desktop_dirs) do - xdg.directory_listings[v] = {} - awful.spawn.with_line_callback("find "..tostring(v).." -maxdepth 1 -name *.desktop",{ - stdout = function(line) - -- Assume the cache is valid for a listed file - if cache and cache.directory_listings[v][line] then - xdg.directory_listings[v][line] = true - xdg.apps[line] = cache.apps[line] - xdg.categories[cache.apps[line].category].apps[line] = cache.apps[line] - return - end - local data = menu_utils.parse_desktop_file(line) - if data.NoDisplay then - return - end - local appdata = { - name = data.Name, - category = "Other", - exec = data.Exec, - icon = (data.Icon and menu_utils.lookup_icon(data.Icon)), - description = data.Comment - } - -- Match first available cateogry for sorting - for _,vv in pairs(data.Categories or {"Other"}) do - if xdg.categories[vv] then - appdata.category = vv - break - end - -- Oh how do I love those Wine applications and their categories - if vv:match("^Wine") then - appdata.category = "Wine" - break - end - end - -- Open terminal apps in the terminal (duh) - if data.Terminal then - appdata.exec = global.terminal.." -e "..appdata.exec - end - -- Just for you, Wine - special case because you're being a shit - if (appdata.exec and appdata.exec:find("%W?wine ")) then - appdata.category = "Wine" - end - xdg.apps[line] = appdata - xdg.categories[appdata.category].apps[line] = appdata - -- Add the file to the listing of cached ones - xdg.directory_listings[v][line] = true - end, - output_done = function() - -- Save directory listing hash - desktop_dirs_complete = desktop_dirs_complete + 1 - -- Call a global signal - awesome.emit_signal("xdg::dir_finished",v) - end - }) -end +lib.async_process_dirs(xdg,desktop_dirs,cache,function(v) + -- Count completed directory + desktop_dirs_complete = desktop_dirs_complete + 1 + -- Call a global signal + awesome.emit_signal("xdg::dir_finished",v) +end) local count = function(t) local n = 0 diff --git a/widgets/base/layout.lua b/widgets/base/layout.lua index 00422cd..5ccab58 100644 --- a/widgets/base/layout.lua +++ b/widgets/base/layout.lua @@ -1,2 +1,9 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") return function(args) return awful.widget.layoutbox(args.screen) end diff --git a/widgets/rootmenu/controls.lua b/widgets/rootmenu/controls.lua index 0124e72..7153e31 100644 --- a/widgets/rootmenu/controls.lua +++ b/widgets/rootmenu/controls.lua @@ -8,11 +8,62 @@ -- Simple global context menu controls local beautiful = require("beautiful") local menugen = require("context_menu") +local xdglib = require("xdg_data") +local menu_gen = require("menubar.menu_gen") +local gears = require("gears") +local json = require("dkjson") + +local function regenerate_xdg() + local desktop_dirs = {os.getenv("HOME").."/Desktop"} + local desktop_dirs_complete = 0 + local _ = ((table.concat(gears.filesystem.get_xdg_data_dirs(),":") or + "/usr/share:/usr/local/share")..":"..os.getenv("HOME").."/.local/share") + :gsub("[^:]*",function(path) + if gears.filesystem.dir_readable(path.."/applications") then + table.insert(desktop_dirs,path.."/applications") + end + end) + + local function count(t) + local c = 0 + for _,_ in pairs(t) do + c = c +1 + end + return c + end + + require("naughty").notify({title="Regenerating XDG cache..."}) + -- Generate a patch containing metadata + local meta = xdglib.generate_meta_patch(_G.xdg) + -- Initialize structure + _G.xdg = xdglib.init_xdg_struct() + -- Add missing category entries + xdglib.add_categories(xdg,menu_gen.all_categories) + -- Asynchronous process scanning + xdglib.async_process_dirs(xdg,desktop_dirs,nil,function() + desktop_dirs_complete = desktop_dirs_complete + 1 + if desktop_dirs_complete == #desktop_dirs then + for k,v in pairs(xdg.categories) do + if count(v.apps) == 0 then + xdg.categories[k] = nil + end + end + xdglib.apply_meta_patch(xdg,meta) + require("naughty").notify({ + text="Done! Restart WM to reload menus." + }) + io.open(gears.filesystem.get_xdg_cache_home().. + ".reno_xdg_cache.json","w" + ):write(json.encode(xdg)):close() + end + end) +end return function(args) local widget = menugen({ items = { {"Awesome", { + {"reload cache",regenerate_xdg}, {"open config dir", "xdg-open "..root_path}, {"open docs", "xdg-open https://awesomewm.org/doc/api/"}, {"restart", function() awesome.restart() end}, diff --git a/widgets/supermenu/applications-tab.lua b/widgets/supermenu/applications-tab.lua index 077daf6..ce6448d 100644 --- a/widgets/supermenu/applications-tab.lua +++ b/widgets/supermenu/applications-tab.lua @@ -1,3 +1,10 @@ +-- This file is part of Reno desktop. +-- +-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +-- +-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") local gears = require("gears") local awmtk2 = require("awmtk2")