diff --git a/helpers/icon_theme.lua b/helpers/icon_theme.lua index c4d4583..5948369 100644 --- a/helpers/icon_theme.lua +++ b/helpers/icon_theme.lua @@ -1,85 +1,42 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- local lgi = require("lgi") local Gio = lgi.Gio +local DesktopAppInfo = Gio.DesktopAppInfo local Gtk = lgi.require("Gtk", "3.0") -local gobject = require("gears.object") -local gtable = require("gears.table") -local setmetatable = setmetatable -local ipairs = ipairs -local icon_theme = { mt = {} } +local ICON_SIZE = 48 +local GTK_THEME = Gtk.IconTheme.get_default() -local name_lookup = -{ - ["jetbrains-studio"] = "android-studio" -} +local _icon_theme = {} -local function get_icon_by_pid_command(self, client, apps) - local pid = client.pid - if pid ~= nil then - local handle = io.popen(string.format("ps -p %d -o comm=", pid)) - local pid_command = handle:read("*a"):gsub("^%s*(.-)%s*$", "%1") - handle:close() - - for _, app in ipairs(apps) do - local executable = app:get_executable() - if executable and executable:find(pid_command, 1, true) then - return self:get_gicon_path(app:get_icon()) +function _icon_theme.get_client_icon_path(client, icon_theme, icon_size) + local desktop_app_info_filename = DesktopAppInfo.search(client.class)[1][1] + if desktop_app_info_filename then + local desktop_app_info = DesktopAppInfo.new(desktop_app_info_filename) + if desktop_app_info then + local icon_name = desktop_app_info:get_string("Icon") + if icon_name then + return _icon_theme.get_icon_path(icon_name, icon_theme, icon_size) end end end + + _icon_theme.choose_icon({"window", "window-manager", "xfwm4-default", "window_list"}, icon_theme, icon_size) end -local function get_icon_by_icon_name(self, client, apps) - local icon_name = client.icon_name and client.icon_name:lower() or nil - if icon_name ~= nil then - for _, app in ipairs(apps) do - local name = app:get_name():lower() - if name and name:find(icon_name, 1, true) then - return self:get_gicon_path(app:get_icon()) - end - end +function _icon_theme.choose_icon(icons_names, icon_theme, icon_size) + if icon_theme then + GTK_THEME = Gtk.IconTheme.new() + Gtk.IconTheme.set_custom_theme(GTK_THEME, icon_theme); end -end - -local function get_icon_by_class(self, client, apps) - if client.class ~= nil then - local class = name_lookup[client.class] or client.class:lower() - - -- Try to remove dashes - local class_1 = class:gsub("[%-]", "") - - -- Try to replace dashes with dot - local class_2 = class:gsub("[%-]", ".") - - -- Try to match only the first word - 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 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 self:get_gicon_path(app:get_icon()) - end - end - end + if icon_size then + ICON_SIZE = icon_size end -end -function icon_theme:get_client_icon_path(client) - local apps = Gio.AppInfo.get_all() - - return get_icon_by_pid_command(self, client, apps) or - get_icon_by_icon_name(self, client, apps) or - get_icon_by_class(self, client, apps) or - client.icon or - self:choose_icon({"window", "window-manager", "xfwm4-default", "window_list" }) -end - -function icon_theme:choose_icon(icons_names) - local icon_info = self.gtk_theme:choose_icon(icons_names, self.icon_size, 0); + local icon_info = GTK_THEME:choose_icon(icons_names, ICON_SIZE, 0); if icon_info then local icon_path = icon_info:get_filename() if icon_path then @@ -90,12 +47,20 @@ function icon_theme:choose_icon(icons_names) return "" end -function icon_theme:get_gicon_path(gicon) +function _icon_theme.get_gicon_path(gicon, icon_theme, icon_size) if gicon == nil then return "" end - local icon_info = self.gtk_theme:lookup_by_gicon(gicon, self.icon_size, 0); + if icon_theme then + GTK_THEME = Gtk.IconTheme.new() + Gtk.IconTheme.set_custom_theme(GTK_THEME, icon_theme); + end + if icon_size then + ICON_SIZE = icon_size + end + + local icon_info = GTK_THEME:lookup_by_gicon(gicon, ICON_SIZE, 0); if icon_info then local icon_path = icon_info:get_filename() if icon_path then @@ -106,8 +71,16 @@ function icon_theme:get_gicon_path(gicon) return "" end -function icon_theme:get_icon_path(icon_name) - local icon_info = self.gtk_theme:lookup_icon(icon_name, self.icon_size, 0) +function _icon_theme.get_icon_path(icon_name, icon_theme, icon_size) + if icon_theme then + GTK_THEME = Gtk.IconTheme.new() + Gtk.IconTheme.set_custom_theme(GTK_THEME, icon_theme); + end + if icon_size then + ICON_SIZE = icon_size + end + + local icon_info = GTK_THEME:lookup_icon(icon_name, ICON_SIZE, 0) if icon_info then local icon_path = icon_info:get_filename() if icon_path then @@ -118,25 +91,4 @@ function icon_theme:get_icon_path(icon_name) return "" end -local function new(theme_name, icon_size) - local ret = gobject{} - gtable.crush(ret, icon_theme, true) - - ret.name = theme_name or nil - ret.icon_size = icon_size or 48 - - if theme_name then - ret.gtk_theme = Gtk.IconTheme.new() - Gtk.IconTheme.set_custom_theme(ret.gtk_theme, theme_name); - else - ret.gtk_theme = Gtk.IconTheme.get_default() - end - - return ret -end - -function icon_theme.mt:__call(...) - return new(...) -end - -return setmetatable(icon_theme, icon_theme.mt) \ No newline at end of file +return _icon_theme \ No newline at end of file diff --git a/helpers/init.lua b/helpers/init.lua index f2c898e..7e7f5d7 100644 --- a/helpers/init.lua +++ b/helpers/init.lua @@ -2,6 +2,7 @@ return { client = require(... .. ".client"), color = require(... .. ".color"), filesystem = require(... .. ".filesystem"), + icon_theme = require(... .. ".icon_theme"), shape = require(... .. ".shape"), time = require(... .. ".time"), } diff --git a/widget/app_launcher/init.lua b/widget/app_launcher/init.lua index 3a58d1e..7029a38 100644 --- a/widget/app_launcher/init.lua +++ b/widget/app_launcher/init.lua @@ -8,6 +8,7 @@ local wibox = require("wibox") local beautiful = require("beautiful") local color = require(tostring(...):match(".*bling") .. ".helpers.color") local prompt = require(... .. ".prompt") +local helpers = require(tostring(path):match(".*bling") .. ".helpers") local dpi = beautiful.xresources.apply_dpi local string = string local table = table @@ -532,14 +533,12 @@ local function generate_apps(self) end) end - local icon_theme = require(tostring(path):match(".*bling") .. ".helpers.icon_theme")(self.icon_theme, self.icon_size) - for _, app in ipairs(apps) do if app.should_show(app) then local name = app_info.get_name(app) local commandline = app_info.get_commandline(app) local executable = app_info.get_executable(app) - local icon = icon_theme:get_gicon_path(app_info.get_icon(app)) + local icon = helpers.icon_theme.get_gicon_path(app_info.get_icon(app), self.icon_theme, self.icon_size) -- Check if this app should be skipped, depanding on the skip_names / skip_commands table if not has_value(self.skip_names, name) and not has_value(self.skip_commands, commandline) then @@ -547,11 +546,13 @@ local function generate_apps(self) if icon ~= "" or self.skip_empty_icons == false then if icon == "" then if self.default_app_icon_name ~= nil then - icon = icon_theme:get_icon_path(self.default_app_icon_name) + icon = helpers.icon_theme.get_icon_path(self.default_app_icon_name, self.icon_theme, self.icon_size) elseif self.default_app_icon_path ~= nil then icon = self.default_app_icon_path else - icon = icon_theme:choose_icon({"application-all", "application", "application-default-icon", "app"}) + icon = helpers.icon_theme.choose_icon( + {"application-all", "application", "application-default-icon", "app"}, + self.icon_theme, self.icon_size) end end