Fuxx
This commit is contained in:
parent
8268fba83d
commit
7ed2a6e110
9565 changed files with 1315332 additions and 90 deletions
127
home/.config/awesome/lib/bling/helpers/client.lua
Normal file
127
home/.config/awesome/lib/bling/helpers/client.lua
Normal file
|
@ -0,0 +1,127 @@
|
|||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
|
||||
local _client = {}
|
||||
|
||||
--- Turn off passed client
|
||||
-- Remove current tag from window's tags
|
||||
--
|
||||
-- @param c A client
|
||||
function _client.turn_off(c, current_tag)
|
||||
if current_tag == nil then
|
||||
current_tag = c.screen.selected_tag
|
||||
end
|
||||
local ctags = {}
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c.sticky = false
|
||||
end
|
||||
|
||||
--- Turn on passed client (add current tag to window's tags)
|
||||
--
|
||||
-- @param c A client
|
||||
function _client.turn_on(c)
|
||||
local current_tag = c.screen.selected_tag
|
||||
ctags = { current_tag }
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c:raise()
|
||||
client.focus = c
|
||||
end
|
||||
|
||||
--- Sync two clients
|
||||
--
|
||||
-- @param to_c The client to which to write all properties
|
||||
-- @param from_c The client from which to read all properties
|
||||
function _client.sync(to_c, from_c)
|
||||
if not from_c or not to_c then
|
||||
return
|
||||
end
|
||||
if not from_c.valid or not to_c.valid then
|
||||
return
|
||||
end
|
||||
if from_c.modal then
|
||||
return
|
||||
end
|
||||
to_c.floating = from_c.floating
|
||||
to_c.maximized = from_c.maximized
|
||||
to_c.above = from_c.above
|
||||
to_c.below = from_c.below
|
||||
to_c:geometry(from_c:geometry())
|
||||
-- TODO: Should also copy over the position in a tiling layout
|
||||
end
|
||||
|
||||
--- Checks whether the passed client is a childprocess of a given process ID
|
||||
--
|
||||
-- @param c A client
|
||||
-- @param pid The process ID
|
||||
-- @return True if the passed client is a childprocess of the given PID otherwise false
|
||||
function _client.is_child_of(c, pid)
|
||||
-- io.popen is normally discouraged. Should probably be changed
|
||||
if not c or not c.valid then
|
||||
return false
|
||||
end
|
||||
if tostring(c.pid) == tostring(pid) then
|
||||
return true
|
||||
end
|
||||
local pid_cmd = [[pstree -T -p -a -s ]]
|
||||
.. tostring(c.pid)
|
||||
.. [[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']]
|
||||
local handle = io.popen(pid_cmd)
|
||||
local parent_pid = handle:read("*a")
|
||||
handle:close()
|
||||
return tostring(parent_pid) == tostring(pid)
|
||||
or tostring(parent_pid) == tostring(c.pid)
|
||||
end
|
||||
|
||||
--- Finds all clients that satisfy the passed rule
|
||||
--
|
||||
-- @param rule The rule to be searched for
|
||||
-- @retrun A list of clients that match the given rule
|
||||
function _client.find(rule)
|
||||
local function matcher(c)
|
||||
return awful.rules.match(c, rule)
|
||||
end
|
||||
local clients = client.get()
|
||||
local findex = gears.table.hasitem(clients, client.focus) or 1
|
||||
local start = gears.math.cycle(#clients, findex + 1)
|
||||
|
||||
local matches = {}
|
||||
for c in awful.client.iterate(matcher, start) do
|
||||
matches[#matches + 1] = c
|
||||
end
|
||||
|
||||
return matches
|
||||
end
|
||||
|
||||
--- Gets the next client by direction from the focused one
|
||||
--
|
||||
-- @param direction it the direction as a string ("up", "down", "left" or "right")
|
||||
-- @retrun the client in the given direction starting at the currently focused one, nil otherwise
|
||||
function _client.get_by_direction(direction)
|
||||
local sel = client.focus
|
||||
if not sel then
|
||||
return nil
|
||||
end
|
||||
local cltbl = sel.screen:get_clients()
|
||||
local geomtbl = {}
|
||||
for i, cl in ipairs(cltbl) do
|
||||
geomtbl[i] = cl:geometry()
|
||||
end
|
||||
local target = gears.geometry.rectangle.get_in_direction(
|
||||
direction,
|
||||
geomtbl,
|
||||
sel:geometry()
|
||||
)
|
||||
return cltbl[target]
|
||||
end
|
||||
|
||||
return _client
|
158
home/.config/awesome/lib/bling/helpers/color.lua
Normal file
158
home/.config/awesome/lib/bling/helpers/color.lua
Normal file
|
@ -0,0 +1,158 @@
|
|||
local tonumber = tonumber
|
||||
local string = string
|
||||
local math = math
|
||||
local floor = math.floor
|
||||
local max = math.max
|
||||
local min = math.min
|
||||
local abs = math.abs
|
||||
local format = string.format
|
||||
|
||||
local _color = {}
|
||||
|
||||
--- Try to guess if a color is dark or light.
|
||||
--
|
||||
-- @string color The color with hexadecimal HTML format `"#RRGGBB"`.
|
||||
-- @treturn bool `true` if the color is dark, `false` if it is light.
|
||||
function _color.is_dark(color)
|
||||
-- Try to determine if the color is dark or light
|
||||
local numeric_value = 0
|
||||
for s in color:gmatch("[a-fA-F0-9][a-fA-F0-9]") do
|
||||
numeric_value = numeric_value + tonumber("0x" .. s)
|
||||
end
|
||||
return (numeric_value < 383)
|
||||
end
|
||||
|
||||
function _color.is_opaque(color)
|
||||
if type(color) == "string" then
|
||||
color = _color.hex_to_rgba(color)
|
||||
end
|
||||
|
||||
return color.a < 0.01
|
||||
end
|
||||
|
||||
--- Lighten a color.
|
||||
--
|
||||
-- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`.
|
||||
-- @int[opt=26] amount How much light from 0 to 255. Default is around 10%.
|
||||
-- @treturn string The lighter color
|
||||
function _color.lighten(color, amount)
|
||||
amount = amount or 26
|
||||
local c = {
|
||||
r = tonumber("0x" .. color:sub(2, 3)),
|
||||
g = tonumber("0x" .. color:sub(4, 5)),
|
||||
b = tonumber("0x" .. color:sub(6, 7)),
|
||||
}
|
||||
|
||||
c.r = c.r + amount
|
||||
c.r = c.r < 0 and 0 or c.r
|
||||
c.r = c.r > 255 and 255 or c.r
|
||||
c.g = c.g + amount
|
||||
c.g = c.g < 0 and 0 or c.g
|
||||
c.g = c.g > 255 and 255 or c.g
|
||||
c.b = c.b + amount
|
||||
c.b = c.b < 0 and 0 or c.b
|
||||
c.b = c.b > 255 and 255 or c.b
|
||||
|
||||
return string.format("#%02x%02x%02x", c.r, c.g, c.b)
|
||||
end
|
||||
|
||||
--- Darken a color.
|
||||
--
|
||||
-- @string color The color to darken with hexadecimal HTML format `"#RRGGBB"`.
|
||||
-- @int[opt=26] amount How much dark from 0 to 255. Default is around 10%.
|
||||
-- @treturn string The darker color
|
||||
function _color.darken(color, amount)
|
||||
amount = amount or 26
|
||||
return _color.lighten(color, -amount)
|
||||
end
|
||||
|
||||
-- Returns a value that is clipped to interval edges if it falls outside the interval
|
||||
function _color.clip(num, min_num, max_num)
|
||||
return max(min(num, max_num), min_num)
|
||||
end
|
||||
|
||||
-- Converts the given hex color to rgba
|
||||
function _color.hex_to_rgba(color)
|
||||
color = color:gsub("#", "")
|
||||
return { r = tonumber("0x" .. color:sub(1, 2)),
|
||||
g = tonumber("0x" .. color:sub(3, 4)),
|
||||
b = tonumber("0x" .. color:sub(5, 6)),
|
||||
a = #color == 8 and tonumber("0x" .. color:sub(7, 8)) or 255 }
|
||||
end
|
||||
|
||||
-- Converts the given rgba color to hex
|
||||
function _color.rgba_to_hex(color)
|
||||
local r = _color.clip(color.r or color[1], 0, 255)
|
||||
local g = _color.clip(color.g or color[2], 0, 255)
|
||||
local b = _color.clip(color.b or color[3], 0, 255)
|
||||
local a = _color.clip(color.a or color[4] or 255, 0, 255)
|
||||
return "#" .. format("%02x%02x%02x%02x",
|
||||
floor(r),
|
||||
floor(g),
|
||||
floor(b),
|
||||
floor(a))
|
||||
end
|
||||
|
||||
-- Converts the given hex color to hsv
|
||||
function _color.hex_to_hsv(color)
|
||||
local color = _color.hex2rgb(color)
|
||||
local C_max = max(color.r, color.g, color.b)
|
||||
local C_min = min(color.r, color.g, color.b)
|
||||
local delta = C_max - C_min
|
||||
local H, S, V
|
||||
if delta == 0 then
|
||||
H = 0
|
||||
elseif C_max == color.r then
|
||||
H = 60 * (((color.g - color.b) / delta) % 6)
|
||||
elseif C_max == color.g then
|
||||
H = 60 * (((color.b - color.r) / delta) + 2)
|
||||
elseif C_max == color.b then
|
||||
H = 60 * (((color.r - color.g) / delta) + 4)
|
||||
end
|
||||
if C_max == 0 then
|
||||
S = 0
|
||||
else
|
||||
S = delta / C_max
|
||||
end
|
||||
V = C_max
|
||||
|
||||
return { h = H,
|
||||
s = S * 100,
|
||||
v = V * 100 }
|
||||
end
|
||||
|
||||
-- Converts the given hsv color to hex
|
||||
function _color.hsv_to_hex(H, S, V)
|
||||
S = S / 100
|
||||
V = V / 100
|
||||
if H > 360 then H = 360 end
|
||||
if H < 0 then H = 0 end
|
||||
local C = V * S
|
||||
local X = C * (1 - abs(((H / 60) % 2) - 1))
|
||||
local m = V - C
|
||||
local r_, g_, b_ = 0, 0, 0
|
||||
if H >= 0 and H < 60 then
|
||||
r_, g_, b_ = C, X, 0
|
||||
elseif H >= 60 and H < 120 then
|
||||
r_, g_, b_ = X, C, 0
|
||||
elseif H >= 120 and H < 180 then
|
||||
r_, g_, b_ = 0, C, X
|
||||
elseif H >= 180 and H < 240 then
|
||||
r_, g_, b_ = 0, X, C
|
||||
elseif H >= 240 and H < 300 then
|
||||
r_, g_, b_ = X, 0, C
|
||||
elseif H >= 300 and H < 360 then
|
||||
r_, g_, b_ = C, 0, X
|
||||
end
|
||||
local r, g, b = (r_ + m) * 255, (g_ + m) * 255, (b_ + m) * 255
|
||||
return ("#%02x%02x%02x"):format(floor(r), floor(g), floor(b))
|
||||
end
|
||||
|
||||
function _color.multiply(color, amount)
|
||||
return { _color.clip(color.r * amount, 0, 255),
|
||||
_color.clip(color.g * amount, 0, 255),
|
||||
_color.clip(color.b * amount, 0, 255),
|
||||
255 }
|
||||
end
|
||||
|
||||
return _color
|
62
home/.config/awesome/lib/bling/helpers/filesystem.lua
Normal file
62
home/.config/awesome/lib/bling/helpers/filesystem.lua
Normal file
|
@ -0,0 +1,62 @@
|
|||
local Gio = require("lgi").Gio
|
||||
local awful = require("awful")
|
||||
local string = string
|
||||
|
||||
local _filesystem = {}
|
||||
|
||||
--- Get a list of files from a given directory.
|
||||
-- @string path The directory to search.
|
||||
-- @tparam[opt] table exts Specific extensions to limit the search to. eg:`{ "jpg", "png" }`
|
||||
-- If ommited, all files are considered.
|
||||
-- @bool[opt=false] recursive List files from subdirectories
|
||||
-- @staticfct bling.helpers.filesystem.get_random_file_from_dir
|
||||
function _filesystem.list_directory_files(path, exts, recursive)
|
||||
recursive = recursive or false
|
||||
local files, valid_exts = {}, {}
|
||||
|
||||
-- Transforms { "jpg", ... } into { [jpg] = #, ... }
|
||||
if exts then
|
||||
for i, j in ipairs(exts) do
|
||||
valid_exts[j:lower()] = i
|
||||
end
|
||||
end
|
||||
|
||||
-- Build a table of files from the path with the required extensions
|
||||
local file_list = Gio.File.new_for_path(path):enumerate_children(
|
||||
"standard::*",
|
||||
0
|
||||
)
|
||||
if file_list then
|
||||
for file in function()
|
||||
return file_list:next_file()
|
||||
end do
|
||||
local file_type = file:get_file_type()
|
||||
if file_type == "REGULAR" then
|
||||
local file_name = file:get_display_name()
|
||||
if
|
||||
not exts
|
||||
or valid_exts[file_name:lower():match(".+%.(.*)$") or ""]
|
||||
then
|
||||
table.insert(files, file_name)
|
||||
end
|
||||
elseif recursive and file_type == "DIRECTORY" then
|
||||
local file_name = file:get_display_name()
|
||||
files = gears.table.join(
|
||||
files,
|
||||
list_directory_files(file_name, exts, recursive)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return files
|
||||
end
|
||||
|
||||
function _filesystem.save_image_async_curl(url, filepath, callback)
|
||||
awful.spawn.with_line_callback(string.format("curl -L -s %s -o %s", url, filepath),
|
||||
{
|
||||
exit=callback
|
||||
})
|
||||
end
|
||||
|
||||
return _filesystem
|
142
home/.config/awesome/lib/bling/helpers/icon_theme.lua
Normal file
142
home/.config/awesome/lib/bling/helpers/icon_theme.lua
Normal file
|
@ -0,0 +1,142 @@
|
|||
local lgi = require("lgi")
|
||||
local Gio = lgi.Gio
|
||||
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 name_lookup =
|
||||
{
|
||||
["jetbrains-studio"] = "android-studio"
|
||||
}
|
||||
|
||||
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())
|
||||
end
|
||||
end
|
||||
end
|
||||
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
|
||||
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
|
||||
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);
|
||||
if icon_info then
|
||||
local icon_path = icon_info:get_filename()
|
||||
if icon_path then
|
||||
return icon_path
|
||||
end
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
function icon_theme:get_gicon_path(gicon)
|
||||
if gicon == nil then
|
||||
return ""
|
||||
end
|
||||
|
||||
local icon_info = self.gtk_theme:lookup_by_gicon(gicon, self.icon_size, 0);
|
||||
if icon_info then
|
||||
local icon_path = icon_info:get_filename()
|
||||
if icon_path then
|
||||
return icon_path
|
||||
end
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
function icon_theme:get_icon_path(icon_name)
|
||||
local icon_info = self.gtk_theme:lookup_icon(icon_name, self.icon_size, 0)
|
||||
if icon_info then
|
||||
local icon_path = icon_info:get_filename()
|
||||
if icon_path then
|
||||
return icon_path
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
7
home/.config/awesome/lib/bling/helpers/init.lua
Normal file
7
home/.config/awesome/lib/bling/helpers/init.lua
Normal file
|
@ -0,0 +1,7 @@
|
|||
return {
|
||||
client = require(... .. ".client"),
|
||||
color = require(... .. ".color"),
|
||||
filesystem = require(... .. ".filesystem"),
|
||||
shape = require(... .. ".shape"),
|
||||
time = require(... .. ".time"),
|
||||
}
|
30
home/.config/awesome/lib/bling/helpers/shape.lua
Normal file
30
home/.config/awesome/lib/bling/helpers/shape.lua
Normal file
|
@ -0,0 +1,30 @@
|
|||
local gears = require("gears")
|
||||
|
||||
local shape = {}
|
||||
|
||||
-- Create rounded rectangle shape (in one line)
|
||||
|
||||
function shape.rrect(radius)
|
||||
return function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, radius)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create partially rounded rect
|
||||
|
||||
function shape.prrect(radius, tl, tr, br, bl)
|
||||
return function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(
|
||||
cr,
|
||||
width,
|
||||
height,
|
||||
tl,
|
||||
tr,
|
||||
br,
|
||||
bl,
|
||||
radius
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
return shape
|
24
home/.config/awesome/lib/bling/helpers/time.lua
Normal file
24
home/.config/awesome/lib/bling/helpers/time.lua
Normal file
|
@ -0,0 +1,24 @@
|
|||
local time = {}
|
||||
|
||||
--- Parse a time string to seconds (from midnight)
|
||||
--
|
||||
-- @string time The time (`HH:MM:SS`)
|
||||
-- @treturn int The number of seconds since 00:00:00
|
||||
function time.hhmmss_to_seconds(time)
|
||||
hour_sec = tonumber(string.sub(time, 1, 2)) * 3600
|
||||
min_sec = tonumber(string.sub(time, 4, 5)) * 60
|
||||
get_sec = tonumber(string.sub(time, 7, 8))
|
||||
return (hour_sec + min_sec + get_sec)
|
||||
end
|
||||
|
||||
--- Get time difference in seconds.
|
||||
--
|
||||
-- @tparam string base The time to compare from (`HH:MM:SS`).
|
||||
-- @tparam string base The time to compare to (`HH:MM:SS`).
|
||||
-- @treturn int Number of seconds between the two times.
|
||||
function time.time_diff(base, compare)
|
||||
local diff = time.hhmmss_to_seconds(base) - time.hhmmss_to_seconds(compare)
|
||||
return diff
|
||||
end
|
||||
|
||||
return time
|
Loading…
Add table
Add a link
Reference in a new issue