yes, I'm very commit lazy
@@ -8,13 +8,13 @@
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local beautiful = require("beautiful")
|
||||
local gtable = require("gears.table")
|
||||
local base = require("wibox.widget.base")
|
||||
local gstring = require("gears.string")
|
||||
local akeygrabber = require("awful.keygrabber")
|
||||
local akey = require("awful.key")
|
||||
local textbox = require("wibox.widget.textbox")
|
||||
local beautiful = require('beautiful')
|
||||
local gtable = require('gears.table')
|
||||
local base = require('wibox.widget.base')
|
||||
local gstring = require('gears.string')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local akey = require('awful.key')
|
||||
local textbox = require('wibox.widget.textbox')
|
||||
|
||||
local capi = {
|
||||
selection = selection,
|
||||
@@ -28,15 +28,15 @@ local inputbox = { mt = {} }
|
||||
local function text_with_cursor(text, cursor_pos, self)
|
||||
local char, spacer, text_start, text_end
|
||||
|
||||
local cursor_fg = beautiful.inputbox_cursor_fg or "#313131"
|
||||
local cursor_bg = beautiful.inputbox_cursor_bg or "#0dccfc"
|
||||
local placeholder_text = self.hint_text or ""
|
||||
local placeholder_fg = beautiful.inputbox_placeholder_fg or "#777777"
|
||||
local highlight_bg = beautiful.inputbox_highlight_bg or "#35ffe4"
|
||||
local highlight_fg = beautiful.inputbox_highlight_fg or "#000000"
|
||||
local cursor_fg = beautiful.inputbox_cursor_fg or '#313131'
|
||||
local cursor_bg = beautiful.inputbox_cursor_bg or '#0dccfc'
|
||||
local placeholder_text = self.hint_text or ''
|
||||
local placeholder_fg = beautiful.inputbox_placeholder_fg or '#777777'
|
||||
local highlight_bg = beautiful.inputbox_highlight_bg or '#35ffe4'
|
||||
local highlight_fg = beautiful.inputbox_highlight_fg or '#000000'
|
||||
|
||||
if text == "" then
|
||||
return "<span foreground='" .. placeholder_fg .. "'>" .. placeholder_text .. "</span>"
|
||||
if text == '' then
|
||||
return "<span foreground='" .. placeholder_fg .. "'>" .. placeholder_text .. '</span>'
|
||||
end
|
||||
|
||||
local offset = 0
|
||||
@@ -45,13 +45,13 @@ local function text_with_cursor(text, cursor_pos, self)
|
||||
end
|
||||
|
||||
if #text < cursor_pos then
|
||||
char = " "
|
||||
spacer = ""
|
||||
char = ' '
|
||||
spacer = ''
|
||||
text_start = gstring.xml_escape(text)
|
||||
text_end = ""
|
||||
text_end = ''
|
||||
else
|
||||
char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset))
|
||||
spacer = " "
|
||||
spacer = ' '
|
||||
text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1))
|
||||
text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1))
|
||||
end
|
||||
@@ -65,10 +65,10 @@ local function text_with_cursor(text, cursor_pos, self)
|
||||
|
||||
return text_start_highlight ..
|
||||
"<span foreground='" .. highlight_fg .. "' background='" .. highlight_bg .. "'>" ..
|
||||
text_highlighted .. "</span>" .. text_end_highlight
|
||||
text_highlighted .. '</span>' .. text_end_highlight
|
||||
else
|
||||
return text_start .. "<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
|
||||
char .. "</span>" .. text_end .. spacer
|
||||
char .. '</span>' .. text_end .. spacer
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,23 +90,23 @@ inputbox.set_widget = base.set_widget_common
|
||||
|
||||
--- Clears the current text
|
||||
function inputbox:clear()
|
||||
self:set_text("")
|
||||
self:set_text('')
|
||||
end
|
||||
|
||||
function inputbox:get_text()
|
||||
return self._private.text or ""
|
||||
return self._private.text or ''
|
||||
end
|
||||
|
||||
function inputbox:set_text(text)
|
||||
self._private.text = text
|
||||
self.markup = text_with_cursor(self:get_text(), #self:get_text(), self)
|
||||
self:emit_signal("property::text", text)
|
||||
self:emit_signal('property::text', text)
|
||||
end
|
||||
|
||||
--- Stop the keygrabber and mousegrabber
|
||||
function inputbox:stop()
|
||||
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end
|
||||
self:emit_signal("stopped")
|
||||
self:emit_signal('stopped')
|
||||
self.akeygrabber.stop()
|
||||
end
|
||||
|
||||
@@ -116,16 +116,16 @@ function inputbox:focus()
|
||||
self:run()
|
||||
end
|
||||
|
||||
self:connect_signal("button::press", function()
|
||||
self:connect_signal('button::press', function()
|
||||
if capi.mouse.current_widget ~= self then
|
||||
self:emit_signal("keygrabber::stop", "")
|
||||
self:emit_signal('keygrabber::stop', '')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Init the inputbox and start the keygrabber
|
||||
function inputbox:run()
|
||||
if not self._private.text then self._private.text = "" end
|
||||
if not self._private.text then self._private.text = '' end
|
||||
|
||||
-- Init the cursor position, but causes on refocus the cursor to move to the left
|
||||
local cursor_pos = #self:get_text() + 1
|
||||
@@ -136,24 +136,22 @@ function inputbox:run()
|
||||
self.akeygrabber = akeygrabber {
|
||||
autostart = true,
|
||||
start_callback = function()
|
||||
self:emit_signal("started")
|
||||
self:emit_signal('started')
|
||||
end,
|
||||
stop_callback = function(_, stop_key)
|
||||
if stop_key == "Return" then
|
||||
self:emit_signal("submit", self:get_text(), stop_key)
|
||||
-- Only reset text on enter as on escape you might want to continue later
|
||||
self:set_text("")
|
||||
if stop_key == 'Return' then
|
||||
self:emit_signal('submit', self:get_text(), stop_key)
|
||||
else
|
||||
self:emit_signal("stopped", stop_key)
|
||||
self:emit_signal('stopped', stop_key)
|
||||
end
|
||||
end,
|
||||
stop_key = { "Escape", "Return" },
|
||||
stop_key = { 'Escape', 'Return' },
|
||||
keybindings = {
|
||||
--lShift, rShift = #50, #62
|
||||
--lControl, rControl = #37, #105
|
||||
akey {
|
||||
modifiers = { "Shift" },
|
||||
key = "Left", -- left
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
if cursor_pos > 1 then
|
||||
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0
|
||||
@@ -178,12 +176,12 @@ function inputbox:run()
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Shift", "Left")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Shift" },
|
||||
key = "Right", -- right
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
if #self._private.text >= cursor_pos then
|
||||
if not self._private.highlight.cur_pos_end then
|
||||
@@ -209,29 +207,29 @@ function inputbox:run()
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Shift", "Right")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "a", -- a
|
||||
modifiers = { 'Control' },
|
||||
key = 'a', -- a
|
||||
on_press = function()
|
||||
-- Mark the entire text
|
||||
self._private.highlight = {
|
||||
cur_pos_start = 1,
|
||||
cur_pos_end = #self._private.text
|
||||
cur_pos_end = #self._private.text,
|
||||
}
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Control", "a")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'a')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "v", -- v
|
||||
modifiers = { 'Control' },
|
||||
key = 'v', -- v
|
||||
on_press = function()
|
||||
local sel = capi.selection()
|
||||
if sel then
|
||||
sel = sel:gsub("\n", "")
|
||||
sel = sel:gsub('\n', '')
|
||||
if self._private.highlight and self._private.highlight.cur_pos_start and
|
||||
self._private.highlight.cur_pos_end then
|
||||
-- insert the text into the selected part
|
||||
@@ -248,35 +246,35 @@ function inputbox:run()
|
||||
end
|
||||
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Control", "v")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'v')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "c", -- c
|
||||
modifiers = { 'Control' },
|
||||
key = 'c', -- c
|
||||
on_press = function()
|
||||
--TODO
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "x", -- x
|
||||
modifiers = { 'Control' },
|
||||
key = 'x', -- x
|
||||
on_press = function()
|
||||
--TODO
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "Left", -- left
|
||||
modifiers = { 'Control' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
-- Find all spaces
|
||||
local spaces = {}
|
||||
local t, i = self._private.text, 0
|
||||
|
||||
while t:find("%s") do
|
||||
i = t:find("%s")
|
||||
while t:find('%s') do
|
||||
i = t:find('%s')
|
||||
table.insert(spaces, i)
|
||||
t = t:sub(1, i - 1) .. "-" .. t:sub(i + 1)
|
||||
t = t:sub(1, i - 1) .. '-' .. t:sub(i + 1)
|
||||
end
|
||||
|
||||
local cp = 1
|
||||
@@ -292,14 +290,14 @@ function inputbox:run()
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Control", "Left")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { "Control" },
|
||||
key = "Right", -- right
|
||||
modifiers = { 'Control' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
local next_space = self._private.text:sub(cursor_pos):find("%s")
|
||||
local next_space = self._private.text:sub(cursor_pos):find('%s')
|
||||
if next_space then
|
||||
cursor_pos = cursor_pos + next_space
|
||||
else
|
||||
@@ -312,12 +310,12 @@ function inputbox:run()
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", "Control", "Right")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = "BackSpace", --BackSpace
|
||||
key = 'BackSpace', --BackSpace
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the left
|
||||
if self._private.highlight and self._private.highlight.cur_pos_start and
|
||||
@@ -337,12 +335,12 @@ function inputbox:run()
|
||||
end
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", nil, "BackSpace")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'BackSpace')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = "Delete", --delete
|
||||
key = 'Delete', --delete
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the right
|
||||
if self._private.highlight and self._private.highlight.cur_pos_start and
|
||||
@@ -359,41 +357,41 @@ function inputbox:run()
|
||||
end
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", nil, "Delete")
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'Delete')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = "Left", --left
|
||||
key = 'Left', --left
|
||||
on_press = function()
|
||||
-- Move cursor ro the left
|
||||
if cursor_pos > 1 then
|
||||
cursor_pos = cursor_pos - 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = "Right", --right
|
||||
key = 'Right', --right
|
||||
on_press = function()
|
||||
-- Move cursor to the right
|
||||
if cursor_pos <= #self._private.text then
|
||||
cursor_pos = cursor_pos + 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end
|
||||
end,
|
||||
},
|
||||
--self.keybindings
|
||||
},
|
||||
keypressed_callback = function(_, modifiers, key)
|
||||
if modifiers[1] == "Shift" then
|
||||
if modifiers[1] == 'Shift' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
string.upper(key) .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #key
|
||||
end
|
||||
elseif modifiers[1] == "Mod2" or "" then
|
||||
elseif modifiers[1] == 'Mod2' or '' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
key .. self._private.text:sub(cursor_pos))
|
||||
@@ -407,8 +405,8 @@ function inputbox:run()
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
|
||||
self:emit_signal("inputbox::key_pressed", modifiers, key)
|
||||
end
|
||||
self:emit_signal('inputbox::key_pressed', modifiers, key)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -426,6 +424,7 @@ end
|
||||
-- @treturn awful.widget.inputbox The inputbox widget.
|
||||
-- @constructorfct awful.widget.inputbox
|
||||
function inputbox.new(args)
|
||||
args = args or {}
|
||||
-- directly pass a possible default text(this is not meant to be a hint)
|
||||
local w = textbox()
|
||||
|
||||
@@ -437,7 +436,7 @@ function inputbox.new(args)
|
||||
w.keybindings = args.keybindings or {}
|
||||
w.hint_text = args.hint_text
|
||||
|
||||
w.markup = args.text or text_with_cursor("", 1, w)
|
||||
w.markup = args.text or text_with_cursor('', 1, w)
|
||||
return w
|
||||
end
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local gtable = require("gears.table")
|
||||
local gcolor = require("gears.color")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
local gshape = require("gears.shape")
|
||||
local rubato = require("src.lib.rubato")
|
||||
local abutton = require("awful.button")
|
||||
local base = require('wibox.widget.base')
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gshape = require('gears.shape')
|
||||
local rubato = require('src.lib.rubato')
|
||||
local abutton = require('awful.button')
|
||||
|
||||
local toggle_widget = { mt = {} }
|
||||
|
||||
@@ -52,7 +52,7 @@ function toggle_widget:toggle_animation(pos, color)
|
||||
cr:move_to(pos, 0)
|
||||
local x = pos
|
||||
local y = 5
|
||||
local newwidth = width / 2 - 10
|
||||
local newwidth = width / 2 - 6
|
||||
local newheight = height - 10
|
||||
|
||||
local radius = height / 6.0
|
||||
@@ -88,7 +88,7 @@ function toggle_widget.new(args)
|
||||
end,
|
||||
draw = ret:toggle_animation(0, ret.newcolor),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
},
|
||||
active = false,
|
||||
widget = wibox.container.background,
|
||||
@@ -106,9 +106,9 @@ function toggle_widget.new(args)
|
||||
duration = 0.2,
|
||||
pos = 5,
|
||||
subscribed = function(pos)
|
||||
ret.toggle_button:get_children_by_id("background")[1].draw = ret:toggle_animation(pos, ret.newcolor)
|
||||
ret.toggle_button:emit_signal("widget::redraw_needed")
|
||||
end
|
||||
ret.toggle_button:get_children_by_id('background')[1].draw = ret:toggle_animation(pos, ret.newcolor)
|
||||
ret.toggle_button:emit_signal('widget::redraw_needed')
|
||||
end,
|
||||
}
|
||||
|
||||
ret:set_widget(wibox.widget {
|
||||
@@ -116,27 +116,27 @@ function toggle_widget.new(args)
|
||||
{
|
||||
args.text and {
|
||||
text = args.text,
|
||||
valign = "center",
|
||||
align = "center",
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = "clearall"
|
||||
id = 'clearall',
|
||||
} or nil,
|
||||
ret.toggle_button,
|
||||
spacing = args.text and dpi(10) or dpi(0),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "layout12"
|
||||
id = 'layout12',
|
||||
},
|
||||
id = "background4",
|
||||
id = 'background4',
|
||||
fg = args.fg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "place",
|
||||
id = 'place',
|
||||
widget = wibox.container.place,
|
||||
valign = "bottom",
|
||||
halign = "right",
|
||||
valign = 'bottom',
|
||||
halign = 'right',
|
||||
})
|
||||
|
||||
ret.toggle_button:buttons(
|
||||
@@ -147,7 +147,7 @@ function toggle_widget.new(args)
|
||||
else
|
||||
ret:set_enabled()
|
||||
end
|
||||
ret:emit_signal("dnd::toggle", ret.active)
|
||||
ret:emit_signal('dnd::toggle', ret.active)
|
||||
end
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,12 +1,40 @@
|
||||
---@diagnostic disable: lowercase-global
|
||||
-----------------------------------------------------------------------------------------
|
||||
-- █████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███╗ ███╗███████╗██╗ ██╗███╗ ███╗ --
|
||||
-- ██╔══██╗██║ ██║██╔════╝██╔════╝██╔═══██╗████╗ ████║██╔════╝██║ ██║████╗ ████║ --
|
||||
-- ███████║██║ █╗ ██║█████╗ ███████╗██║ ██║██╔████╔██║█████╗ ██║ █╗ ██║██╔████╔██║ --
|
||||
-- ██╔══██║██║███╗██║██╔══╝ ╚════██║██║ ██║██║╚██╔╝██║██╔══╝ ██║███╗██║██║╚██╔╝██║ --
|
||||
-- ██║ ██║╚███╔███╔╝███████╗███████║╚██████╔╝██║ ╚═╝ ██║███████╗╚███╔███╔╝██║ ╚═╝ ██║ --
|
||||
-- ╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ --
|
||||
-----------------------------------------------------------------------------------------
|
||||
--[[
|
||||
|
||||
╭─────────────────────────────────────────────────────────────────╮
|
||||
│ ______ ___ ________ │
|
||||
│ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ │
|
||||
│ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ │
|
||||
│ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ │
|
||||
│ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ │
|
||||
│ /____/ │
|
||||
╰─────────────────────────────────────────────────────────────────╯
|
||||
|
||||
]]
|
||||
--#region prints
|
||||
io.stdout:write([[
|
||||
]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ /____/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[╰─────────────────────────────────────────────────────────────────╯
|
||||
]] .. '\27[0m\n')
|
||||
|
||||
io.stderr:write([[
|
||||
]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ /____/ ]] .. '\27[32m' .. [[│
|
||||
]] .. '\27[32m' .. [[╰─────────────────────────────────────────────────────────────────╯
|
||||
]] .. '\27[0m\n')
|
||||
--#endregion
|
||||
|
||||
-- Initialising, order is important!
|
||||
awesome = awesome
|
||||
client = client
|
||||
@@ -20,18 +48,20 @@ tag = tag
|
||||
-- Do not touch as this is used to share some variable settings files
|
||||
Global_config = {}
|
||||
|
||||
require("src.core.error_handling")
|
||||
require("src.theme.user_config")
|
||||
require("src.theme.theme_config")
|
||||
require("src.tools.gio_icon_lookup")
|
||||
require("src.theme.init")
|
||||
require("src.tools.hex_to_rgba")
|
||||
require("src.core.signals")
|
||||
require("src.core.notifications")
|
||||
require("src.core.rules")
|
||||
require("src.bindings.global_buttons")
|
||||
require("src.bindings.bind_to_tags")
|
||||
require("src.modules.init")
|
||||
require("src.tools.auto_starter")(User_config.autostart)
|
||||
require('src.core.error_handling')
|
||||
require('src.theme.user_config')
|
||||
require('src.theme.theme_config')
|
||||
require('src.tools.gio_icon_lookup')
|
||||
require('src.theme.init')
|
||||
require('src.tools.hex_to_rgba')
|
||||
require('src.core.signals')
|
||||
require('src.core.notifications')
|
||||
require('src.core.rules')
|
||||
require('src.bindings.global_buttons')
|
||||
require('src.bindings.bind_to_tags')
|
||||
require('src.modules.init')
|
||||
--require('src.tools.auto_starter')(User_config.autostart)
|
||||
|
||||
require("src.config.setup")()
|
||||
--require('src.core.setup')()
|
||||
|
||||
--require('src.tools.helpers.pulseaudio')()
|
||||
|
||||
1
awesome/src/assets/CT.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="ct" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"><defs><linearGradient id="ct-s-path1-stroke" x1="-0.024162" y1="0.504999" x2="0.975838" y2="0.504455" spreadMethod="pad" gradientUnits="objectBoundingBox" gradientTransform="translate(0 0)"><stop id="ct-s-path1-stroke-0" offset="0%" stop-color="#faa3ff"/><stop id="ct-s-path1-stroke-1" offset="50%" stop-color="#ffd9fd"/><stop id="ct-s-path1-stroke-2" offset="100%" stop-color="#7ef2ff"/></linearGradient></defs><path id="ct-s-path1" d="M281.200226,185.600197L215.59979,316.799803L346.800008,316.8l-32.800004,65.6h-131.200023l-32.800005-65.600197L248.400073,120h196.799951h196.799951l-32.800004,65.6h-65.600012L461.599945,382.4h-65.600011l85.280014-196.799803-68.470031.000003L445.200024,120l-32.390106,65.6h-131.609692" transform="translate(-139.999975-.535)" fill="#fff" fill-opacity="0" stroke="url(#ct-s-path1-stroke)" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" stroke-dashoffset="5"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 20 KiB |
4
awesome/src/assets/icons/notifications/close.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#00000000">
|
||||
<path d="M0 0h24v24H0z" />
|
||||
<path fill="#ef9a9a" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 273 B |
BIN
awesome/src/assets/icons/setup/titlebar_left.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
awesome/src/assets/icons/setup/titlebar_top.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
awesome/src/assets/icons/start.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 310 KiB |
BIN
awesome/src/assets/userpfp/userpfp.png
Normal file
|
After Width: | Height: | Size: 305 KiB |
@@ -1,7 +1,12 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local globalkeys = require("src.bindings.global_keys")
|
||||
local akey = require('awful.key')
|
||||
local ascreen = require('awful.screen')
|
||||
local atag = require('awful.tag')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
-- Local libs
|
||||
local globalkeys = require('src.bindings.global_keys')
|
||||
|
||||
local modkey = User_config.modkey
|
||||
|
||||
local capi = {
|
||||
@@ -10,63 +15,34 @@ local capi = {
|
||||
}
|
||||
|
||||
for i = 1, 9 do
|
||||
globalkeys = gears.table.join(globalkeys,
|
||||
globalkeys = gtable.join(globalkeys,
|
||||
akey({ modkey }, '#' .. i + 9, function()
|
||||
local screen = ascreen.focused()
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
tag:view_only()
|
||||
end
|
||||
capi.client.emit_signal('tag::switched')
|
||||
end, { description = 'Switch to tag ' .. i, group = 'Tag' }),
|
||||
|
||||
-- View tag only
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#" .. i + 9,
|
||||
akey({ modkey, 'Control' }, '#' .. i + 9,
|
||||
function()
|
||||
local screen = awful.screen.focused()
|
||||
local screen = ascreen.focused()
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
tag:view_only()
|
||||
atag.viewtoggle(tag)
|
||||
end
|
||||
capi.client.emit_signal("tag::switched")
|
||||
end,
|
||||
{ description = "View Tag " .. i, group = "Tag" }
|
||||
),
|
||||
-- Brings the window over without chaning the tag, reverts automatically on tag change
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#" .. i + 9,
|
||||
function()
|
||||
local screen = awful.screen.focused()
|
||||
end, { description = 'View tag ' .. i, group = 'Tag' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#' .. i + 9, function()
|
||||
local screen = ascreen.focused()
|
||||
if capi.client.focus then
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
awful.tag.viewtoggle(tag)
|
||||
capi.client.focus:move_to_tag(tag)
|
||||
end
|
||||
end,
|
||||
{ description = "Toggle Tag " .. i, group = "Tag" }
|
||||
),
|
||||
-- Brings the window over without chaning the tag, reverts automatically on tag change
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#" .. i + 9,
|
||||
function()
|
||||
local screen = awful.screen.focused()
|
||||
if capi.client.focus then
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
capi.client.focus:move_to_tag(tag)
|
||||
end
|
||||
end
|
||||
end,
|
||||
{ description = "Move focused client on tag " .. i, group = "Tag" }
|
||||
),
|
||||
-- Brings the window over without chaning the tag, reverts automatically on tag change
|
||||
awful.key(
|
||||
{ modkey, "Control", "Shift" },
|
||||
"#" .. i + 9,
|
||||
function()
|
||||
local screen = awful.screen.focused()
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
awful.tag.viewtoggle(tag)
|
||||
end
|
||||
end,
|
||||
{ description = "Move focused client on tag " .. i, group = "Tag" }
|
||||
)
|
||||
end
|
||||
end, { description = 'Move focused client to tag ' .. i, group = 'Tag' })
|
||||
)
|
||||
end
|
||||
capi.root.keys(globalkeys)
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local abutton = require('awful.button')
|
||||
local gtable = require('gears.table')
|
||||
local amouse = require('awful.mouse')
|
||||
|
||||
local modkey = User_config.modkey
|
||||
|
||||
return gears.table.join(
|
||||
awful.button({}, 1, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
return gtable.join {
|
||||
abutton({}, 1, function(c)
|
||||
c:emit_signal('request::activate', 'mouse_click', { raise = true })
|
||||
end),
|
||||
awful.button({ modkey }, 1, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
awful.mouse.client.move(c)
|
||||
abutton({ modkey }, 1, function(c)
|
||||
c:emit_signal('request::activate', 'mouse_click', { raise = true })
|
||||
amouse.client.move(c)
|
||||
end),
|
||||
awful.button({ modkey }, 3, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
awful.mouse.client.resize(c)
|
||||
end)
|
||||
)
|
||||
abutton({ modkey }, 3, function(c)
|
||||
c:emit_signal('request::activate', 'mouse_click', { raise = true })
|
||||
amouse.client.resize(c)
|
||||
end),
|
||||
}
|
||||
|
||||
@@ -1,61 +1,156 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
|
||||
local capi = {
|
||||
client = client
|
||||
}
|
||||
local aclient = require('awful.client')
|
||||
local akey = require('awful.key')
|
||||
local ascreen = require('awful.screen')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local modkey = User_config.modkey
|
||||
|
||||
return gears.table.join(
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#41",
|
||||
function(c)
|
||||
c.fullscreen = not c.fullscreen
|
||||
c:raise()
|
||||
end,
|
||||
{ description = "Toggle fullscreen", group = "Client" }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#24",
|
||||
function(c)
|
||||
c:kill()
|
||||
end,
|
||||
{ description = "Close focused client", group = "Client" }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#42",
|
||||
awful.client.floating.toggle,
|
||||
{ description = "Toggle floating window", group = "Client" }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#58",
|
||||
function(c)
|
||||
c.maximized = not c.maximized
|
||||
c:raise()
|
||||
end,
|
||||
{ description = "(un)maximize", group = "Client" }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey },
|
||||
"#57",
|
||||
function(c)
|
||||
if c == capi.client.focus then
|
||||
c.minimized = true
|
||||
else
|
||||
c.minimized = false
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end
|
||||
end,
|
||||
{ description = "(un)hide", group = "Client" }
|
||||
)
|
||||
return gtable.join(
|
||||
--#region Basic interactions
|
||||
akey({ modkey }, '#24', function(c)
|
||||
c:kill()
|
||||
end, { description = 'Close client', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#41', function(c)
|
||||
c.fullscreen = not c.fullscreen
|
||||
c:raise()
|
||||
end, { description = 'Toggle fullscreen', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#42',
|
||||
aclient.floating.toggle,
|
||||
{ description = 'Toggle floating', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#57', function(c)
|
||||
c.minimized = true
|
||||
end, { description = 'Minimize', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#58', function(c)
|
||||
c.maximized = not c.maximized
|
||||
c:raise()
|
||||
end, { description = 'Toggle maximize', group = 'Client' }),
|
||||
--#endregion
|
||||
|
||||
--#region Client focus movement
|
||||
akey({ modkey }, '#44', function(c)
|
||||
aclient.focus.global_bydirection('up', c)
|
||||
end, { description = 'Move client a screen up', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#111', function(c)
|
||||
aclient.focus.global_bydirection('up', c)
|
||||
end, { description = 'Move client a screen up', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#43', function(c)
|
||||
aclient.focus.global_bydirection('left', c)
|
||||
end, { description = 'Move client a screen left', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#113', function(c)
|
||||
aclient.focus.global_bydirection('left', c)
|
||||
end, { description = 'Move client a screen left', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#46', function(c)
|
||||
aclient.focus.global_bydirection('right', c)
|
||||
end, { description = 'Move client a screen right', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#114', function(c)
|
||||
aclient.focus.global_bydirection('right', c)
|
||||
end, { description = 'Move client a screen right', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#45', function(c)
|
||||
aclient.focus.global_bydirection('down', c)
|
||||
end, { description = 'Move client a screen down', group = 'Client' }),
|
||||
|
||||
akey({ modkey }, '#116', function(c)
|
||||
aclient.focus.global_bydirection('down', c)
|
||||
end, { description = 'Move client a screen down', group = 'Client' }),
|
||||
--#endregion
|
||||
|
||||
--#region Screen movement
|
||||
akey({ modkey, 'Shift' }, '#44', function(c)
|
||||
local s = ascreen.focus_bydirection('Up', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen up', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#111', function(c)
|
||||
local s = ascreen.focus_bydirection('Up', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
c:activate {
|
||||
--switch_to_tag = true,
|
||||
raise = true,
|
||||
context = 'somet_reason',
|
||||
}
|
||||
end, { description = 'Move client a screen up', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#43', function(c)
|
||||
c:move_to_screen(ascreen.focus_bydirection('left', c.screen))
|
||||
c.first_tag:view_only()
|
||||
client.focus = c
|
||||
c:raise()
|
||||
c:activate {
|
||||
--switch_to_tag = true,
|
||||
raise = true,
|
||||
context = 'somet_reason',
|
||||
}
|
||||
end, { description = 'Move client a screen left', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#113', function(c)
|
||||
local s = ascreen.focus_bydirection('left', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen left', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#46', function(c)
|
||||
local s = ascreen.focus_bydirection('Right', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen right', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#114', function(c)
|
||||
local s = ascreen.focus_bydirection('Right', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen right', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#45', function(c)
|
||||
local s = ascreen.focus_bydirection('Down', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen down', group = 'Client' }),
|
||||
|
||||
akey({ modkey, 'Shift' }, '#116', function(c)
|
||||
local s = ascreen.focus_bydirection('Down', c.screen)
|
||||
c:move_to_screen(s)
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
end
|
||||
c:emit_signal('request::activate')
|
||||
c:raise()
|
||||
end, { description = 'Move client a screen down', group = 'Client' })
|
||||
--#endregion
|
||||
)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
-- Awesome Libs
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local gtable = require('gears.table')
|
||||
local abutton = require('awful.button')
|
||||
local atag = require('awful.tag')
|
||||
|
||||
local capi = {
|
||||
root = root
|
||||
}
|
||||
|
||||
capi.root.buttons = gears.table.join(
|
||||
awful.button({}, 4, awful.tag.viewnext),
|
||||
awful.button({}, 5, awful.tag.viewprev)
|
||||
capi.root.buttons = gtable.join(
|
||||
abutton({}, 4, atag.viewnext),
|
||||
abutton({}, 5, atag.viewprev)
|
||||
)
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
-- Awesome libs
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local hotkeys_popup = require("awful.hotkeys_popup")
|
||||
local ruled = require("ruled")
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local akey = require('awful.key')
|
||||
local gtable = require('gears.table')
|
||||
local atag = require('awful.tag')
|
||||
local aclient = require('awful.client')
|
||||
local aspawn = require('awful.spawn')
|
||||
local alayout = require('awful.layout')
|
||||
local ascreen = require('awful.screen')
|
||||
local hotkeys_popup = require('awful.hotkeys_popup')
|
||||
local ruled = require('ruled')
|
||||
|
||||
-- Third party libs
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
-- Local libs
|
||||
local config = require('src.tools.config')
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
local backlight_helper = require('src.tools.helpers.backlight')
|
||||
local powermenu = require('src.modules.powermenu.init')
|
||||
local kb_helper = require('src.tools.helpers.kb_helper')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -15,301 +25,290 @@ local capi = {
|
||||
|
||||
local modkey = User_config.modkey
|
||||
|
||||
awful.keygrabber {
|
||||
keybindings = {
|
||||
awful.key {
|
||||
modifiers = { "Mod1" },
|
||||
key = "Tab",
|
||||
akeygrabber {
|
||||
keybindings = {
|
||||
akey {
|
||||
modifiers = { 'Mod1' },
|
||||
key = 'Tab',
|
||||
on_press = function()
|
||||
capi.awesome.emit_signal("window_switcher::select_next")
|
||||
end
|
||||
}
|
||||
capi.awesome.emit_signal('window_switcher::select_next')
|
||||
end,
|
||||
},
|
||||
},
|
||||
root_keybindings = {
|
||||
awful.key {
|
||||
modifiers = { "Mod1" },
|
||||
key = "Tab",
|
||||
root_keybindings = {
|
||||
akey {
|
||||
modifiers = { 'Mod1' },
|
||||
key = 'Tab',
|
||||
on_press = function()
|
||||
end
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
stop_key = "Mod1",
|
||||
stop_event = "release",
|
||||
start_callback = function()
|
||||
capi.awesome.emit_signal("toggle_window_switcher")
|
||||
stop_key = 'Mod1',
|
||||
stop_event = 'release',
|
||||
start_callback = function()
|
||||
capi.awesome.emit_signal('toggle_window_switcher')
|
||||
end,
|
||||
stop_callback = function()
|
||||
capi.awesome.emit_signal("window_switcher::raise")
|
||||
capi.awesome.emit_signal("toggle_window_switcher")
|
||||
stop_callback = function()
|
||||
capi.awesome.emit_signal('window_switcher::raise')
|
||||
capi.awesome.emit_signal('toggle_window_switcher')
|
||||
end,
|
||||
export_keybindings = true,
|
||||
}
|
||||
|
||||
return gears.table.join(
|
||||
awful.key(
|
||||
return gtable.join(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#39",
|
||||
'#39',
|
||||
hotkeys_popup.show_help,
|
||||
{ description = "Cheat sheet", group = "Awesome" }
|
||||
{ description = 'Cheat sheet', group = 'Awesome' }
|
||||
),
|
||||
-- Tag browsing
|
||||
awful.key(
|
||||
--[[ akey(
|
||||
{ modkey },
|
||||
"#113",
|
||||
awful.tag.viewprev,
|
||||
{ description = "View previous tag", group = "Tag" }
|
||||
'#113',
|
||||
atag.viewprev,
|
||||
{ description = 'View previous tag', group = 'Tag' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#114",
|
||||
awful.tag.viewnext,
|
||||
{ description = "View next tag", group = "Tag" }
|
||||
),
|
||||
awful.key(
|
||||
'#114',
|
||||
atag.viewnext,
|
||||
{ description = 'View next tag', group = 'Tag' }
|
||||
), ]]
|
||||
akey(
|
||||
{ modkey },
|
||||
"#66",
|
||||
awful.tag.history.restore,
|
||||
{ description = "Go back to last tag", group = "Tag" }
|
||||
'#66',
|
||||
atag.history.restore,
|
||||
{ description = 'Go back to last tag', group = 'Tag' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#44",
|
||||
'#44',
|
||||
function()
|
||||
awful.client.focus.byidx(1)
|
||||
aclient.focus.byidx(1)
|
||||
end,
|
||||
{ description = "Focus next client by index", group = "Client" }
|
||||
{ description = 'Focus next client by index', group = 'Client' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#45",
|
||||
'#45',
|
||||
function()
|
||||
awful.client.focus.byidx(-1)
|
||||
aclient.focus.byidx(-1)
|
||||
end,
|
||||
{ description = "Focus previous client by index", group = "Client" }
|
||||
{ description = 'Focus previous client by index', group = 'Client' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#44",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#44',
|
||||
function()
|
||||
awful.client.swap.byidx(1)
|
||||
aclient.swap.byidx(1)
|
||||
end,
|
||||
{ description = "Swap with next client by index", group = "Client" }
|
||||
{ description = 'Swap with next client by index', group = 'Client' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#45",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#45',
|
||||
function()
|
||||
awful.client.swap.byidx(-1)
|
||||
aclient.swap.byidx(-1)
|
||||
end,
|
||||
{ description = "Swap with previous client by index", group = "Client" }
|
||||
{ description = 'Swap with previous client by index', group = 'Client' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#44",
|
||||
akey(
|
||||
{ modkey, 'Control' },
|
||||
'#44',
|
||||
function()
|
||||
awful.screen.focus_relative(1)
|
||||
ascreen.focus_relative(1)
|
||||
end,
|
||||
{ description = "Focus the next screen", group = "Screen" }
|
||||
{ description = 'Focus the next screen', group = 'Screen' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#45",
|
||||
akey(
|
||||
{ modkey, 'Control' },
|
||||
'#45',
|
||||
function()
|
||||
awful.screen.focus_relative(-1)
|
||||
ascreen.focus_relative(-1)
|
||||
end,
|
||||
{ description = "Focus the previous screen", group = "Screen" }
|
||||
{ description = 'Focus the previous screen', group = 'Screen' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#30",
|
||||
awful.client.urgent.jumpto,
|
||||
{ description = "Jump to urgent client", group = "Client" }
|
||||
'#30',
|
||||
aclient.urgent.jumpto,
|
||||
{ description = 'Jump to urgent client', group = 'Client' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#36",
|
||||
'#36',
|
||||
function()
|
||||
awful.spawn(User_config.terminal)
|
||||
aspawn(User_config.terminal)
|
||||
end,
|
||||
{ description = "Open terminal", group = "Applications" }
|
||||
{ description = 'Open terminal', group = 'Applications' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#27",
|
||||
akey(
|
||||
{ modkey, 'Control' },
|
||||
'#27',
|
||||
capi.awesome.restart,
|
||||
{ description = "Reload awesome", group = "Awesome" }
|
||||
{ description = 'Reload awesome', group = 'Awesome' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#46",
|
||||
'#46',
|
||||
function()
|
||||
awful.tag.incmwfact(0.05)
|
||||
atag.incmwfact(0.05)
|
||||
end,
|
||||
{ description = "Increase client width", group = "Layout" }
|
||||
{ description = 'Increase client width', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#43",
|
||||
'#43',
|
||||
function()
|
||||
awful.tag.incmwfact(-0.05)
|
||||
atag.incmwfact(-0.05)
|
||||
end,
|
||||
{ description = "Decrease client width", group = "Layout" }
|
||||
{ description = 'Decrease client width', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#43",
|
||||
akey(
|
||||
{ modkey, 'Control' },
|
||||
'#43',
|
||||
function()
|
||||
awful.tag.incncol(1, nil, true)
|
||||
atag.incncol(1, nil, true)
|
||||
end,
|
||||
{ description = "Increase the number of columns", group = "Layout" }
|
||||
{ description = 'Increase the number of columns', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"#46",
|
||||
akey(
|
||||
{ modkey, 'Control' },
|
||||
'#46',
|
||||
function()
|
||||
awful.tag.incncol(-1, nil, true)
|
||||
atag.incncol(-1, nil, true)
|
||||
end,
|
||||
{ description = "Decrease the number of columns", group = "Layout" }
|
||||
{ description = 'Decrease the number of columns', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#65",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#65',
|
||||
function()
|
||||
awful.layout.inc(-1)
|
||||
alayout.inc(-1)
|
||||
end,
|
||||
{ description = "Select previous layout", group = "Layout" }
|
||||
{ description = 'Select previous layout', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#36",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#36',
|
||||
function()
|
||||
awful.layout.inc(1)
|
||||
alayout.inc(1)
|
||||
end,
|
||||
{ description = "Select next layout", group = "Layout" }
|
||||
{ description = 'Select next layout', group = 'Layout' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#40",
|
||||
'#40',
|
||||
function()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
end,
|
||||
{ descripton = "Application launcher", group = "Application" }
|
||||
{ descripton = 'Application launcher', group = 'Application' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#26",
|
||||
'#26',
|
||||
function()
|
||||
awful.spawn(User_config.file_manager)
|
||||
aspawn(User_config.file_manager)
|
||||
end,
|
||||
{ descripton = "Open file manager", group = "System" }
|
||||
{ descripton = 'Open file manager', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#26",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#26',
|
||||
function()
|
||||
capi.awesome.emit_signal("module::powermenu:show")
|
||||
powermenu:toggle()
|
||||
end,
|
||||
{ descripton = "Session options", group = "System" }
|
||||
{ descripton = 'Session options', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"#107",
|
||||
'#107',
|
||||
function()
|
||||
awful.spawn(User_config.screenshot_program)
|
||||
aspawn(User_config.screenshot_program)
|
||||
end,
|
||||
{ description = "Screenshot", group = "Applications" }
|
||||
{ description = 'Screenshot', group = 'Applications' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioLowerVolume",
|
||||
'XF86AudioLowerVolume',
|
||||
function(c)
|
||||
awful.spawn.easy_async_with_shell("pactl set-sink-volume @DEFAULT_SINK@ -2%", function()
|
||||
capi.awesome.emit_signal("widget::volume_osd:rerun")
|
||||
end)
|
||||
audio_helper.sink_volume_down()
|
||||
end,
|
||||
{ description = "Lower volume", group = "System" }
|
||||
{ description = 'Lower volume', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioRaiseVolume",
|
||||
'XF86AudioRaiseVolume',
|
||||
function(c)
|
||||
awful.spawn.easy_async_with_shell("pactl set-sink-volume @DEFAULT_SINK@ +2%", function()
|
||||
capi.awesome.emit_signal("widget::volume_osd:rerun")
|
||||
end)
|
||||
audio_helper.sink_volume_up()
|
||||
end,
|
||||
{ description = "Increase volume", group = "System" }
|
||||
{ description = 'Increase volume', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioMute",
|
||||
'XF86AudioMute',
|
||||
function(c)
|
||||
awful.spawn("pactl set-sink-mute @DEFAULT_SINK@ toggle")
|
||||
capi.awesome.emit_signal("widget::volume_osd:rerun")
|
||||
audio_helper.sink_toggle_mute()
|
||||
end,
|
||||
{ description = "Mute volume", group = "System" }
|
||||
{ description = 'Mute volume', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86MonBrightnessUp",
|
||||
'XF86MonBrightnessUp',
|
||||
function(c)
|
||||
backlight_helper.brightness_increase()
|
||||
end,
|
||||
{ description = "Raise backlight brightness", group = "System" }
|
||||
{ description = 'Raise backlight brightness', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86MonBrightnessDown",
|
||||
'XF86MonBrightnessDown',
|
||||
function(c)
|
||||
backlight_helper.brightness_decrease()
|
||||
end,
|
||||
{ description = "Lower backlight brightness", group = "System" }
|
||||
{ description = 'Lower backlight brightness', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioPlay",
|
||||
'XF86AudioPlay',
|
||||
function(c)
|
||||
awful.spawn("playerctl play-pause")
|
||||
aspawn('playerctl play-pause')
|
||||
end,
|
||||
{ description = "Play / Pause audio", group = "System" }
|
||||
{ description = 'Play / Pause audio', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioNext",
|
||||
'XF86AudioNext',
|
||||
function(c)
|
||||
awful.spawn("playerctl next")
|
||||
aspawn('playerctl next')
|
||||
end,
|
||||
{ description = "Play / Pause audio", group = "System" }
|
||||
{ description = 'Play / Pause audio', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{},
|
||||
"XF86AudioPrev",
|
||||
'XF86AudioPrev',
|
||||
function(c)
|
||||
awful.spawn("playerctl previous")
|
||||
aspawn('playerctl previous')
|
||||
end,
|
||||
{ description = "Play / Pause audio", group = "System" }
|
||||
{ description = 'Play / Pause audio', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#65",
|
||||
'#65',
|
||||
function()
|
||||
capi.awesome.emit_signal("kblayout::toggle")
|
||||
kb_helper:cycle_layout()
|
||||
end,
|
||||
{ description = "Toggle keyboard layout", group = "System" }
|
||||
{ description = 'Cycle keyboard layout', group = 'System' }
|
||||
),
|
||||
awful.key(
|
||||
akey(
|
||||
{ modkey },
|
||||
"#22",
|
||||
'#22',
|
||||
function()
|
||||
capi.mousegrabber.run(
|
||||
function(m)
|
||||
if m.buttons[1] then
|
||||
|
||||
local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r")
|
||||
if not handler then return end
|
||||
local data_table = json:decode(handler:read("a")) or {}
|
||||
handler:close()
|
||||
|
||||
if type(data_table) ~= "table" then return end
|
||||
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
|
||||
if type(data) ~= 'table' then return end
|
||||
|
||||
local c = capi.mouse.current_client
|
||||
if not c then return end
|
||||
@@ -320,8 +319,8 @@ return gears.table.join(
|
||||
WM_INSTANCE = c.instance,
|
||||
}
|
||||
|
||||
-- Check if data_table already had the client then return
|
||||
for _, v in ipairs(data_table) do
|
||||
-- Check if data already had the client then return
|
||||
for _, v in ipairs(data) do
|
||||
if v.WM_NAME == client_data.WM_NAME and
|
||||
v.WM_CLASS == client_data.WM_CLASS and
|
||||
v.WM_INSTANCE == client_data.WM_INSTANCE then
|
||||
@@ -329,43 +328,33 @@ return gears.table.join(
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(data_table, client_data)
|
||||
table.insert(data, client_data)
|
||||
|
||||
ruled.client.append_rule {
|
||||
rule = { class = c.class, instance = c.instance },
|
||||
properties = {
|
||||
floating = true
|
||||
floating = true,
|
||||
},
|
||||
}
|
||||
c.floating = true
|
||||
|
||||
handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "w")
|
||||
if not handler then return end
|
||||
handler:write(json:encode(data_table))
|
||||
handler:close()
|
||||
config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data)
|
||||
capi.mousegrabber.stop()
|
||||
end
|
||||
return true
|
||||
end,
|
||||
"crosshair"
|
||||
'crosshair'
|
||||
)
|
||||
end
|
||||
),
|
||||
awful.key(
|
||||
{ modkey, "Shift" },
|
||||
"#22",
|
||||
akey(
|
||||
{ modkey, 'Shift' },
|
||||
'#22',
|
||||
function()
|
||||
capi.mousegrabber.run(
|
||||
function(m)
|
||||
if m.buttons[1] then
|
||||
|
||||
local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r")
|
||||
if not handler then return end
|
||||
local data_table = json:decode(handler:read("a")) or {}
|
||||
handler:close()
|
||||
|
||||
if type(data_table) ~= "table" then return end
|
||||
|
||||
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
|
||||
local c = capi.mouse.current_client
|
||||
if not c then return end
|
||||
|
||||
@@ -376,14 +365,14 @@ return gears.table.join(
|
||||
}
|
||||
|
||||
-- Remove client_data from data_table
|
||||
for k, v in ipairs(data_table) do
|
||||
for k, v in ipairs(data) do
|
||||
if v.WM_CLASS == client_data.WM_CLASS and
|
||||
v.WM_INSTANCE == client_data.WM_INSTANCE then
|
||||
table.remove(data_table, k)
|
||||
table.remove(data, k)
|
||||
ruled.client.remove_rule {
|
||||
rule = { class = c.class, instance = c.instance },
|
||||
properties = {
|
||||
floating = true
|
||||
floating = true,
|
||||
},
|
||||
}
|
||||
c.floating = false
|
||||
@@ -391,15 +380,12 @@ return gears.table.join(
|
||||
end
|
||||
end
|
||||
|
||||
handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "w")
|
||||
if not handler then return end
|
||||
handler:write(json:encode(data_table))
|
||||
handler:close()
|
||||
config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data)
|
||||
capi.mousegrabber.stop()
|
||||
end
|
||||
return true
|
||||
end,
|
||||
"crosshair"
|
||||
'crosshair'
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
@@ -2,33 +2,38 @@
|
||||
-- This class is to output an error if you fuck up the config --
|
||||
----------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local naughty = require("naughty")
|
||||
local naughty = require('naughty')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
if capi.awesome.startup_errors then
|
||||
naughty.notify({ preset = naughty.config.presets.critical,
|
||||
title = "Oops, there were errors during startup!",
|
||||
text = capi.awesome.startup_errors })
|
||||
naughty.notify { preset = naughty.config.presets.critical,
|
||||
title = 'Oops, there were errors during startup!',
|
||||
text = capi.awesome.startup_errors,
|
||||
gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg',
|
||||
}
|
||||
end
|
||||
|
||||
do
|
||||
local in_error = false
|
||||
capi.awesome.connect_signal(
|
||||
"debug::error",
|
||||
'debug::error',
|
||||
function(err)
|
||||
if in_error then
|
||||
return
|
||||
end
|
||||
in_error = true
|
||||
|
||||
naughty.notify({
|
||||
naughty.notification {
|
||||
preset = naughty.config.presets.critical,
|
||||
title = "ERROR",
|
||||
text = tostring(err)
|
||||
})
|
||||
title = 'ERROR',
|
||||
app_name = 'System Notification',
|
||||
message = tostring(err),
|
||||
icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg',
|
||||
}
|
||||
in_error = false
|
||||
end
|
||||
)
|
||||
|
||||
@@ -2,347 +2,331 @@
|
||||
-- The Notification defaults --
|
||||
-------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local menubar = require('menubar')
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local rubato = require("src.lib.rubato")
|
||||
local aspawn = require('awful.spawn')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local naughty = require('naughty')
|
||||
local wibox = require('wibox')
|
||||
local abutton = require('awful.button')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
client = client,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
naughty.config.defaults.ontop = true
|
||||
naughty.config.defaults.icon_size = dpi(80)
|
||||
naughty.config.defaults.timeout = Theme_config.notification.timeout
|
||||
naughty.config.defaults.title = "System Notification"
|
||||
naughty.config.defaults.timeout = 5
|
||||
naughty.config.defaults.title = 'System Notification'
|
||||
naughty.config.defaults.margin = dpi(10)
|
||||
naughty.config.defaults.position = Theme_config.notification.position
|
||||
naughty.config.defaults.shape = Theme_config.notification.shape
|
||||
naughty.config.defaults.border_width = Theme_config.notification.border_width
|
||||
naughty.config.defaults.border_color = Theme_config.notification.border_color
|
||||
naughty.config.defaults.spacing = Theme_config.notification.spacing
|
||||
|
||||
Theme.notification_spacing = Theme_config.notification.corner_spacing
|
||||
|
||||
naughty.connect_signal('request::icon', function(n, context, hints)
|
||||
if context ~= 'app_icon' then
|
||||
return
|
||||
end
|
||||
local path = menubar.utils.lookup_icon(hints.app_icon) or menubar.utils.lookup_icon(hints.app_icon:lower())
|
||||
if path then
|
||||
n.icon = path
|
||||
end
|
||||
end)
|
||||
|
||||
naughty.connect_signal("request::display", function(n)
|
||||
naughty.connect_signal('request::display', function(n)
|
||||
if User_config.dnd then
|
||||
n:destroy()
|
||||
else
|
||||
if n.urgency == "critical" then
|
||||
n.title = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, ExtraBold 16'>%s</span>",
|
||||
Theme_config.notification.fg_urgent_title, n.title) or ""
|
||||
n.message = string.format("<span foreground='%s'>%s</span>", Theme_config.notification.fg_urgent_message,
|
||||
n.message) or ""
|
||||
n.app_name = string.format("<span foreground='%s'>%s</span>", Theme_config.notification.fg_urgent_app_name,
|
||||
n.app_name) or ""
|
||||
n.bg = Theme_config.notification.bg_urgent
|
||||
else
|
||||
n.title = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, ExtraBold 16'>%s</span>",
|
||||
Theme_config.notification.fg_normal_title, n.title) or ""
|
||||
n.message = string.format("<span foreground='%s'>%s</span>", Theme_config.notification.fg_normal_message,
|
||||
n.message) or ""
|
||||
n.bg = Theme_config.notification.bg_normal
|
||||
n.timeout = n.timeout or Theme_config.notification.timeout or 3
|
||||
if not n.icon then n.icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg' end
|
||||
if not n.app_name then n.app_name = 'System' end
|
||||
if not n.title then n.title = 'System Notification' end
|
||||
if not n.message then n.message = 'No message provided' end
|
||||
|
||||
local color = Theme_config.notification.bg_normal
|
||||
if n.urgency == 'critical' then
|
||||
color = Theme_config.notification.fg_urgent_message
|
||||
end
|
||||
|
||||
local use_image = false
|
||||
|
||||
if n.app_name == "Spotify" then
|
||||
if n.app_name == 'Spotify' then
|
||||
n.actions = {
|
||||
naughty.action {
|
||||
program = "Spotify",
|
||||
id = "skip-prev",
|
||||
icon = gears.color.recolor_image(icondir .. "skip-prev.svg",
|
||||
Theme_config.notification.spotify_button_icon_color)
|
||||
program = 'Spotify',
|
||||
id = 'skip-prev',
|
||||
name = 'Previous',
|
||||
position = 1,
|
||||
}, naughty.action {
|
||||
program = "Spotify",
|
||||
id = "play-pause",
|
||||
icon = gears.color.recolor_image(icondir .. "play-pause.svg",
|
||||
Theme_config.notification.spotify_button_icon_color)
|
||||
program = 'Spotify',
|
||||
id = 'play-pause',
|
||||
name = 'Play/Pause',
|
||||
position = 2,
|
||||
}, naughty.action {
|
||||
program = "Spotify",
|
||||
id = "skip-next",
|
||||
icon = gears.color.recolor_image(icondir .. "skip-next.svg",
|
||||
Theme_config.notification.spotify_button_icon_color)
|
||||
}
|
||||
program = 'Spotify',
|
||||
id = 'skip-next',
|
||||
name = 'Next',
|
||||
position = 3,
|
||||
},
|
||||
}
|
||||
use_image = true
|
||||
n.resident = true
|
||||
end
|
||||
|
||||
local action_template_widget
|
||||
|
||||
if use_image then
|
||||
action_template_widget = wibox.template {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon_role",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "centered",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_height = dpi(35),
|
||||
forced_width = dpi(35),
|
||||
bg = Theme_config.notification.action_bg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
id = "bgrnd"
|
||||
},
|
||||
id = "mrgn",
|
||||
top = dpi(10),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
else
|
||||
action_template_widget = wibox.template {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "text_role",
|
||||
font = "JetBrainsMono Nerd Font, Regular 12",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "centered",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
fg = Theme_config.notification.action_fg,
|
||||
bg = Theme_config.notification.action_bg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
id = "bgrnd"
|
||||
},
|
||||
id = "mrgn",
|
||||
top = dpi(10),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
if n.category == 'device.added' or n.category == 'network.connected' then
|
||||
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-added.oga')
|
||||
elseif n.category == 'device.removed' or n.category == 'network.disconnected' then
|
||||
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-removed.oga')
|
||||
elseif n.category == 'device.error' or n.category == 'im.error' or n.category == 'network.error' or n.category ==
|
||||
'transfer.error' then
|
||||
aspawn('ogg123 ogg123 /usr/share/sounds/Pop/stereo/alert/battery-low.oga')
|
||||
elseif n.category == 'email.arrived' then
|
||||
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/message-new-email.oga')
|
||||
end
|
||||
|
||||
local actions_template = wibox.widget {
|
||||
local action_template = wibox.widget {
|
||||
notification = n,
|
||||
base_layout = wibox.widget {
|
||||
spacing = dpi(40),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
spacing = dpi(90),
|
||||
layout = wibox.layout.flex.horizontal,
|
||||
},
|
||||
widget_template = {
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'text_role',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
font = 'JetBrainsMono Nerd Font, Bold 16',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(35),
|
||||
strategy = 'exact',
|
||||
},
|
||||
id = 'background_role',
|
||||
widget = wibox.container.background,
|
||||
bg = color,
|
||||
fg = Theme_config.notification.bg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
},
|
||||
widget_template = action_template_widget,
|
||||
style = {
|
||||
underline_normal = false,
|
||||
underline_selected = true
|
||||
underline_selected = false,
|
||||
shape_normal = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
--Don't remove or it will break
|
||||
bg_normal = color,
|
||||
bg_selected = color,
|
||||
fg_normal = Theme_config.notification.bg,
|
||||
fg_selected = Theme_config.notification.bg,
|
||||
},
|
||||
widget = naughty.list.actions
|
||||
widget = naughty.list.actions,
|
||||
}
|
||||
|
||||
local arc_start = n.timeout
|
||||
-- Hack to get the action buttons to work even after update
|
||||
--[[ for i = 1, #action_template._private.layout.children, 1 do
|
||||
hover.bg_hover { widget = action_template._private.layout.children[i].children[1], overlay = 12, press_overlay = 24 }
|
||||
end
|
||||
if (#action_template._private.layout.children > 0) and action_template._private.notification[1].actions[1].program == 'Spotify' then
|
||||
action_template._private.layout.children[1].children[1]:connect_signal('button::press', function()
|
||||
aspawn('playerctl previous')
|
||||
end)
|
||||
action_template._private.layout.children[2].children[1]:connect_signal('button::press', function()
|
||||
aspawn('playerctl play-pause')
|
||||
end)
|
||||
action_template._private.layout.children[3].children[1]:connect_signal('button::press', function()
|
||||
aspawn('playerctl next')
|
||||
end)
|
||||
end ]]
|
||||
|
||||
local start_timer = n.timeout
|
||||
if n.timeout == 0 then
|
||||
arc_start = 10
|
||||
start_timer = 5
|
||||
end
|
||||
|
||||
local w_template = wibox.template {
|
||||
local notification = wibox.template {
|
||||
widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Title
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = gears.color.recolor_image(icondir .. "notification-outline.svg",
|
||||
Theme_config.notification.icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
markup = n.app_name or 'System Notification',
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
fg = Theme_config.notification.fg_appname,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
nil,
|
||||
{
|
||||
{
|
||||
{
|
||||
text = os.date("%H:%M"),
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "background",
|
||||
fg = Theme_config.notification.fg_time,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{
|
||||
{ -- Icon
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
font = User_config.font.specify .. ", 10",
|
||||
text = "✕",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
notification = n,
|
||||
widget = naughty.widget.icon,
|
||||
image = n.icon,
|
||||
resize = true,
|
||||
},
|
||||
start_angle = 4.71239,
|
||||
thickness = dpi(2),
|
||||
min_value = 0,
|
||||
max_value = arc_start,
|
||||
value = arc_start,
|
||||
widget = wibox.container.arcchart,
|
||||
id = "arc_chart"
|
||||
widget = wibox.container.background,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
},
|
||||
id = "background1",
|
||||
fg = Theme_config.notification.fg_close,
|
||||
bg = Theme_config.notification.bg_close,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
width = dpi(20),
|
||||
height = dpi(20),
|
||||
},
|
||||
{ -- Title
|
||||
{
|
||||
notification = n,
|
||||
widget = naughty.widget.title,
|
||||
markup = [[<span foreground="]] ..
|
||||
Theme_config.notification.bg .. [[" font="JetBrainsMono Nerd Font, Bold 16">]] .. (n.app_name or
|
||||
'Unknown App') .. [[</span> | <span font="JetBrainsMono Nerd Font, Regular 16">]] .. (n.title or 'System Notification') .. [[</span>]],
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
id = "const1"
|
||||
width = dpi(430),
|
||||
height = dpi(35),
|
||||
strategy = 'max',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
id = "arc_margin"
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "arc_app_layout_2"
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(10),
|
||||
},
|
||||
id = "arc_app_layout",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "arc_app_bg",
|
||||
border_color = Theme_config.notification.title_border_color,
|
||||
border_width = Theme_config.notification.title_border_width,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{
|
||||
{
|
||||
nil,
|
||||
{
|
||||
{
|
||||
{
|
||||
image = n.icon,
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 10)
|
||||
end
|
||||
{ -- Clock
|
||||
widget = wibox.widget.textclock,
|
||||
format = '%H:%M',
|
||||
font = 'JetBrainsMono Nerd Font, Bold 16',
|
||||
fg = Theme_config.notification.bg,
|
||||
halign = 'right',
|
||||
valign = 'center',
|
||||
},
|
||||
width = naughty.config.defaults.icon_size,
|
||||
height = naughty.config.defaults.icon_size,
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
{ -- Close button
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.notification.bg),
|
||||
resize = true,
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
start_angle = 4.71239,
|
||||
thickness = dpi(2),
|
||||
min_value = 0,
|
||||
max_value = start_timer,
|
||||
value = start_timer,
|
||||
widget = wibox.container.arcchart,
|
||||
id = 'arc',
|
||||
},
|
||||
fg = Theme_config.notification.bg_close,
|
||||
bg = color,
|
||||
widget = wibox.container.background,
|
||||
id = 'arc_bg',
|
||||
},
|
||||
strategy = 'exact',
|
||||
width = dpi(18),
|
||||
height = dpi(18),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
left = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
halign = "center",
|
||||
valign = "top",
|
||||
widget = wibox.container.place
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
left = dpi(20),
|
||||
bottom = dpi(15),
|
||||
top = dpi(15),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = color,
|
||||
fg = '#212121',
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
},
|
||||
{ -- Main body
|
||||
{ -- Image
|
||||
{
|
||||
{
|
||||
notification = n,
|
||||
image = n.icon,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
upscale = true,
|
||||
resize_strategy = 'scale',
|
||||
widget = naughty.widget.icon,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(10))
|
||||
end,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = dpi(128),
|
||||
width = dpi(128),
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = naughty.widget.title,
|
||||
align = "left"
|
||||
},
|
||||
{
|
||||
widget = naughty.widget.message,
|
||||
align = "left"
|
||||
},
|
||||
{
|
||||
actions_template,
|
||||
widget = wibox.container.place
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
notification = n,
|
||||
widget = naughty.widget.message,
|
||||
font = 'JetBrainsMono Nerd Font, Regular 10',
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
},
|
||||
left = dpi(10),
|
||||
bottom = dpi(10),
|
||||
top = dpi(10),
|
||||
right = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = dpi(128),
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "widget_layout",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
{ -- Spacer
|
||||
{
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.notification.action_bg,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = dpi(2),
|
||||
},
|
||||
action_template,
|
||||
spacing = dpi(15),
|
||||
id = 'main_layout',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "min_size",
|
||||
strategy = "min",
|
||||
width = dpi(100),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(15),
|
||||
},
|
||||
id = "max_size",
|
||||
strategy = "max",
|
||||
width = Theme.notification_max_width or dpi(500),
|
||||
widget = wibox.container.constraint
|
||||
bg = '#212121',
|
||||
border_color = '#414141',
|
||||
border_width = dpi(2),
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "background",
|
||||
bg = Theme_config.notification.bg,
|
||||
border_color = Theme_config.notification.border_color,
|
||||
border_width = Theme_config.notification.border_width,
|
||||
shape = Theme_config.notification.shape_inside,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
width = dpi(600),
|
||||
},
|
||||
update_callback = function()
|
||||
|
||||
end
|
||||
}
|
||||
local close = w_template:get_widget().max_size.min_size.widget_layout.arc_app_bg.arc_app_layout.arc_app_layout_2.arc_margin
|
||||
.const1.background1
|
||||
local arc = close.arc_chart
|
||||
|
||||
if #action_template._private.layout.children < 1 then
|
||||
notification:get_widget().children[1].children[1].children[1].children[3] = nil
|
||||
end
|
||||
|
||||
local arc_bg = notification:get_widget().children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1]
|
||||
local arc = arc_bg.children[1]
|
||||
|
||||
local timeout = n.timeout
|
||||
|
||||
@@ -352,45 +336,36 @@ naughty.connect_signal("request::display", function(n)
|
||||
duration = n.timeout,
|
||||
pos = n.timeout,
|
||||
easing = rubato.linear,
|
||||
clamp_position = true,
|
||||
subscribed = function(value)
|
||||
arc.value = value
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
rubato_timer.target = 0
|
||||
|
||||
w_template:get_widget():connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
n.timeout = 99999
|
||||
rubato_timer.pause = true
|
||||
end
|
||||
)
|
||||
notification:get_widget():connect_signal('mouse::enter', function()
|
||||
n.timeout = 99999
|
||||
rubato_timer.pause = true
|
||||
end)
|
||||
|
||||
w_template:get_widget():connect_signal(
|
||||
"mouse::leave",
|
||||
function()
|
||||
n.timeout = rubato_timer.pos
|
||||
rubato_timer.pause = false
|
||||
rubato_timer.target = 0
|
||||
end
|
||||
)
|
||||
notification:get_widget():connect_signal('mouse::leave', function()
|
||||
n.timeout = rubato_timer.pos
|
||||
rubato_timer.pause = false
|
||||
rubato_timer.target = 0
|
||||
end)
|
||||
end
|
||||
|
||||
Hover_signal(close)
|
||||
hover.bg_hover { widget = arc_bg }
|
||||
|
||||
close:connect_signal("button::press", function()
|
||||
arc_bg:connect_signal('button::press', function()
|
||||
n:destroy()
|
||||
end)
|
||||
|
||||
w_template:get_widget():connect_signal("button::press", function(_, _, _, key)
|
||||
if key == 3 then
|
||||
n:destroy()
|
||||
end
|
||||
-- Raise the client on click
|
||||
if key == 1 then
|
||||
notification:get_widget():buttons { gtable.join(
|
||||
abutton({}, 1, function()
|
||||
for _, client in ipairs(capi.client.get()) do
|
||||
if client.name:match(n.app_name) then
|
||||
if client.class:lower():match(n.app_name:lower()) then
|
||||
if not client:isvisible() and client.first_tag then
|
||||
client.first_tag:view_only()
|
||||
end
|
||||
@@ -398,44 +373,209 @@ naughty.connect_signal("request::display", function(n)
|
||||
client:raise()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end),
|
||||
abutton({}, 3, function()
|
||||
n:destroy()
|
||||
end)
|
||||
), }
|
||||
|
||||
local box = naughty.layout.box {
|
||||
notification = n,
|
||||
timeout = 5,
|
||||
type = "notification",
|
||||
type = 'notification',
|
||||
screen = capi.screen.primary,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 10)
|
||||
end,
|
||||
widget_template = w_template
|
||||
widget_template = notification,
|
||||
}
|
||||
|
||||
box.buttons = {}
|
||||
n.buttons = {}
|
||||
|
||||
-- This is stupid but there is on way to clone the notifaction widget and being able to modify only the clone
|
||||
--[=[ naughty.emit_signal('notification_surface', wibox.template {
|
||||
widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Title
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
notification = n,
|
||||
widget = naughty.widget.icon,
|
||||
--image = n.icon or '',
|
||||
resize = true,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
width = dpi(20),
|
||||
height = dpi(20),
|
||||
},
|
||||
{ -- Title
|
||||
{
|
||||
notification = n,
|
||||
widget = naughty.widget.title,
|
||||
markup = [[<span foreground="]] ..
|
||||
Theme_config.notification.bg .. [[" font="JetBrainsMono Nerd Font, Bold 16">]] .. (n.app_name or
|
||||
'Unknown App') .. [[</span> | <span font="JetBrainsMono Nerd Font, Regular 16">]] .. (n.title or 'System Notification') .. [[</span>]],
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(280),
|
||||
height = dpi(35),
|
||||
strategy = 'max',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(10),
|
||||
},
|
||||
nil,
|
||||
{
|
||||
{
|
||||
{ -- Clock
|
||||
widget = wibox.widget.textclock,
|
||||
format = '%H:%M',
|
||||
font = 'JetBrainsMono Nerd Font, Bold 16',
|
||||
fg = Theme_config.notification.bg,
|
||||
halign = 'right',
|
||||
valign = 'center',
|
||||
},
|
||||
{ -- Close button
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.notification.bg),
|
||||
resize = true,
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
start_angle = 4.71239,
|
||||
thickness = dpi(2),
|
||||
min_value = 0,
|
||||
max_value = start_timer,
|
||||
value = start_timer,
|
||||
widget = wibox.container.arcchart,
|
||||
id = 'arc',
|
||||
},
|
||||
fg = Theme_config.notification.bg_close,
|
||||
bg = color,
|
||||
widget = wibox.container.background,
|
||||
id = 'arc_bg',
|
||||
},
|
||||
strategy = 'exact',
|
||||
width = dpi(18),
|
||||
height = dpi(18),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
left = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = color,
|
||||
fg = '#212121',
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
},
|
||||
{ -- Main body
|
||||
{ -- Image
|
||||
{
|
||||
{
|
||||
notification = n,
|
||||
--image = n.icon or '',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
upscale = true,
|
||||
resize_strategy = 'scale',
|
||||
widget = naughty.widget.icon,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(10))
|
||||
end,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = dpi(128),
|
||||
width = dpi(128),
|
||||
},
|
||||
{
|
||||
{
|
||||
notification = n,
|
||||
widget = naughty.widget.message,
|
||||
text = n.message,
|
||||
font = 'JetBrainsMono Nerd Font, Regular 8',
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = dpi(128),
|
||||
},
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(15),
|
||||
},
|
||||
bg = '#212121',
|
||||
border_color = '#414141',
|
||||
border_width = dpi(2),
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
width = dpi(600),
|
||||
},
|
||||
}) ]=]
|
||||
end
|
||||
end)
|
||||
|
||||
naughty.connect_signal(
|
||||
"destroyed",
|
||||
function()
|
||||
end
|
||||
)
|
||||
|
||||
naughty.connect_signal(
|
||||
"invoked",
|
||||
function(_, action)
|
||||
if action.program == "Spotify" then
|
||||
if action.id == "skip-prev" then
|
||||
awful.spawn("playerctl previous")
|
||||
end
|
||||
if action.id == "play-pause" then
|
||||
awful.spawn("playerctl play-pause")
|
||||
end
|
||||
if action.id == "skip-next" then
|
||||
awful.spawn("playerctl next")
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
--[[
|
||||
naughty.notification {
|
||||
app_name = 'Spotify',
|
||||
title = 'The Beatles - Here Comes The Sun',
|
||||
message = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
|
||||
icon = '/home/crylia/Bilder/57384097.jpg',
|
||||
timeout = 30,
|
||||
actions = {
|
||||
naughty.action {
|
||||
name = 'amet',
|
||||
position = 1,
|
||||
text = 'Test',
|
||||
},
|
||||
naughty.action {
|
||||
name = 'Lorem ipsum dolor sit amet',
|
||||
position = 2,
|
||||
},
|
||||
naughty.action {
|
||||
name = 'Lorem',
|
||||
position = 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
]]
|
||||
|
||||
@@ -3,56 +3,98 @@
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local ruled = require("ruled")
|
||||
local aclient = require('awful.client')
|
||||
local aplacement = require('awful.placement')
|
||||
local ascreen = require('awful.screen')
|
||||
local ruled = require('ruled')
|
||||
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
local config = require('src.tools.config')
|
||||
|
||||
awful.rules.rules = {
|
||||
{
|
||||
awesome.register_xproperty('_NET_WM_BYPASS_COMPOSITOR', 'boolean')
|
||||
|
||||
ruled.client.connect_signal('request::rules', function()
|
||||
ruled.client.append_rule {
|
||||
rule = {},
|
||||
properties = {
|
||||
border_width = beautiful.border_width,
|
||||
border_color = beautiful.border_normal,
|
||||
focus = awful.client.focus.filter,
|
||||
raise = true,
|
||||
keys = require("src.bindings.client_keys"),
|
||||
buttons = require("src.bindings.client_buttons"),
|
||||
screen = awful.screen.preferred,
|
||||
placement = awful.placement.under_mouse + awful.placement.no_overlap + awful.placement.no_offscreen +
|
||||
awful.placement.centered
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "titlebar",
|
||||
border_width = Theme.border_width,
|
||||
border_color = Theme.border_normal,
|
||||
maximized = false,
|
||||
maximized_horizontal = false,
|
||||
maximized_vertical = false,
|
||||
focus = aclient.focus.filter,
|
||||
raise = true,
|
||||
keys = require('src.bindings.client_keys'),
|
||||
buttons = require('src.bindings.client_buttons'),
|
||||
screen = ascreen.preferred,
|
||||
placement = aplacement.under_mouse + aplacement.no_overlap + aplacement.no_offscreen + aplacement.centered,
|
||||
},
|
||||
}
|
||||
|
||||
ruled.client.append_rule {
|
||||
rule_any = {
|
||||
type = {
|
||||
"normal",
|
||||
"dialog",
|
||||
"modal",
|
||||
"utility"
|
||||
}
|
||||
'normal',
|
||||
'dialog',
|
||||
},
|
||||
},
|
||||
properties = {
|
||||
titlebars_enabled = true
|
||||
}
|
||||
titlebars_enabled = true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r")
|
||||
|
||||
if not handler then return end
|
||||
local data = json:decode(handler:read("a"))
|
||||
handler:close()
|
||||
|
||||
if type(data) ~= "table" then return end
|
||||
|
||||
for _, c in ipairs(data) do
|
||||
ruled.client.append_rule {
|
||||
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
|
||||
rule_any = {
|
||||
class = {
|
||||
'proton-bridge',
|
||||
'1password',
|
||||
'protonvpn',
|
||||
'Steam',
|
||||
},
|
||||
},
|
||||
properties = {
|
||||
floating = true
|
||||
minimized = true,
|
||||
},
|
||||
}
|
||||
ruled.client.append_rule {
|
||||
rule_any = {
|
||||
class = {
|
||||
'discord',
|
||||
'spotify',
|
||||
},
|
||||
},
|
||||
properties = {
|
||||
tag = '1',
|
||||
screen = 2,
|
||||
},
|
||||
}
|
||||
|
||||
ruled.client.append_rule {
|
||||
rule_any = {
|
||||
class = {
|
||||
'steam_app_990080',
|
||||
},
|
||||
},
|
||||
callback = function(c)
|
||||
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
|
||||
c:connect_signal('focus', function()
|
||||
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
|
||||
end)
|
||||
c:connect_signal('raised', function()
|
||||
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
end)
|
||||
|
||||
do
|
||||
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
|
||||
for _, c in ipairs(data) do
|
||||
ruled.client.append_rule {
|
||||
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
|
||||
properties = {
|
||||
floating = true,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,256 +1,74 @@
|
||||
---@diagnostic disable: undefined-field
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local aplacement = require('awful.placement')
|
||||
local gtimer = require('gears.timer')
|
||||
local ascreen = require('awful.screen')
|
||||
local ruled = require('ruled')
|
||||
|
||||
local color = require("src.lib.color")
|
||||
local rubato = require("src.lib.rubato")
|
||||
local config = require('src.tools.config')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
screen = screen,
|
||||
client = client,
|
||||
tag = tag
|
||||
tag = tag,
|
||||
}
|
||||
|
||||
capi.screen.connect_signal("added", function()
|
||||
capi.screen.connect_signal('added', function()
|
||||
capi.awesome.restart()
|
||||
end)
|
||||
|
||||
capi.screen.connect_signal("removed", function()
|
||||
capi.screen.connect_signal('removed', function()
|
||||
capi.awesome.restart()
|
||||
end)
|
||||
|
||||
capi.client.connect_signal("manage", function(c)
|
||||
capi.client.connect_signal('manage', function(c)
|
||||
if capi.awesome.startup and not c.size_hints.user_porition and not c.size_hints.program_position then
|
||||
awful.placement.no_offscreen(c)
|
||||
end
|
||||
if c.class == "Brave-browser" then
|
||||
c.floating = false
|
||||
aplacement.no_offscreen(c)
|
||||
end
|
||||
if c.transient_for then
|
||||
c.floating = true
|
||||
end
|
||||
if c.fullscreen then
|
||||
gears.timer.delayed_call(function()
|
||||
gtimer.delayed_call(function()
|
||||
if c.valid then
|
||||
c:geometry(c.screen.geometry)
|
||||
end
|
||||
end)
|
||||
end
|
||||
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
|
||||
for _, c in ipairs(data) do
|
||||
ruled.client.append_rule {
|
||||
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
|
||||
properties = {
|
||||
floating = true,
|
||||
},
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal('unmanage', function(c)
|
||||
if #awful.screen.focused().clients > 0 then
|
||||
awful.screen.focused().clients[1]:emit_signal(
|
||||
'request::activate',
|
||||
'mouse_enter', {
|
||||
raise = true
|
||||
if #ascreen.focused().clients > 0 then
|
||||
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
|
||||
raise = true,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
capi.tag.connect_signal('property::selected', function(c)
|
||||
if #awful.screen.focused().clients > 0 then
|
||||
awful.screen.focused().clients[1]:emit_signal(
|
||||
'request::activate',
|
||||
'mouse_enter', {
|
||||
raise = true
|
||||
if #ascreen.focused().clients > 0 then
|
||||
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
|
||||
raise = true,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Sloppy focus
|
||||
--[[ client.connect_signal("mouse::enter", function(c)
|
||||
--[[ client.connect_signal('mouse::enter', function(c)
|
||||
c:emit_signal(
|
||||
"request::activate",
|
||||
"mouse_enter",{
|
||||
raise = true
|
||||
})
|
||||
'request::activate',
|
||||
'mouse_enter', {
|
||||
raise = true,
|
||||
})
|
||||
end) ]]
|
||||
|
||||
--- Takes a wibox.container.background and connects four signals to it
|
||||
---@param widget wibox.container.background a background widget
|
||||
---@param bg_override string | nil overrides the default bg hover color
|
||||
---@param fg_override string | nil overrides the default fg hover color
|
||||
---@param border_override string | nil overrides the default border hover color
|
||||
---@param icon_override string | nil the old icon color
|
||||
---@param icon_override_hover string | nil the hover effect color
|
||||
function Hover_signal(widget, bg_override, fg_override, border_override, icon_override, icon_override_hover)
|
||||
local old_wibox, old_cursor, old_bg, old_fg, old_border
|
||||
widget.bg = widget.bg or "#000000"
|
||||
widget.fg = widget.fg or "#000000"
|
||||
widget.border_color = widget.border_color or "#000000"
|
||||
local icon = nil
|
||||
if icon_override and icon_override_hover then
|
||||
icon = widget:get_children_by_id("icon")[1].icon
|
||||
widget.icon = widget:get_children_by_id("icon")[1]
|
||||
end
|
||||
|
||||
local _, rb, gb, bb = widget.bg:get_rgba()
|
||||
local _, rf, gf, bf = widget.fg:get_rgba()
|
||||
local rbo, gbo, bbo = color.utils.hex_to_rgba(widget.border_color)
|
||||
|
||||
local r_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(rb * 255), rate = 24 }
|
||||
local g_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(gb * 255), rate = 24 }
|
||||
local b_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(bb * 255), rate = 24 }
|
||||
|
||||
local r_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(rf * 255), rate = 24 }
|
||||
local g_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(gf * 255), rate = 24 }
|
||||
local b_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(bf * 255), rate = 24 }
|
||||
|
||||
local r_timed_border = rubato.timed { duration = 0.3, pos = math.floor(rbo), rate = 24 }
|
||||
local g_timed_border = rubato.timed { duration = 0.3, pos = math.floor(gbo), rate = 24 }
|
||||
local b_timed_border = rubato.timed { duration = 0.3, pos = math.floor(bbo), rate = 24 }
|
||||
|
||||
local function update_bg()
|
||||
widget:set_bg("#" ..
|
||||
color.utils.rgba_to_hex { math.min(r_timed_bg.pos, 255), math.min(g_timed_bg.pos, 255),
|
||||
math.min(b_timed_bg.pos, 255) })
|
||||
end
|
||||
|
||||
local function update_fg()
|
||||
widget:set_fg("#" .. color.utils.rgba_to_hex { math.min(r_timed_fg.pos, 255), math.min(g_timed_fg.pos, 255),
|
||||
math.min(b_timed_fg.pos, 255) })
|
||||
end
|
||||
|
||||
local function update_border()
|
||||
widget:set_border_color("#" ..
|
||||
color.utils.rgba_to_hex { math.min(r_timed_border.pos, 255), math.min(g_timed_border.pos, 255),
|
||||
math.min(b_timed_border.pos, 255) })
|
||||
end
|
||||
|
||||
r_timed_bg:subscribe(update_bg)
|
||||
g_timed_bg:subscribe(update_bg)
|
||||
b_timed_bg:subscribe(update_bg)
|
||||
|
||||
r_timed_fg:subscribe(update_fg)
|
||||
g_timed_fg:subscribe(update_fg)
|
||||
b_timed_fg:subscribe(update_fg)
|
||||
|
||||
r_timed_border:subscribe(update_border)
|
||||
g_timed_border:subscribe(update_border)
|
||||
b_timed_border:subscribe(update_border)
|
||||
|
||||
local function set_bg(newbg)
|
||||
r_timed_bg.target, g_timed_bg.target, b_timed_bg.target = newbg[1], newbg[2], newbg[3]
|
||||
end
|
||||
|
||||
local function set_fg(newfg)
|
||||
r_timed_fg.target, g_timed_fg.target, b_timed_fg.target = newfg[1], newfg[2], newfg[3]
|
||||
end
|
||||
|
||||
local function set_border(newborder)
|
||||
r_timed_border.target, g_timed_border.target, b_timed_border.target = newborder[1], newborder[2], newborder[3]
|
||||
end
|
||||
|
||||
local _, rbg, gbg, bbg, abg = widget.bg:get_rgba()
|
||||
old_bg = RGB_to_hex(rbg, gbg, bbg)
|
||||
local _, rfg, gfg, bfg, afg = widget.fg:get_rgba()
|
||||
old_fg = RGB_to_hex(rfg, gfg, bfg)
|
||||
old_border = widget.border_color
|
||||
local rborder, gborder, bborder = color.utils.hex_to_rgba(old_border)
|
||||
|
||||
local function match_hex(hex1, hex2)
|
||||
local r1, g1, b1 = color.utils.hex_to_rgba(hex1)
|
||||
local r2, g2, b2 = color.utils.hex_to_rgba(hex2)
|
||||
return math.abs(r1 - r2) <= 100 and math.abs(g1 - g2) <= 100 and math.abs(b1 - b2) <= 100
|
||||
end
|
||||
|
||||
--[[
|
||||
local button_release = function()
|
||||
if old_bg or bg_override then
|
||||
if bg_override then
|
||||
bg_override = bg_override .. "dd"
|
||||
end
|
||||
widget.bg = bg_override or old_bg .. "dd"
|
||||
end
|
||||
if fg_override or old_fg then
|
||||
if fg_override then
|
||||
fg_override = fg_override .. "dd"
|
||||
end
|
||||
widget.fg = fg_override or old_fg .. "dd"
|
||||
end
|
||||
end ]]
|
||||
|
||||
local mouse_leave = function()
|
||||
|
||||
if old_bg then
|
||||
local r, g, b = color.utils.hex_to_rgba(old_bg)
|
||||
set_bg({ r, g, b })
|
||||
end
|
||||
if old_fg then
|
||||
local r, g, b = color.utils.hex_to_rgba(old_fg)
|
||||
set_fg({ r, g, b })
|
||||
end
|
||||
if old_border then
|
||||
local r, g, b = color.utils.hex_to_rgba(old_border)
|
||||
set_border({ r, g, b })
|
||||
end
|
||||
if old_wibox then
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end
|
||||
if widget.icon and icon_override and icon_override_hover then
|
||||
widget.icon.image = gears.color.recolor_image(icon, icon_override)
|
||||
end
|
||||
end
|
||||
|
||||
local mouse_enter = function()
|
||||
_, rbg, gbg, bbg, abg = widget.bg:get_rgba()
|
||||
if not match_hex(RGB_to_hex(rbg, gbg, bbg), old_bg) then
|
||||
old_bg = RGB_to_hex(rbg, gbg, bbg)
|
||||
set_bg({ rbg * 0.9 * 255, gbg * 0.9 * 255, bbg * 0.9 * 255 })
|
||||
end
|
||||
if old_bg then
|
||||
if bg_override then
|
||||
rbg, gbg, bbg = color.utils.hex_to_rgba(bg_override)
|
||||
set_bg({ rbg, gbg, bbg })
|
||||
else
|
||||
set_bg({ rbg * 0.9 * 255, gbg * 0.9 * 255, bbg * 0.9 * 255 })
|
||||
end
|
||||
end
|
||||
|
||||
_, rfg, gfg, bfg, afg = widget.fg:get_rgba()
|
||||
if not match_hex(RGB_to_hex(rfg, gfg, bfg), old_fg) then
|
||||
old_fg = RGB_to_hex(rfg, gfg, bfg)
|
||||
set_fg({ rfg * 0.9 * 255, gfg * 0.9 * 255, bfg * 0.9 * 255 })
|
||||
end
|
||||
if fg_override or old_fg then
|
||||
if fg_override then
|
||||
rfg, gfg, bfg = color.utils.hex_to_rgba(fg_override)
|
||||
set_fg({ rfg, gfg, bfg })
|
||||
else
|
||||
set_fg({ rfg * 0.9 * 255, gfg * 0.9 * 255, bfg * 0.9 * 255 })
|
||||
end
|
||||
end
|
||||
|
||||
if not match_hex(old_border, widget.border_color) then
|
||||
old_border = widget.border_color
|
||||
rborder, gborder, bborder = color.utils.hex_to_rgba(old_border)
|
||||
end
|
||||
if border_override or old_border then
|
||||
if border_override then
|
||||
rborder, gborder, bborder = color.utils.hex_to_rgba(border_override)
|
||||
set_border({ rborder, gborder, bborder })
|
||||
else
|
||||
set_border({ rborder * 0.9, gborder * 0.9, bborder * 0.9 })
|
||||
end
|
||||
end
|
||||
if icon and widget.icon and icon_override and icon_override_hover then
|
||||
widget.icon.image = gears.color.recolor_image(icon, icon_override_hover)
|
||||
end
|
||||
local w = capi.mouse.current_wibox
|
||||
if w then
|
||||
old_cursor, old_wibox = w.cursor, w
|
||||
w.cursor = "hand1"
|
||||
end
|
||||
--widget:connect_signal("mouse::leave", mouse_leave)
|
||||
end
|
||||
|
||||
widget:connect_signal("mouse::enter", mouse_enter)
|
||||
--widget:connect_signal("button::press", button_press)
|
||||
--widget:connect_signal("button::release", button_release)
|
||||
widget:connect_signal("mouse::leave", mouse_leave)
|
||||
end
|
||||
|
||||
627
awesome/src/core/titlebar.lua
Normal file
@@ -0,0 +1,627 @@
|
||||
local math = math
|
||||
|
||||
-- Awesome libs
|
||||
local abutton = require('awful.button')
|
||||
local atitlebar = require('awful.titlebar')
|
||||
local atooltip = require('awful.tooltip')
|
||||
local cairo = require('lgi').cairo
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gdk = require('lgi').Gdk
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gsurface = require('gears.surface')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local json = require('src.lib.json-lua.json-lua')
|
||||
|
||||
gdk.init {}
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
client = client,
|
||||
}
|
||||
|
||||
local instance = nil
|
||||
|
||||
local titlebar = {}
|
||||
|
||||
local titlebar_position = User_config.titlebar_position
|
||||
|
||||
-- Converts the given hex color to hsv
|
||||
local function hex2hsv(color)
|
||||
local r, g, b = gcolor.parse_color(color)
|
||||
local C_max = math.max(r, g, b)
|
||||
local C_min = math.min(r, g, b)
|
||||
local delta = C_max - C_min
|
||||
local H, S, V
|
||||
if delta == 0 then
|
||||
H = 0
|
||||
elseif C_max == r then
|
||||
H = 60 * (((g - b) / delta) % 6)
|
||||
elseif C_max == g then
|
||||
H = 60 * (((b - r) / delta) + 2)
|
||||
elseif C_max == b then
|
||||
H = 60 * (((r - g) / delta) + 4)
|
||||
end
|
||||
if C_max == 0 then
|
||||
S = 0
|
||||
else
|
||||
S = delta / C_max
|
||||
end
|
||||
V = C_max
|
||||
return H, S * 100, V * 100
|
||||
end
|
||||
|
||||
-- Converts the given hsv color to hex
|
||||
local function hsv2hex(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 - math.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(math.floor(r), math.floor(g), math.floor(b))
|
||||
end
|
||||
|
||||
-- Calculates the relative luminance of the given color
|
||||
local function relative_luminance(color)
|
||||
local r, g, b = gcolor.parse_color(color)
|
||||
local function from_sRGB(u) return u <= 0.0031308 and 25 * u / 323 or ((200 * u + 11) / 211) ^ (12 / 5) end
|
||||
|
||||
return 0.2126 * from_sRGB(r) + 0.7152 * from_sRGB(g) + 0.0722 * from_sRGB(b)
|
||||
end
|
||||
|
||||
-- Rotates the hue of the given hex color by the specified angle (in degrees)
|
||||
local function rotate_hue(color, angle)
|
||||
local H, S, V = hex2hsv(color)
|
||||
angle = math.max(math.min(angle or 0, 360), 0)
|
||||
H = (H + angle) % 360
|
||||
return hsv2hex(H, S, V)
|
||||
end
|
||||
|
||||
-- Lightens a given hex color by the specified amount
|
||||
local function lighten(color, amount)
|
||||
local r, g, b
|
||||
r, g, b = gcolor.parse_color(color)
|
||||
r = 255 * r
|
||||
g = 255 * g
|
||||
b = 255 * b
|
||||
r = r + math.floor(2.55 * amount)
|
||||
g = g + math.floor(2.55 * amount)
|
||||
b = b + math.floor(2.55 * amount)
|
||||
r = r > 255 and 255 or r
|
||||
g = g > 255 and 255 or g
|
||||
b = b > 255 and 255 or b
|
||||
return ('#%02x%02x%02x'):format(r, g, b)
|
||||
end
|
||||
|
||||
-- Darkens a given hex color by the specified amount
|
||||
local function darken(color, amount)
|
||||
local r, g, b
|
||||
r, g, b = gcolor.parse_color(color)
|
||||
r = 255 * r
|
||||
g = 255 * g
|
||||
b = 255 * b
|
||||
r = math.max(0, r - math.floor(r * (amount / 100)))
|
||||
g = math.max(0, g - math.floor(g * (amount / 100)))
|
||||
b = math.max(0, b - math.floor(b * (amount / 100)))
|
||||
return ('#%02x%02x%02x'):format(r, g, b)
|
||||
end
|
||||
|
||||
-- Returns a vertical gradient pattern going from cololr_1 -> color_2
|
||||
local function duotone_gradient_vertical(color_1, color_2, height, offset_1, offset_2)
|
||||
local fill_pattern = cairo.Pattern.create_linear(0, 0, 0, height)
|
||||
local r, g, b, a
|
||||
r, g, b, a = gcolor.parse_color(color_1)
|
||||
fill_pattern:add_color_stop_rgba(offset_1 or 0, r, g, b, a)
|
||||
r, g, b, a = gcolor.parse_color(color_2)
|
||||
fill_pattern:add_color_stop_rgba(offset_2 or 1, r, g, b, a)
|
||||
return fill_pattern
|
||||
end
|
||||
|
||||
-- Returns a horizontal gradient pattern going from cololr_1 -> color_2
|
||||
local function duotone_gradient_horizontal(color_1, color_2, width, offset_1, offset_2)
|
||||
local fill_pattern = cairo.Pattern.create_linear(0, 0, width, 0)
|
||||
local r, g, b, a
|
||||
r, g, b, a = gcolor.parse_color(color_1)
|
||||
fill_pattern:add_color_stop_rgba(offset_1 or 0, r, g, b, a)
|
||||
r, g, b, a = gcolor.parse_color(color_2)
|
||||
fill_pattern:add_color_stop_rgba(offset_2 or 1, r, g, b, a)
|
||||
return fill_pattern
|
||||
end
|
||||
|
||||
local function save(tbl, filename)
|
||||
local handler = io.open(filename, 'w')
|
||||
if not handler then return nil end
|
||||
handler:write(json:encode(tbl))
|
||||
handler:close()
|
||||
end
|
||||
|
||||
local function load(file)
|
||||
local handler = io.open(file, 'r')
|
||||
if not handler then return nil end
|
||||
local data = json:decode(handler:read('*a'))
|
||||
assert(data, 'Failed to load file: ' .. file)
|
||||
handler:close()
|
||||
return data
|
||||
end
|
||||
|
||||
local function set_color_rule(c, color)
|
||||
if (not c) or (not c.instance) then return end
|
||||
titlebar.color_rules[c.instance .. titlebar_position] = color
|
||||
save(titlebar.color_rules, titlebar.color_rules_filepath)
|
||||
end
|
||||
|
||||
local function get_color_rule(c)
|
||||
if (not c) or (not c.instance) then return end
|
||||
return titlebar.color_rules[c.instance .. titlebar_position]
|
||||
end
|
||||
|
||||
---Gets the dominant color of a client for the purpose of setting the titlebar color
|
||||
---@param client any
|
||||
---@return string hex color
|
||||
local function get_dominant_color(client)
|
||||
local tally = {}
|
||||
local content = gsurface(client.content)
|
||||
local cgeo = client:geometry()
|
||||
local x_offset, y_offset = 2, 2
|
||||
local color
|
||||
|
||||
if titlebar_position == 'top' then
|
||||
for x_pos = 0, math.floor(cgeo.width / 2), 2 do
|
||||
for y_pos = 0, 8, 1 do
|
||||
color = '#' .. gdk.pixbuf_get_from_surface(content, x_offset + x_pos, y_offset + y_pos, 1, 1
|
||||
):get_pixels():gsub('.', function(c)
|
||||
return ('%02x'):format(c:byte())
|
||||
end)
|
||||
if not tally[color] then
|
||||
tally[color] = 1
|
||||
else
|
||||
tally[color] = tally[color] + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif titlebar_position == 'left' then
|
||||
x_offset = 0
|
||||
for y_pos = 0, math.floor(cgeo.height / 2), 2 do
|
||||
for x_pos = 0, 8, 1 do
|
||||
color = '#' .. gdk.pixbuf_get_from_surface(content, x_offset + x_pos, y_offset + y_pos, 1, 1
|
||||
):get_pixels():gsub('.', function(c)
|
||||
return ('%02x'):format(c:byte())
|
||||
end)
|
||||
if not tally[color] then
|
||||
tally[color] = 1
|
||||
else
|
||||
tally[color] = tally[color] + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mode_c = 0
|
||||
for kolor, kount in pairs(tally) do
|
||||
if kount > mode_c then
|
||||
mode_c = kount
|
||||
color = kolor
|
||||
end
|
||||
end
|
||||
set_color_rule(client, color)
|
||||
return color
|
||||
end
|
||||
|
||||
local function create_button_image(name, is_focused, event, is_on)
|
||||
titlebar.key = titlebar.key or {}
|
||||
|
||||
titlebar.key.close_color = Theme_config.titlebar.close
|
||||
titlebar.key.minimize_color = Theme_config.titlebar.minimize
|
||||
titlebar.key.maximize_color = Theme_config.titlebar.maximize
|
||||
titlebar.key.floating_color = Theme_config.titlebar.floating
|
||||
titlebar.key.ontop_color = Theme_config.titlebar.ontop
|
||||
titlebar.key.sticky_color = Theme_config.titlebar.sticky
|
||||
|
||||
local focus_state = is_focused and 'focused' or 'unfocused'
|
||||
local key_img
|
||||
if is_on ~= nil then
|
||||
local toggle_state = is_on and 'on' or 'off'
|
||||
key_img = ('%s_%s_%s_%s'):format(name, toggle_state, focus_state, event)
|
||||
else
|
||||
key_img = ('%s_%s_%s'):format(name, focus_state, event)
|
||||
end
|
||||
if titlebar.key[key_img] then return titlebar.key[key_img] end
|
||||
local key_color = key_img .. '_color'
|
||||
if not titlebar.key[key_color] then
|
||||
local key_base_color = name .. '_color'
|
||||
local base_color = titlebar.key[key_base_color] or rotate_hue(hsv2hex(math.random(0, 360), 70, 90), 33)
|
||||
titlebar.key[key_base_color] = base_color
|
||||
local button_color = base_color
|
||||
local H = hex2hsv(base_color)
|
||||
if not is_focused and event ~= 'hover' then
|
||||
button_color = hsv2hex(H, 0, 50)
|
||||
end
|
||||
button_color = (event == 'hover') and lighten(button_color, 25) or
|
||||
(event == 'press') and darken(button_color, 25) or button_color
|
||||
titlebar.key[key_color] = button_color
|
||||
end
|
||||
local button_size = Theme_config.titlebar.button_size
|
||||
local surface = cairo.ImageSurface.create('ARGB32', button_size, button_size)
|
||||
local cr = cairo.Context.create(surface)
|
||||
cr:arc(button_size / 2, button_size / 2, button_size / 2, math.rad(0), math.rad(360))
|
||||
cr:set_source_rgba(gcolor.parse_color(titlebar.key[key_color] or '#fefefa'))
|
||||
cr.antialias = cairo.Antialias.BEST
|
||||
cr:fill()
|
||||
titlebar.key[key_img] = surface
|
||||
return titlebar.key[key_img]
|
||||
end
|
||||
|
||||
---Returns a button widget for the titlebar
|
||||
---@param c client
|
||||
---@param name string Name for the tooltip and the correct button image
|
||||
---@param button_callback function callback function called when the button is pressed
|
||||
---@param property string|nil client state, e.g. active or inactive
|
||||
---@return wibox.widget button widget
|
||||
local function create_titlebar_button(c, name, button_callback, property)
|
||||
local button_img = wibox.widget.imagebox(nil, false)
|
||||
local tooltip = atooltip {
|
||||
text = name,
|
||||
delay_show = 0.5,
|
||||
margins_leftright = 12,
|
||||
margins_topbottom = 6,
|
||||
timeout = 0.25,
|
||||
align = 'bottom_right',
|
||||
}
|
||||
tooltip:add_to_object(button_img)
|
||||
local is_on, is_focused
|
||||
local event = 'normal'
|
||||
local function update()
|
||||
is_focused = c.active
|
||||
-- If the button is for a property that can be toggled
|
||||
if property then
|
||||
is_on = c[property]
|
||||
button_img.image = create_button_image(name, is_focused, event, is_on)
|
||||
else
|
||||
button_img.image = create_button_image(name, is_focused, event)
|
||||
end
|
||||
end
|
||||
|
||||
c:connect_signal('unfocus', update)
|
||||
c:connect_signal('focus', update)
|
||||
if property then c:connect_signal('property::' .. property, update) end
|
||||
button_img:connect_signal('mouse::enter', function()
|
||||
event = 'hover'
|
||||
update()
|
||||
end)
|
||||
button_img:connect_signal('mouse::leave', function()
|
||||
event = 'normal'
|
||||
update()
|
||||
end)
|
||||
|
||||
button_img.buttons = abutton({}, 1, function()
|
||||
event = 'press'
|
||||
update()
|
||||
end, function()
|
||||
if button_callback then
|
||||
event = 'normal'
|
||||
button_callback()
|
||||
else
|
||||
event = 'hover'
|
||||
end
|
||||
update()
|
||||
end)
|
||||
|
||||
button_img.id = 'button_image'
|
||||
update()
|
||||
return wibox.widget {
|
||||
{
|
||||
{
|
||||
button_img,
|
||||
widget = wibox.container.constraint,
|
||||
height = Theme_config.titlebar.button_size,
|
||||
width = Theme_config.titlebar.button_size,
|
||||
strategy = 'exact',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
}
|
||||
end
|
||||
|
||||
---Get the mouse bindings for the titlebar
|
||||
---@param c client
|
||||
---@return table all mouse bindings for the titlebar
|
||||
local function get_titlebar_mouse_bindings(c)
|
||||
local clicks = 0
|
||||
local tolerance = 4
|
||||
local buttons = { abutton({}, 1, function()
|
||||
local cx, cy = capi.mouse.coords().x, capi.mouse.coords().y
|
||||
local delta = 250 / 1000
|
||||
clicks = clicks + 1
|
||||
if clicks == 2 then
|
||||
local nx, ny = capi.mouse.coords().x, capi.mouse.coords().y
|
||||
if math.abs(cx - nx) <= tolerance and math.abs(cy - ny) <= tolerance then
|
||||
c.maximized = not c.maximized
|
||||
end
|
||||
else
|
||||
c:activate { context = 'titlebar', action = 'mouse_move' }
|
||||
end
|
||||
-- Start a timer to clear the click count
|
||||
gtimer.weak_start_new(delta, function() clicks = 0 end)
|
||||
end), abutton({}, 2, function()
|
||||
c.color = get_dominant_color(c)
|
||||
set_color_rule(c, c.color)
|
||||
add_titlebar(c)
|
||||
end), abutton({}, 3, function()
|
||||
c:activate { context = 'mouse_click', action = 'mouse_resize' }
|
||||
end), }
|
||||
return buttons
|
||||
end
|
||||
|
||||
---Creates a title widget for the titlebar
|
||||
---@param c client
|
||||
---@return wibox.widget The title widget
|
||||
local function create_titlebar_title(c)
|
||||
local title_widget = wibox.widget {
|
||||
halign = 'center',
|
||||
ellipsize = 'middle',
|
||||
opacity = c.active and 1 or 0.7,
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
}
|
||||
|
||||
local function update()
|
||||
title_widget.markup = ("<span foreground='%s'>%s</span>"):format(
|
||||
(((relative_luminance('#fefefa') + 0.05) / (relative_luminance(c.color) + 0.05)) >= 7 and true)
|
||||
and '#fefefa' or '#242424', c.name)
|
||||
end
|
||||
|
||||
c:connect_signal('property::name', update)
|
||||
c:connect_signal('unfocus', function()
|
||||
title_widget.opacity = 0.7
|
||||
end)
|
||||
c:connect_signal('focus', function() title_widget.opacity = 1 end)
|
||||
update()
|
||||
return {
|
||||
title_widget,
|
||||
widget = wibox.container.margin,
|
||||
margins = Theme_config.titlebar.title_margin,
|
||||
}
|
||||
end
|
||||
|
||||
---Creates the widget for a titlebar item
|
||||
---@param c client
|
||||
---@param name string The name of the item
|
||||
---@return wibox.widget|nil widget The titlebar item widget
|
||||
local function get_titlebar_item(c, name)
|
||||
if titlebar_position == 'top' then
|
||||
if name == 'close' then return create_titlebar_button(c, name, function() c:kill() end)
|
||||
elseif name == 'maximize' then
|
||||
return create_titlebar_button(c, name, function() c.maximized = not c.maximized end, 'maximized')
|
||||
elseif name == 'minimize' then
|
||||
return create_titlebar_button(c, name, function() c.minimized = true end)
|
||||
elseif name == 'ontop' then
|
||||
return create_titlebar_button(c, name, function() c.ontop = not c.ontop end, 'ontop')
|
||||
elseif name == 'floating' then
|
||||
return create_titlebar_button(c, name, function()
|
||||
c.floating = not c.floating
|
||||
if c.floating then
|
||||
c.maximized = false
|
||||
end
|
||||
end, 'floating')
|
||||
elseif name == 'sticky' then
|
||||
return create_titlebar_button(c, name, function()
|
||||
c.sticky = not c.sticky
|
||||
return c.sticky
|
||||
end, 'sticky')
|
||||
elseif name == 'title' then
|
||||
return create_titlebar_title(c)
|
||||
elseif name == 'icon' then
|
||||
return wibox.widget {
|
||||
atitlebar.widget.iconwidget(c),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
}
|
||||
end
|
||||
elseif titlebar_position == 'left' then
|
||||
if name == 'close' then
|
||||
return create_titlebar_button(c, name, function() c:kill() end)
|
||||
elseif name == 'maximize' then
|
||||
return create_titlebar_button(c, name, function() c.maximized = not c.maximized end, 'maximized')
|
||||
elseif name == 'minimize' then
|
||||
return create_titlebar_button(c, name, function() c.minimized = true end)
|
||||
elseif name == 'ontop' then
|
||||
return create_titlebar_button(c, name, function() c.ontop = not c.ontop end, 'ontop')
|
||||
elseif name == 'floating' then
|
||||
return create_titlebar_button(c, name, function()
|
||||
c.floating = not c.floating
|
||||
if c.floating then
|
||||
c.maximized = false
|
||||
end
|
||||
end, 'floating')
|
||||
elseif name == 'sticky' then
|
||||
return create_titlebar_button(c, name, function()
|
||||
c.sticky = not c.sticky
|
||||
return c.sticky
|
||||
end, 'sticky')
|
||||
elseif name == 'icon' then
|
||||
return wibox.widget {
|
||||
atitlebar.widget.iconwidget(c),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Groups together the titlebar items for left, center, right placement
|
||||
---@param c client
|
||||
---@param group table|string The name of the group or a table of item names
|
||||
---@return wibox.widget|nil widget The titlebar item widget
|
||||
local function create_titlebar_items(c, group)
|
||||
if not group then return nil end
|
||||
if type(group) == 'string' then return create_titlebar_title(c) end
|
||||
local layout
|
||||
|
||||
if titlebar_position == 'left' then
|
||||
layout = wibox.widget {
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
}
|
||||
elseif titlebar_position == 'top' then
|
||||
layout = wibox.widget {
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
end
|
||||
|
||||
local item
|
||||
for _, name in ipairs(group) do
|
||||
item = get_titlebar_item(c, name)
|
||||
if item then layout:add(item) end
|
||||
end
|
||||
return layout
|
||||
end
|
||||
|
||||
---Adds the titlebar to the left of a client
|
||||
---@param c client
|
||||
function add_titlebar(c)
|
||||
if titlebar_position == 'top' then
|
||||
atitlebar(c, {
|
||||
size = Theme_config.titlebar.size,
|
||||
bg = gcolor.transparent,
|
||||
position = 'top',
|
||||
}):setup {
|
||||
{
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.left_and_bottom),
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(5),
|
||||
},
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.middle),
|
||||
buttons = get_titlebar_mouse_bindings(c),
|
||||
layout = wibox.layout.flex.horizontal,
|
||||
},
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.right_and_top),
|
||||
widget = wibox.container.margin,
|
||||
right = dpi(5),
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = duotone_gradient_vertical(
|
||||
lighten(c.color, 1),
|
||||
c.color,
|
||||
Theme_config.titlebar.size,
|
||||
0,
|
||||
0.5
|
||||
),
|
||||
}
|
||||
elseif titlebar_position == 'left' then
|
||||
atitlebar(c, {
|
||||
size = Theme_config.titlebar.size,
|
||||
bg = gcolor.transparent,
|
||||
position = 'left',
|
||||
}):setup {
|
||||
{
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.right_and_top),
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(5),
|
||||
},
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.middle),
|
||||
buttons = get_titlebar_mouse_bindings(c),
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
{
|
||||
create_titlebar_items(c, User_config.titlebar_items.left_and_bottom),
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(5),
|
||||
},
|
||||
layout = wibox.layout.align.vertical,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = duotone_gradient_horizontal(
|
||||
lighten(c.color, 1),
|
||||
c.color,
|
||||
Theme_config.titlebar.size,
|
||||
0,
|
||||
0.5
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
if not c.floating then
|
||||
atitlebar.hide(c, titlebar_position)
|
||||
end
|
||||
c:connect_signal('property::maximized', function()
|
||||
if not c.floating then
|
||||
--if not client or not client.focus then return end
|
||||
atitlebar.hide(c, titlebar_position)
|
||||
elseif c.floating and (not (c.maximized or c.fullscreen)) then
|
||||
atitlebar.show(c, titlebar_position)
|
||||
end
|
||||
end)
|
||||
c:connect_signal('property::floating', function()
|
||||
if not c.floating then
|
||||
--if not client or not client.focus then return end
|
||||
atitlebar.hide(c, titlebar_position)
|
||||
elseif c.floating and (not (c.maximized or c.fullscreen)) then
|
||||
atitlebar.show(c, titlebar_position)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable(titlebar, { __call = function()
|
||||
|
||||
titlebar.color_rules_filepath = gfilesystem.get_configuration_dir() .. '/src/config/' .. 'color_rules.json'
|
||||
titlebar.color_rules = load(titlebar.color_rules_filepath) or {}
|
||||
|
||||
capi.client.connect_signal('request::titlebars', function(c)
|
||||
c._cb_add_window_decorations = function()
|
||||
gtimer.weak_start_new(0.5, function()
|
||||
c.color = get_dominant_color(c)
|
||||
add_titlebar(c)
|
||||
c:disconnect_signal('request::activate', c._cb_add_window_decorations)
|
||||
end)
|
||||
end
|
||||
|
||||
local color = get_color_rule(c)
|
||||
if color then
|
||||
c.color = color
|
||||
add_titlebar(c)
|
||||
else
|
||||
c.color = Theme_config.titlebar.color
|
||||
add_titlebar(c)
|
||||
c:connect_signal('request::activate', c._cb_add_window_decorations)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal('request::manage', function(c)
|
||||
if not c.floating then
|
||||
--if not client or not client.focus then return end
|
||||
atitlebar.hide(c, titlebar_position)
|
||||
elseif c.floating and (not (c.maximized or c.fullscreen)) then
|
||||
atitlebar.show(c, titlebar_position)
|
||||
end
|
||||
end)
|
||||
end, })
|
||||
end
|
||||
return instance
|
||||
1
awesome/src/lib/dbus_proxy
Submodule
@@ -1,60 +0,0 @@
|
||||
local setmetatable = setmetatable
|
||||
local base = require("wibox.widget.base")
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local module = { mt = {} }
|
||||
|
||||
function module:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function module:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
module.set_widget = base.set_widget_common
|
||||
|
||||
function module:set_widget_template(widget_template)
|
||||
self._private.widget_template = widget_template
|
||||
self:set_widget(widget_template)
|
||||
end
|
||||
|
||||
function module:get_widget()
|
||||
return self._private.widget
|
||||
end
|
||||
|
||||
function module:get_children()
|
||||
return { self._private.widget }
|
||||
end
|
||||
|
||||
function module:set_children(children)
|
||||
self:set_widget(children[1])
|
||||
end
|
||||
|
||||
function module:reset()
|
||||
self._private.widget_template = nil
|
||||
self:set_widget(nil)
|
||||
end
|
||||
|
||||
local function new(args)
|
||||
local self = base.make_widget(nil, nil, { enable_properties = true })
|
||||
|
||||
gtable.crush(self, module, true)
|
||||
|
||||
self:set_widget(wibox.widget.textbox("Hello World!"))
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function module.mt:__call(...)
|
||||
return new(...)
|
||||
end
|
||||
|
||||
return setmetatable(module, module.mt)
|
||||
@@ -3,26 +3,31 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome libs
|
||||
local abutton = require("awful.button")
|
||||
local aspawn = require("awful.spawn")
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local Gio = require("lgi").Gio
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local Gio = require('lgi').Gio
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
local dock = require('src.modules.crylia_bar.dock')
|
||||
|
||||
-- Local libs
|
||||
local config = require('src.tools.config')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/'
|
||||
|
||||
local application_grid = { mt = {} }
|
||||
|
||||
@@ -31,11 +36,11 @@ local application_grid = { mt = {} }
|
||||
This is done here once because it would be unnecessary to do it for every instance
|
||||
]]
|
||||
do
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config'
|
||||
gfilesystem.make_directories(dir)
|
||||
dir = dir .. "/applications.json"
|
||||
dir = dir .. '/applications.json'
|
||||
if not gfilesystem.file_readable(dir) then
|
||||
aspawn("touch " .. dir)
|
||||
aspawn('touch ' .. dir)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -125,55 +130,55 @@ local function get_applications_from_file()
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "",
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '',
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
height = dpi(64),
|
||||
width = dpi(64),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{ -- Name
|
||||
text = app_info.get_name(app),
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(170),
|
||||
-- Prevents widget from overflowing
|
||||
height = dpi(40),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
name = app_info.get_name(app),
|
||||
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, "Comment") or "",
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
|
||||
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, "Keywords") or "",
|
||||
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or "",
|
||||
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, "Terminal") == "true",
|
||||
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Comment') or '',
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'),
|
||||
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Keywords') or '',
|
||||
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or '',
|
||||
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Terminal') == 'true',
|
||||
actions = Gio.DesktopAppInfo.list_actions(desktop_app_info),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or "",
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
border_color = Theme_config.application_launcher.application.border_color,
|
||||
border_width = Theme_config.application_launcher.application.border_width,
|
||||
bg = Theme_config.application_launcher.application.bg,
|
||||
fg = Theme_config.application_launcher.application.fg,
|
||||
shape = Theme_config.application_launcher.application.shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
local context_menu = cm {
|
||||
widget_template = wibox.widget {
|
||||
@@ -183,122 +188,113 @@ local function get_applications_from_file()
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Execute as sudo",
|
||||
icon = gcolor.recolor_image(icondir .. "launch.svg",
|
||||
name = 'Execute as sudo',
|
||||
icon = gcolor.recolor_image(icondir .. 'launch.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
aspawn("/home/crylia/.config/awesome/src/scripts/start_as_admin.sh " .. app_widget.exec)
|
||||
end
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
aspawn('/home/crylia/.config/awesome/src/scripts/start_as_admin.sh ' .. app_widget.exec)
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Pin to dock",
|
||||
icon = gcolor.recolor_image(icondir .. "pin.svg",
|
||||
name = 'Pin to dock',
|
||||
icon = gcolor.recolor_image(icondir .. 'pin.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
-- Open dock.js and read all its content into a table, add the new app into the table and write it back
|
||||
local file_path = gfilesystem.get_configuration_dir() .. "src/config/dock.json"
|
||||
local handler = io.open(file_path, "r")
|
||||
if not handler then return end
|
||||
--[[ async.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', function(data)
|
||||
table.insert(data, {
|
||||
name = app_widget.name or '',
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '',
|
||||
comment = app_widget.comment or '',
|
||||
exec = app_widget.exec or '',
|
||||
keywords = app_widget.keywords or '',
|
||||
categories = app_widget.categories or '',
|
||||
terminal = app_widget.terminal or '',
|
||||
actions = app_widget.actions or '',
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ''
|
||||
})
|
||||
|
||||
local dock_table = json:decode(handler:read("a")) or {}
|
||||
|
||||
handler:close()
|
||||
assert(type(dock_table) == "table", "dock_table is not a table")
|
||||
|
||||
table.insert(dock_table, {
|
||||
name = app_widget.name or "",
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or
|
||||
Get_gicon_path(app_info.get_icon(app),
|
||||
Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "",
|
||||
comment = app_widget.comment or "",
|
||||
exec = app_widget.exec or "",
|
||||
keywords = app_widget.keywords or "",
|
||||
categories = app_widget.categories or "",
|
||||
terminal = app_widget.terminal or "",
|
||||
actions = app_widget.actions or "",
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
|
||||
})
|
||||
|
||||
local dock_encoded = json:encode(dock_table)
|
||||
handler = io.open(file_path, "w")
|
||||
|
||||
if not handler then return end
|
||||
|
||||
handler:write(dock_encoded)
|
||||
handler:close()
|
||||
capi.awesome.emit_signal("dock::changed")
|
||||
end
|
||||
async.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', data, function()
|
||||
capi.awesome.emit_signal('dock::changed')
|
||||
end)
|
||||
end) ]]
|
||||
dock:get_dock_for_screen(capi.mouse.screen):pin_element {
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Add to desktop",
|
||||
icon = gcolor.recolor_image(icondir .. "desktop.svg",
|
||||
name = 'Add to desktop',
|
||||
icon = gcolor.recolor_image(icondir .. 'desktop.svg',
|
||||
Theme_config.application_launcher.application.cm_icon_color),
|
||||
callback = function()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal("desktop::add_to_desktop", {
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
capi.awesome.emit_signal('desktop::add_to_desktop', {
|
||||
label = app_info.get_name(app),
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or "",
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
|
||||
icon = Get_gicon_path(app_info.get_icon(app)) or '',
|
||||
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'),
|
||||
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '',
|
||||
})
|
||||
end
|
||||
}
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Hide context menu when the mouse leaves it
|
||||
context_menu:connect_signal("mouse::leave", function()
|
||||
context_menu:connect_signal('mouse::leave', function()
|
||||
context_menu.visible = false
|
||||
end)
|
||||
|
||||
-- Execute command on left click and hide launcher, right click to show context menu
|
||||
app_widget:buttons(
|
||||
gtable.join(
|
||||
abutton({
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 1,
|
||||
on_release = function()
|
||||
Gio.AppInfo.launch_uris_async(app)
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
end
|
||||
}),
|
||||
abutton({
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
end,
|
||||
},
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 3,
|
||||
on_release = function()
|
||||
context_menu:toggle()
|
||||
end
|
||||
})
|
||||
end,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
Hover_signal(app_widget)
|
||||
hover.bg_hover { widget = app_widget }
|
||||
table.insert(list, app_widget)
|
||||
end
|
||||
end
|
||||
@@ -308,48 +304,41 @@ end
|
||||
---Takes the search filter and returns a list of applications in the correct order
|
||||
---@param search_filter any
|
||||
function application_grid:set_applications(search_filter)
|
||||
local filter = search_filter or self.filter or ""
|
||||
local filter = search_filter or self.filter or ''
|
||||
-- Reset to first position
|
||||
self._private.curser = {
|
||||
x = 1,
|
||||
y = 1
|
||||
y = 1,
|
||||
}
|
||||
|
||||
local grid = wibox.widget {
|
||||
homogenous = true,
|
||||
expand = false,
|
||||
spacing = dpi(10),
|
||||
id = "grid",
|
||||
id = 'grid',
|
||||
-- 200 is the application element width + 10 spacing
|
||||
forced_num_cols = math.floor((capi.mouse.screen.geometry.width / 100 * 60) / 200),
|
||||
forced_num_rows = 7,
|
||||
orientation = "vertical",
|
||||
layout = wibox.layout.grid
|
||||
orientation = 'vertical',
|
||||
layout = wibox.layout.grid,
|
||||
}
|
||||
|
||||
-- Read the dock.json file and get all apps, these are needed to read/write the launch count
|
||||
local handler = io.open(gfilesystem.get_configuration_dir() .. "src/config/applications.json", "r")
|
||||
if not handler then return end
|
||||
|
||||
local dock_encoded = handler:read("a") or "{}"
|
||||
local dock = json:decode(dock_encoded)
|
||||
|
||||
assert(type(dock) == "table", "dock is not a table")
|
||||
|
||||
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json')
|
||||
local mylist = {}
|
||||
|
||||
for _, application in ipairs(self.app_list) do
|
||||
-- Match the filter for the name, categories and keywords
|
||||
if string.match(string.lower(application.name or ""), string.lower(filter)) or
|
||||
string.match(string.lower(application.categories or ""), string.lower(filter)) or
|
||||
string.match(string.lower(application.keywords or ""), string.lower(filter)) then
|
||||
if string.match(string.lower(application.name or ''), string.lower(filter)) or
|
||||
string.match(string.lower(application.categories or ''), string.lower(filter)) or
|
||||
string.match(string.lower(application.keywords or ''), string.lower(filter)) then
|
||||
|
||||
-- If there are no elements in the table, set everything to 0
|
||||
if #dock == 0 then
|
||||
if #data == 0 then
|
||||
application.counter = 0
|
||||
end
|
||||
-- Read the counter for the matching app
|
||||
for _, app in ipairs(dock) do
|
||||
for _, app in ipairs(data) do
|
||||
if app.desktop_file == application.desktop_file then
|
||||
application.counter = app.counter or 0
|
||||
break;
|
||||
@@ -380,7 +369,7 @@ function application_grid:set_applications(search_filter)
|
||||
|
||||
-- Check if the curser is currently at the same position as the app
|
||||
capi.awesome.connect_signal(
|
||||
"update::selected",
|
||||
'update::selected',
|
||||
function()
|
||||
if self._private.curser.y == pos.row and self._private.curser.x == pos.col then
|
||||
app.border_color = Theme_config.application_launcher.application.border_color_active
|
||||
@@ -391,7 +380,7 @@ function application_grid:set_applications(search_filter)
|
||||
)
|
||||
end
|
||||
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
self:set_widget(grid)
|
||||
end
|
||||
|
||||
@@ -401,7 +390,7 @@ function application_grid:move_up()
|
||||
if self._private.curser.y < 1 then
|
||||
self._private.curser.y = 1
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser down by one, making sure it doesn't go out of bounds
|
||||
@@ -411,7 +400,7 @@ function application_grid:move_down()
|
||||
if self._private.curser.y > grid_rows then
|
||||
self._private.curser.y = grid_rows
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser left by one, making sure it doesn't go out of bounds
|
||||
@@ -420,7 +409,7 @@ function application_grid:move_left()
|
||||
if self._private.curser.x < 1 then
|
||||
self._private.curser.x = 1
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
-- Move the curser right by one, making sure it doesn't go out of bounds
|
||||
@@ -430,7 +419,7 @@ function application_grid:move_right()
|
||||
if self._private.curser.x > grid_cols then
|
||||
self._private.curser.x = grid_cols
|
||||
end
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
--- Execute the currently selected app and add to the launch count
|
||||
@@ -441,17 +430,9 @@ function application_grid:execute()
|
||||
-- Launch the application async
|
||||
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(selected_widget.exec, nil, 0))
|
||||
|
||||
local file_path = gfilesystem.get_configuration_dir() .. "src/config/applications.json"
|
||||
local handler = io.open(file_path, "r")
|
||||
if not handler then return end
|
||||
|
||||
local dock_encoded = handler:read("a") or "{}"
|
||||
local dock = json:decode(dock_encoded)
|
||||
|
||||
assert(type(dock) == "table", "dock is not a table")
|
||||
|
||||
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json')
|
||||
-- Increase the counter by one then rewrite to the file, its a bit hacky but it works
|
||||
for _, prog in ipairs(dock) do
|
||||
for _, prog in ipairs(data) do
|
||||
if prog.desktop_file:match(selected_widget.desktop_file) then
|
||||
prog.counter = prog.counter + 1
|
||||
-- I don't like goto's, but its the easiest way here(PR is welcome).
|
||||
@@ -462,25 +443,21 @@ function application_grid:execute()
|
||||
local prog = {
|
||||
name = selected_widget.name,
|
||||
desktop_file = selected_widget.desktop_file,
|
||||
counter = 1
|
||||
counter = 1,
|
||||
}
|
||||
table.insert(dock, prog)
|
||||
table.insert(data, prog)
|
||||
end
|
||||
::continue::
|
||||
handler:close()
|
||||
handler = io.open(file_path, "w")
|
||||
if not handler then return end
|
||||
handler:write(json:encode_pretty(dock))
|
||||
handler:close()
|
||||
config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json', data)
|
||||
end
|
||||
|
||||
-- Reset the grid cursor
|
||||
function application_grid:reset()
|
||||
self._private.curser = {
|
||||
x = 1,
|
||||
y = 1
|
||||
y = 1,
|
||||
}
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
end
|
||||
|
||||
function application_grid.new(args)
|
||||
@@ -496,8 +473,4 @@ function application_grid.new(args)
|
||||
return w
|
||||
end
|
||||
|
||||
function application_grid.mt:__call(...)
|
||||
return application_grid.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(application_grid, application_grid.mt)
|
||||
return setmetatable(application_grid, { __call = function(...) return application_grid.new(...) end })
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local akeygrabber = require("awful.keygrabber")
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Own libs
|
||||
local app_grid = require("src.modules.application_launcher.application")
|
||||
local app_grid = require('src.modules.application_launcher.application')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -23,18 +23,17 @@ local capi = {
|
||||
-- This grid object is shared to avoid having multipe unnecessary instances
|
||||
local application_grid = app_grid {}
|
||||
|
||||
local application_launcher = { mt = {} }
|
||||
local application_launcher = {}
|
||||
|
||||
function application_launcher.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- Create a new inputbox
|
||||
local searchbar = awidget.inputbox {
|
||||
hint_text = "Search...",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
hint_text = 'Search...',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
}
|
||||
|
||||
-- Application launcher popup
|
||||
local application_container = apopup {
|
||||
widget = {
|
||||
@@ -48,7 +47,7 @@ function application_launcher.new(args)
|
||||
margins = 5,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
height = dpi(50),
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
@@ -57,22 +56,22 @@ function application_launcher.new(args)
|
||||
border_color = Theme_config.application_launcher.searchbar.border_color,
|
||||
border_width = Theme_config.application_launcher.searchbar.border_width,
|
||||
shape = Theme_config.application_launcher.searchbar.shape,
|
||||
id = "searchbar_bg"
|
||||
id = 'searchbar_bg',
|
||||
},
|
||||
{
|
||||
application_grid,
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(100),
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
height = args.screen.geometry.height / 100 * 60,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
ontop = true,
|
||||
@@ -82,7 +81,7 @@ function application_launcher.new(args)
|
||||
placement = aplacement.centered,
|
||||
bg = Theme_config.application_launcher.bg,
|
||||
border_color = Theme_config.application_launcher.border_color,
|
||||
border_width = Theme_config.application_launcher.border_width
|
||||
border_width = Theme_config.application_launcher.border_width,
|
||||
}
|
||||
|
||||
gtable.crush(application_container, application_launcher, true)
|
||||
@@ -91,31 +90,31 @@ function application_launcher.new(args)
|
||||
searchbar:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
searchbar:focus()
|
||||
end)
|
||||
end),
|
||||
})
|
||||
|
||||
--#region Hover signals to change the cursor to a text cursor
|
||||
local old_cursor, old_wibox
|
||||
searchbar:connect_signal("mouse::enter", function()
|
||||
searchbar:connect_signal('mouse::enter', function()
|
||||
local wid = capi.mouse.current_wibox
|
||||
if wid then
|
||||
old_cursor, old_wibox = wid.cursor, wid
|
||||
wid.cursor = "xterm"
|
||||
wid.cursor = 'xterm'
|
||||
end
|
||||
end)
|
||||
searchbar:connect_signal("mouse::leave", function()
|
||||
searchbar:connect_signal('mouse::leave', function()
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
-- Get a reference to the searchbar background value
|
||||
local searchbar_bg = application_container.widget:get_children_by_id("searchbar_bg")[1]
|
||||
local searchbar_bg = application_container.widget:get_children_by_id('searchbar_bg')[1]
|
||||
|
||||
-- Toggle visible for the application launcher and init the searchbar
|
||||
capi.awesome.connect_signal("application_launcher::show", function()
|
||||
capi.awesome.connect_signal('application_launcher::show', function()
|
||||
if capi.mouse.screen == args.screen then
|
||||
capi.awesome.emit_signal("update::selected")
|
||||
capi.awesome.emit_signal('update::selected')
|
||||
if capi.mouse.screen == args.screen then
|
||||
application_container.visible = not application_container.visible
|
||||
end
|
||||
@@ -123,76 +122,76 @@ function application_launcher.new(args)
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active
|
||||
searchbar:focus()
|
||||
else
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
akeygrabber.stop()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Execute the currently selected application, reset the searchbar and hide the launcher
|
||||
searchbar:connect_signal("submit", function(_, text)
|
||||
searchbar:connect_signal('submit', function(_, text)
|
||||
application_grid:execute()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
searchbar:set_text("")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color
|
||||
end)
|
||||
|
||||
-- Hide the application launcher when the keygrabber stops and reset the searchbar
|
||||
searchbar:connect_signal("stopped", function(_, stop_key)
|
||||
if stop_key == "Escape" then
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
searchbar:connect_signal('stopped', function(_, stop_key)
|
||||
if stop_key == 'Escape' then
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
end
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color
|
||||
end)
|
||||
|
||||
-- When started change the background for the searchbar
|
||||
searchbar:connect_signal("started", function()
|
||||
searchbar:connect_signal('started', function()
|
||||
searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active
|
||||
end)
|
||||
|
||||
-- On every keypress in the searchbar check for certain inputs
|
||||
searchbar:connect_signal("inputbox::key_pressed", function(_, modkey, key)
|
||||
if key == "Escape" then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar
|
||||
searchbar:connect_signal('inputbox::key_pressed', function(_, modkey, key)
|
||||
if key == 'Escape' then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar
|
||||
searchbar:stop()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
elseif key == "Down" or key == "Right" then --If down or right is pressed initiate the grid navigation
|
||||
if key == "Down" then
|
||||
searchbar:set_text('')
|
||||
elseif key == 'Down' or key == 'Right' then --If down or right is pressed initiate the grid navigation
|
||||
if key == 'Down' then
|
||||
application_grid:move_down()
|
||||
elseif key == "Right" then
|
||||
elseif key == 'Right' then
|
||||
application_grid:move_right()
|
||||
end
|
||||
searchbar:stop()
|
||||
--New keygrabber to allow for key navigation
|
||||
akeygrabber.run(function(mod, key2, event)
|
||||
if event == "press" then
|
||||
if key2 == "Down" then
|
||||
if event == 'press' then
|
||||
if key2 == 'Down' then
|
||||
application_grid:move_down()
|
||||
elseif key2 == "Up" then
|
||||
elseif key2 == 'Up' then
|
||||
local old_y = application_grid._private.curser.y
|
||||
application_grid:move_up()
|
||||
if old_y - application_grid._private.curser.y == 0 then
|
||||
searchbar:focus()
|
||||
end
|
||||
elseif key2 == "Left" then
|
||||
elseif key2 == 'Left' then
|
||||
application_grid:move_left()
|
||||
elseif key2 == "Right" then
|
||||
elseif key2 == 'Right' then
|
||||
application_grid:move_right()
|
||||
elseif key2 == "Return" then
|
||||
elseif key2 == 'Return' then
|
||||
akeygrabber.stop()
|
||||
application_grid:execute()
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
elseif key2 == "Escape" then
|
||||
capi.awesome.emit_signal("application_launcher::show")
|
||||
elseif key2 == 'Escape' then
|
||||
capi.awesome.emit_signal('application_launcher::show')
|
||||
application_grid:reset()
|
||||
searchbar:set_text("")
|
||||
searchbar:set_text('')
|
||||
application_grid:set_applications(searchbar:get_text())
|
||||
akeygrabber.stop()
|
||||
end
|
||||
@@ -205,8 +204,4 @@ function application_launcher.new(args)
|
||||
end)
|
||||
end
|
||||
|
||||
function application_launcher.mt:__call(...)
|
||||
return application_launcher.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(application_launcher, application_launcher.mt)
|
||||
return setmetatable(application_launcher, { __call = function(_, ...) return application_launcher.new(...) end })
|
||||
|
||||
575
awesome/src/modules/audio/audio_controller.lua
Normal file
@@ -0,0 +1,575 @@
|
||||
-- Awesome Libs
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
-- Local libs
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
|
||||
|
||||
local audio_controller = {}
|
||||
|
||||
--#region wibox.widget.base boilerplate
|
||||
|
||||
function audio_controller:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function audio_controller:fit(context, width, height)
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
---Set the default source asynchronously
|
||||
---@param sink any
|
||||
function audio_controller:set_default_sink(sink)
|
||||
if not sink then return end
|
||||
aspawn('pactl set-default-sink ' .. sink)
|
||||
self:emit_signal('AC::device_changed')
|
||||
end
|
||||
|
||||
---Set the default source asynchronously
|
||||
function audio_controller:set_default_source(source)
|
||||
if not source then return end
|
||||
aspawn('pactl set-default-source ' .. source)
|
||||
self:emit_signal('AC::device_changed')
|
||||
end
|
||||
|
||||
---Get the default sink asynchronously
|
||||
---@param callback function returns the default sink as string
|
||||
function audio_controller:get_default_sink_async(callback)
|
||||
aspawn.easy_async_with_shell('pactl get-default-sink', function(stdout) callback(stdout:gsub('\n', '')) end)
|
||||
end
|
||||
|
||||
---Takes a sink and name and returns a new device widget, the device_type is for the color
|
||||
---@param device string sink
|
||||
---@param name string name of the device
|
||||
---@param device_type string sink or source
|
||||
---@return wibox.widget
|
||||
function audio_controller:get_device_widget(device, name, device_type)
|
||||
--remove leading spaces from name
|
||||
name = name:gsub('^%s*(.-)%s*$', '%1')
|
||||
local icon_color, fg
|
||||
if device_type == 'source' then
|
||||
icon_color = Theme_config.volume_controller.device_microphone_fg
|
||||
fg = Theme_config.volume_controller.device_microphone_fg
|
||||
elseif device_type == 'sink' then
|
||||
icon_color = Theme_config.volume_controller.device_headphones_fg
|
||||
fg = Theme_config.volume_controller.device_headphones_fg
|
||||
end
|
||||
|
||||
local device_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'icon',
|
||||
resize = true,
|
||||
image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 'name',
|
||||
text = name,
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.volume_controller.device_bg,
|
||||
fg = fg,
|
||||
border_color = Theme_config.volume_controller.device_border_color,
|
||||
border_width = Theme_config.volume_controller.device_border_width,
|
||||
shape = Theme_config.volume_controller.device_shape,
|
||||
widget = wibox.container.background,
|
||||
sink = device,
|
||||
}
|
||||
|
||||
if device_type == 'sink' then
|
||||
device_widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
self:set_default_sink(device)
|
||||
end)
|
||||
))
|
||||
elseif device_type == 'source' then
|
||||
device_widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
self:set_default_source(device)
|
||||
end)
|
||||
))
|
||||
end
|
||||
|
||||
self:connect_signal('AC::device_changed', function(new_sink)
|
||||
if device_widget.device == new_sink then
|
||||
device_widget.bg = Theme_config.volume_controller.device_headphones_selected_bg
|
||||
device_widget.fg = Theme_config.volume_controller.device_headphones_selected_fg
|
||||
device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.device_headphones_selected_fg)
|
||||
else
|
||||
device_widget.bg = Theme_config.volume_controller.device_bg
|
||||
device_widget.fg = fg
|
||||
device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color)
|
||||
end
|
||||
end)
|
||||
|
||||
hover.bg_hover { widget = device_widget }
|
||||
|
||||
return device_widget
|
||||
end
|
||||
|
||||
---Get all sink devices
|
||||
---@param callback function returns a list of sinks
|
||||
function audio_controller:get_sink_devices_async(callback)
|
||||
-- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n"
|
||||
aspawn.easy_async_with_shell([=[
|
||||
LC_ALL=C pactl list sinks | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }'
|
||||
]=], function(stdout)
|
||||
local sinks = wibox.layout.fixed.vertical {}
|
||||
for line in stdout:gmatch('[^\r\n]+') do
|
||||
-- Call the callback function with the name and description
|
||||
local s, n = line:match('(.-);(.+)')
|
||||
table.insert(sinks, self:get_device_widget(s, n, 'sink'))
|
||||
end
|
||||
self.sinks = sinks
|
||||
callback()
|
||||
end)
|
||||
end
|
||||
|
||||
---Get all source devices
|
||||
---@param callback function returns a list of sources
|
||||
function audio_controller:get_source_devices_async(callback)
|
||||
-- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n"
|
||||
aspawn.easy_async_with_shell([=[
|
||||
LC_ALL=C pactl list sources | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }'
|
||||
]=], function(stdout)
|
||||
local sources = wibox.layout.fixed.vertical {}
|
||||
for line in stdout:gmatch('[^\r\n]+') do
|
||||
local s, n = line:match('(.-);(.+)')
|
||||
table.insert(sources, self:get_device_widget(s, n, 'source'))
|
||||
end
|
||||
self.sources = sources
|
||||
callback()
|
||||
end)
|
||||
end
|
||||
|
||||
---Creates a new audio controller
|
||||
---@return wibox.widget auio_controller the audio controller widget
|
||||
function audio_controller.new()
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{ -- sink Device selector
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'sink_dd_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = 'Output Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'sink_dd_shape',
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- sink dropdown
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = 'sink_list',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = 'sink_list_shape',
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = 'sink_height',
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
width = dpi(300),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- source Device selector
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'source_dd_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = 'Input Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'source_dd_shape',
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- source dropdown
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = 'source_list',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = 'source_list_shape',
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = 'source_height',
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
width = dpi(300),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- sink volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.volume_fg),
|
||||
id = 'sink_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(26),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gshape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(15),
|
||||
handle_cursor = 'left_ptr',
|
||||
maximum = 100,
|
||||
forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity
|
||||
value = 50,
|
||||
widget = wibox.widget.slider,
|
||||
id = 'sink_slider',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(300),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Spacer
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(10),
|
||||
},
|
||||
{ -- source volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.volume_fg),
|
||||
id = 'source_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(26),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gshape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(15),
|
||||
handle_cursor = 'left_ptr',
|
||||
maximum = 100,
|
||||
forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity
|
||||
value = 50,
|
||||
widget = wibox.widget.slider,
|
||||
id = 'source_slider',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(400),
|
||||
height = dpi(26),
|
||||
strategy = 'exact',
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
-- The parent margin doesn't render without an empty widget here???
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
|
||||
assert(w, 'Failed to create volume controller widget')
|
||||
|
||||
gtable.crush(w, audio_controller, true)
|
||||
|
||||
local sink_icon = w:get_children_by_id('sink_icon')[1]
|
||||
local sink_slider = w:get_children_by_id('sink_slider')[1]
|
||||
|
||||
sink_slider:connect_signal('property::value', function(_, value)
|
||||
audio_helper.set_sink_volume(value)
|
||||
end)
|
||||
|
||||
-- Set the volume and icon
|
||||
audio_helper:connect_signal('sink::get', function(_, muted, volume)
|
||||
volume = tonumber(volume)
|
||||
assert(type(muted) == 'boolean' and type(volume) == 'number', 'audio::get signal expects boolean and number')
|
||||
if w.sink_volume == volume and w.sink_muted == muted then return end
|
||||
w.sink_volume = volume
|
||||
w.sink_muted = muted
|
||||
if muted then
|
||||
sink_icon:set_image(gcolor.recolor_image(icondir .. 'volume-mute.svg', Theme_config.volume_controller.volume_fg))
|
||||
else
|
||||
local icon = icondir .. 'volume'
|
||||
if volume == 0 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume > 0 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
|
||||
sink_slider:set_value(volume)
|
||||
sink_icon:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_controller.volume_fg))
|
||||
end
|
||||
end)
|
||||
|
||||
local source_icon = w:get_children_by_id('source_icon')[1]
|
||||
local source_slider = w:get_children_by_id('source_slider')[1]
|
||||
|
||||
-- Microphone slider change event
|
||||
source_slider:connect_signal('property::value', function(_, value)
|
||||
audio_helper.set_source_volume(value)
|
||||
end)
|
||||
|
||||
--- Set the source volume and icon
|
||||
audio_helper:connect_signal('source::get', function(_, muted, volume)
|
||||
volume = tonumber(volume)
|
||||
assert(type(muted) == 'boolean' and type(volume) == 'number', 'microphone::get signal expects boolean and number')
|
||||
if w.source_volume == volume and w.source_muted == muted then return end
|
||||
w.source_volume = volume
|
||||
w.source_muted = muted
|
||||
if muted then
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
if not volume then return end
|
||||
source_slider:set_value(tonumber(volume))
|
||||
if volume > 0 then
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local sink_dd_shape = w:get_children_by_id('sink_dd_shape')[1]
|
||||
local sink_height = w:get_children_by_id('sink_height')[1]
|
||||
local sink_dd_icon = w:get_children_by_id('sink_dd_icon')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = sink_height.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
sink_height.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
sink_dd_shape:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
if sink_height.height == 0 then
|
||||
local size = dpi((#w.sinks * 44) + ((#w.sinks - 1) * 10) + 20)
|
||||
|
||||
if #w.sinks > 4 then
|
||||
size = dpi(226)
|
||||
end
|
||||
rubato_timer.target = size
|
||||
|
||||
sink_dd_shape.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
|
||||
sink_dd_shape.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end),
|
||||
})
|
||||
|
||||
local source_dd_shape = w:get_children_by_id('source_dd_shape')[1]
|
||||
local source_height = w:get_children_by_id('source_height')[1]
|
||||
local source_dd_icon = w:get_children_by_id('source_dd_icon')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = source_height.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
source_height.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
source_dd_shape:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
if source_height.height == 0 then
|
||||
local size = dpi(((#w.sources * 44) + ((#w.sources - 1) * 10) + 20))
|
||||
|
||||
if #w.sources > 4 then
|
||||
size = dpi(226)
|
||||
end
|
||||
|
||||
rubato_timer.target = size
|
||||
|
||||
source_dd_shape.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
|
||||
source_dd_shape.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end),
|
||||
})
|
||||
|
||||
local sink_list = w:get_children_by_id('sink_list')[1]
|
||||
w:get_sink_devices_async(function()
|
||||
sink_list.children = w.sinks
|
||||
end)
|
||||
|
||||
local source_list = w:get_children_by_id('source_list')[1]
|
||||
w:get_source_devices_async(function()
|
||||
source_list.children = w.sources
|
||||
end)
|
||||
|
||||
hover.bg_hover { widget = sink_dd_shape }
|
||||
hover.bg_hover { widget = source_dd_shape }
|
||||
return w
|
||||
end
|
||||
|
||||
return setmetatable(audio_controller, { __call = function() return audio_controller.new() end })
|
||||
@@ -1,553 +0,0 @@
|
||||
-----------------------------------
|
||||
-- This is the volume controller --
|
||||
-----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local gobject = require("gears.object")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mousegrabber = mousegrabber,
|
||||
}
|
||||
|
||||
local rubato = require("src.lib.rubato")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
|
||||
|
||||
local volume_controler = { mt = {} }
|
||||
|
||||
function volume_controler.get_device_widget()
|
||||
local device = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
text = name,
|
||||
id = "node",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "device_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "device_margin",
|
||||
margins = dpi(9),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "background",
|
||||
bg = Theme_config.volume_controller.device_bg,
|
||||
border_color = Theme_config.volume_controller.device_border_color,
|
||||
border_width = Theme_config.volume_controller.device_border_width,
|
||||
shape = Theme_config.volume_controller.device_shape,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
if true then
|
||||
device:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
if node then
|
||||
--awful.spawn("./.config/awesome/src/scripts/vol.sh set_sink " .. node)
|
||||
--capi.awesome.emit_signal("update::bg_sink", node)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
--[[ capi.awesome.connect_signal(
|
||||
"update::bg_sink",
|
||||
function(new_node)
|
||||
if node == new_node then
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
|
||||
Theme_config.volume_controller.device_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_headphones_selected_bg
|
||||
device.fg = Theme_config.volume_controller.device_headphones_selected_fg
|
||||
Hover_signal(device)
|
||||
else
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_bg
|
||||
device.fg = Theme_config.volume_controller.device_headphones_fg
|
||||
Hover_signal(device)
|
||||
end
|
||||
end
|
||||
) ]]
|
||||
else
|
||||
device:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
if node then
|
||||
--awful.spawn("./.config/awesome/src/scripts/mic.sh set_source " .. node)
|
||||
--capi.awesome.emit_signal("update::bg_source", node)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
--[[ capi.awesome.connect_signal(
|
||||
"update::bg_source",
|
||||
function(new_node)
|
||||
if node == new_node then
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
|
||||
Theme_config.volume_controller.device_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_microphone_selected_bg
|
||||
device.fg = Theme_config.volume_controller.device_microphone_selected_fg
|
||||
Hover_signal(device)
|
||||
else
|
||||
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color)
|
||||
device.bg = Theme_config.volume_controller.device_bg
|
||||
device.fg = Theme_config.volume_controller.device_microphone_fg
|
||||
Hover_signal(device)
|
||||
end
|
||||
end
|
||||
) ]]
|
||||
end
|
||||
return device
|
||||
end
|
||||
|
||||
-- Get all source devices
|
||||
function volume_controler:get_source_devices()
|
||||
|
||||
end
|
||||
|
||||
-- Get all input devices
|
||||
function volume_controler:get_input_devices()
|
||||
|
||||
end
|
||||
|
||||
function volume_controler:toggle()
|
||||
volume_controler.popup.visible = not volume_controler.popup.visible
|
||||
end
|
||||
|
||||
function volume_controler.run(args)
|
||||
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
-- Audio Device selector
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon"
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Output Device",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "device_name"
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "audio_volume",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "audio_bg",
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_headphones_fg,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "audio_selector_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
id = "volume_list",
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
id = "volume_device_list",
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "place",
|
||||
height = dpi(200),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
id = "volume_device_background",
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_height = 0
|
||||
},
|
||||
-- Microphone selector
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon",
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Input Device",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "device_name"
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "mic_volume",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "mic_bg",
|
||||
bg = Theme_config.volume_controller.list_bg,
|
||||
fg = Theme_config.volume_controller.list_microphone_fg,
|
||||
shape = Theme_config.volume_controller.selector_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "mic_selector_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
id = "mic_list",
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
id = "volume_device_list",
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "place",
|
||||
height = dpi(200),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "volume_device_background",
|
||||
border_color = Theme_config.volume_controller.list_border_color,
|
||||
border_width = Theme_config.volume_controller.list_border_width,
|
||||
shape = Theme_config.volume_controller.list_shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_height = 0
|
||||
},
|
||||
-- Audio volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_controller.volume_fg),
|
||||
id = "icon",
|
||||
},
|
||||
{
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.border_color,
|
||||
bar_active_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.volume_fg,
|
||||
handle_width = dpi(12),
|
||||
maximum = 100,
|
||||
forced_height = dpi(26),
|
||||
widget = wibox.widget.slider,
|
||||
id = "slider"
|
||||
},
|
||||
left = dpi(5),
|
||||
id = "slider_margin",
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "audio_volume",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "audio_volume_margin",
|
||||
top = dpi(10),
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
-- Microphone volume slider
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "microphone.svg", Theme_config.volume_controller.microphone_fg),
|
||||
id = "icon"
|
||||
},
|
||||
{
|
||||
{
|
||||
bar_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(5))
|
||||
end,
|
||||
bar_height = dpi(5),
|
||||
bar_color = Theme_config.volume_controller.device_border_color,
|
||||
bar_active_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_border_color = Theme_config.volume_controller.microphone_fg,
|
||||
handle_width = dpi(12),
|
||||
maximum = 100,
|
||||
forced_height = dpi(26),
|
||||
widget = wibox.widget.slider,
|
||||
id = "slider"
|
||||
},
|
||||
left = dpi(5),
|
||||
id = "slider_margin",
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "mic_volume",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "mic_volume_margin",
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "controller_layout",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "controller_margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = Theme_config.volume_controller.bg,
|
||||
border_color = Theme_config.volume_controller.border_color,
|
||||
border_width = Theme_config.volume_controller.border_width,
|
||||
shape = Theme_config.volume_controller.shape,
|
||||
forced_width = dpi(400),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
ret.widget = w
|
||||
ret.audio_dropdown = w:get_children_by_id("audio_list")[1]
|
||||
ret.mic_dropdown = w:get_children_by_id("mic_list")[1]
|
||||
ret.audio_slider = w:get_children_by_id("slider")[1]
|
||||
ret.mic_slider = w:get_children_by_id("slider")[1]
|
||||
|
||||
-- Main container
|
||||
ret.popup = awful.popup {
|
||||
widget = w,
|
||||
ontop = true,
|
||||
bg = Theme_config.volume_controller.bg,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
--! Calculate the popup position instead of hardcoding it
|
||||
placement = function(c) awful.placement.align(c,
|
||||
{ position = "top_right", margins = { right = dpi(305), top = dpi(60) } })
|
||||
end,
|
||||
shape = Theme_config.volume_controller.shape,
|
||||
}
|
||||
|
||||
-- Set the volume and icon
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
|
||||
.recolor_image(icondir .. "volume-mute.svg", Theme_config.volume_controller.volume_fg))
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. "volume"
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.slider_margin.slider:
|
||||
set_value(volume)
|
||||
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
|
||||
.recolor_image(icon
|
||||
.. ".svg", Theme_config.volume_controller.volume_fg))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Get microphone volume
|
||||
capi.awesome.connect_signal(
|
||||
"microphone::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
--volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(0))
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(volume))
|
||||
if volume > 0 then
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone.svg", Theme_config.volume_controller.microphone_fg))
|
||||
else
|
||||
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
|
||||
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Microphone slider change event
|
||||
ret.widget:connect_signal(
|
||||
"property::value",
|
||||
function()
|
||||
end
|
||||
)
|
||||
|
||||
-- Slide animation
|
||||
ret.audio_dropdown:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.4,
|
||||
intro = 0.1,
|
||||
outro = 0.1,
|
||||
pos = mic_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
mic_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if mic_list.forced_height == 0 then
|
||||
rubato_timer.target = dpi(200)
|
||||
mic_selector_margin.mic_bg.shape = function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
mic_bg.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(4))
|
||||
end
|
||||
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_microphone_selected_icon_color))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Slide animation
|
||||
ret.mic_dropdown:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, key)
|
||||
if key == 1 then
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.4,
|
||||
intro = 0.1,
|
||||
outro = 0.1,
|
||||
pos = volume_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
volume_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if volume_list.forced_height == 0 then
|
||||
rubato_timer.target = dpi(200)
|
||||
audio_bg.shape = function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
audio_bg.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(4))
|
||||
end
|
||||
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
|
||||
Theme_config.volume_controller.device_headphones_selected_icon_color))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function volume_controler.mt:__call(...)
|
||||
return volume_controler.run(...)
|
||||
end
|
||||
|
||||
return setmetatable(volume_controler, volume_controler.mt)
|
||||
@@ -3,151 +3,136 @@
|
||||
-----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local gobject = require("gears.object")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
|
||||
|
||||
local osd = { mt = {} }
|
||||
local osd = {}
|
||||
|
||||
function osd:run()
|
||||
self.visible = true
|
||||
if self.timer.started then
|
||||
self.timer:again()
|
||||
else
|
||||
self.timer:start()
|
||||
end
|
||||
end
|
||||
|
||||
function osd.new(args)
|
||||
args = args or {}
|
||||
args.screen = args.screen or 1
|
||||
|
||||
local ret = gobject {}
|
||||
|
||||
ret.w = wibox.widget {
|
||||
{
|
||||
local w = apopup {
|
||||
widget = {
|
||||
{
|
||||
{ -- Volume Icon
|
||||
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_osd.icon_color),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false,
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Volume Bar
|
||||
{
|
||||
{
|
||||
{ -- Volume Icon
|
||||
{
|
||||
id = "progressbar1",
|
||||
color = Theme_config.volume_osd.bar_bg_active,
|
||||
background_color = Theme_config.volume_osd.bar_bg,
|
||||
max_value = 100,
|
||||
value = 50,
|
||||
forced_height = dpi(6),
|
||||
shape = function(cr, width, heigth)
|
||||
gears.shape.rounded_bar(cr, width, heigth, dpi(6))
|
||||
end,
|
||||
widget = wibox.widget.progressbar
|
||||
image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.volume_osd.icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "progressbar_container2",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
id = "progressbar_container",
|
||||
width = dpi(240),
|
||||
heigth = dpi(20),
|
||||
stragety = "max",
|
||||
widget = wibox.container.constraint
|
||||
{ -- Volume Bar
|
||||
{
|
||||
{
|
||||
id = 'progressbar',
|
||||
color = Theme_config.volume_osd.bar_bg_active,
|
||||
background_color = Theme_config.volume_osd.bar_bg,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
shape = gshape.rounded_rect,
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
height = dpi(5),
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{ -- Volume text
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'text_role',
|
||||
text = '0',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(20),
|
||||
bottom = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
shape = Theme_config.volume_osd.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
forced_width = dpi(300),
|
||||
forced_height = dpi(80),
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
border_color = Theme_config.volume_osd.border_color,
|
||||
border_width = Theme_config.volume_osd.border_width,
|
||||
fg = Theme_config.volume_osd.fg,
|
||||
bg = Theme_config.volume_osd.bg,
|
||||
widget = wibox.container.background
|
||||
screen = 1,
|
||||
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
|
||||
}
|
||||
|
||||
local volume_container = awful.popup {
|
||||
widget = ret.w,
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
placement = function(c) awful.placement.bottom_left(c, { margins = dpi(20) }) end,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(14))
|
||||
end
|
||||
}
|
||||
gtable.crush(w, osd)
|
||||
|
||||
local hide_volume_osd = gears.timer {
|
||||
w.timer = gtimer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
volume_container.visible = false
|
||||
end
|
||||
w.visible = false
|
||||
end,
|
||||
}
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
if muted then
|
||||
ret.w:get_children_by_id("icon")[1]
|
||||
:set_image(gears.color.recolor_image(
|
||||
icondir .. "volume-mute" .. ".svg", Theme_config.volume_osd.icon_color))
|
||||
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(0)
|
||||
else
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(volume)
|
||||
local icon = icondir .. "volume"
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
ret.w:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.volume_osd.icon_color))
|
||||
audio_helper:connect_signal('output::get', function(_, muted, volume)
|
||||
volume = tonumber(volume or 0)
|
||||
if muted then
|
||||
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icondir .. 'volume-mute' .. '.svg', Theme_config.volume_osd.icon_color))
|
||||
w.widget:get_children_by_id('progressbar')[1].value = 0
|
||||
else
|
||||
w.widget:get_children_by_id('progressbar')[1].value = volume
|
||||
local icon = icondir .. 'volume'
|
||||
if volume < 1 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"widget::volume_osd:rerun",
|
||||
function()
|
||||
if capi.mouse.screen == args.screen then
|
||||
volume_container.visible = true
|
||||
if hide_volume_osd.started then
|
||||
hide_volume_osd:again()
|
||||
else
|
||||
hide_volume_osd:start()
|
||||
end
|
||||
end
|
||||
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_osd.icon_color))
|
||||
w.widget:get_children_by_id('text_role')[1].text = volume
|
||||
end
|
||||
)
|
||||
w:run()
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
function osd.mt:__call(...)
|
||||
return osd.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(osd, osd.mt)
|
||||
return setmetatable(osd, { __call = function(_, ...) return osd.new(...) end })
|
||||
|
||||
@@ -3,23 +3,24 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local awidget = require("awful.widget")
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears").color
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gtable = require("gears").table
|
||||
local lgi = require("lgi")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local awidget = require('awful.widget')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears').color
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gtable = require('gears').table
|
||||
local lgi = require('lgi')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Own libs
|
||||
local context_menu = require("src.modules.context_menu")
|
||||
local context_menu = require('src.modules.context_menu.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
local device = { mt = {} }
|
||||
@@ -33,7 +34,7 @@ function device:layout(_, width, height)
|
||||
end
|
||||
|
||||
function device:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
@@ -48,29 +49,14 @@ end
|
||||
|
||||
--#endregion
|
||||
|
||||
local dbus_proxy = require('dbus_proxy')
|
||||
--- Connect to a device if not connected else disconnect
|
||||
function device:toggle_connect()
|
||||
if not self.device.Paired then
|
||||
self:toggle_pair()
|
||||
return
|
||||
end
|
||||
if not self.device.Connected then
|
||||
|
||||
--TODO: Implement device passcode support, I have no idea how to get the
|
||||
--TODO: Methods from Agent1 implemented
|
||||
--[[ self._private.AgentManager1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.AgentManager1"
|
||||
}
|
||||
|
||||
self._private.Agent1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.Agent1",
|
||||
}
|
||||
|
||||
self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, "")
|
||||
self._private.AgentManager1:RequestDefaultAgent(self._private.Agent1.object_path) ]]
|
||||
|
||||
self.device:ConnectAsync()
|
||||
else
|
||||
self.device:DisconnectAsync()
|
||||
@@ -79,37 +65,52 @@ end
|
||||
|
||||
--- Pair to a device if not paired else unpair
|
||||
function device:toggle_pair()
|
||||
if self.device.Paired then
|
||||
if not self.device.Paired then
|
||||
self._private.AgentManager1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.bluez',
|
||||
path = '/org/bluez',
|
||||
interface = 'org.bluez.AgentManager1',
|
||||
}
|
||||
|
||||
self._private.Agent1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.bluez',
|
||||
path = '/org/bluez',
|
||||
interface = 'org.bluez.Agent1',
|
||||
}
|
||||
|
||||
self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, 'KeyboardDisplay')
|
||||
self.device:PairAsync()
|
||||
else
|
||||
self.device:CancelPairingAsync()
|
||||
--Remove via adapter
|
||||
end
|
||||
end
|
||||
|
||||
--- Trust a device if not trusted else untrust
|
||||
function device:toggle_trusted()
|
||||
self.device:Set("org.bluez.Device1", "Trusted", lgi.GLib.Variant("b", not self.device.Trusted))
|
||||
self.device.Trusted = { signature = "b", value = not self.device.Trusted }
|
||||
self.device:Set('org.bluez.Device1', 'Trusted', lgi.GLib.Variant('b', not self.device.Trusted))
|
||||
self.device.Trusted = { signature = 'b', value = not self.device.Trusted }
|
||||
end
|
||||
|
||||
---Rename a device alias
|
||||
---@param newname string New name, if empty the device name will be reset
|
||||
---@return string name The new or old name depending if the string was empty or not
|
||||
function device:rename(newname)
|
||||
self.device:Set("org.bluez.Device1", "Alias", lgi.GLib.Variant("s", newname))
|
||||
self.device.Alias = { signature = "s", value = newname }
|
||||
return self.device:Get("org.bluez.Device1", "Alias")
|
||||
self.device:Set('org.bluez.Device1', 'Alias', lgi.GLib.Variant('s', newname))
|
||||
self.device.Alias = { signature = 's', value = newname }
|
||||
return self.device:Get('org.bluez.Device1', 'Alias')
|
||||
end
|
||||
|
||||
function device.new(args)
|
||||
args = args or {}
|
||||
|
||||
local icon = device.Icon or "bluetooth-on"
|
||||
local icon = device.Icon or 'bluetooth-on'
|
||||
|
||||
local inputbox = awidget.inputbox {
|
||||
text = args.device.Alias or args.device.Name,
|
||||
halign = "left",
|
||||
valign = "center",
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
}
|
||||
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
@@ -119,78 +120,80 @@ function device.new(args)
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(
|
||||
icondir .. icon .. ".svg", Theme_config.bluetooth_controller.icon_color),
|
||||
icondir .. icon .. '.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
inputbox,
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(300),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ -- Spacing
|
||||
forced_width = dpi(10),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "con",
|
||||
id = 'con',
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = Theme_config.bluetooth_controller.icon_shape,
|
||||
bg = Theme_config.bluetooth_controller.con_button_color,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
margin = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.bluetooth_controller.device_bg,
|
||||
fg = Theme_config.bluetooth_controller.device_fg,
|
||||
border_color = Theme_config.bluetooth_controller.device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.device_border_width,
|
||||
id = "background",
|
||||
id = 'background',
|
||||
shape = Theme_config.bluetooth_controller.device_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(ret, 'Failed to create widget')
|
||||
|
||||
gtable.crush(ret, device, true)
|
||||
|
||||
ret.device = args.device or {}
|
||||
|
||||
-- Set the image of the connection button depending on the connection state
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. 'link.svg' or
|
||||
icondir .. 'link-off.svg',
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
|
||||
local cm = context_menu {
|
||||
@@ -201,78 +204,82 @@ function device.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}, spacing = dpi(10),
|
||||
entries = {
|
||||
{ -- Connect/Disconnect a device
|
||||
name = ret.device.Connected and "Disconnect" or "Connect",
|
||||
icon = gcolor.recolor_image(ret.device.Connected and icondir .. "bluetooth-off.svg" or
|
||||
icondir .. "bluetooth-on.svg",
|
||||
name = ret.device.Connected and 'Disconnect' or 'Connect',
|
||||
icon = gcolor.recolor_image(ret.device.Connected and icondir .. 'bluetooth-off.svg' or
|
||||
icondir .. 'bluetooth-on.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_connect()
|
||||
end,
|
||||
id = "connected"
|
||||
id = 'connected',
|
||||
},
|
||||
{ -- Pair/Unpair a device
|
||||
name = "Pair",
|
||||
icon = gcolor.recolor_image(ret.device.Paired and icondir .. "link-off.svg" or
|
||||
icondir .. "link.svg",
|
||||
name = 'Pair',
|
||||
icon = gcolor.recolor_image(ret.device.Paired and icondir .. 'link-off.svg' or
|
||||
icondir .. 'link.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_pair()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{ -- Trust/Untrust a device
|
||||
name = ret.device.Trusted and "Untrust" or "Trust",
|
||||
icon = gcolor.recolor_image(ret.device.Trusted and icondir .. "untrusted.svg" or icondir .. "trusted.svg",
|
||||
name = ret.device.Trusted and 'Untrust' or 'Trust',
|
||||
icon = gcolor.recolor_image(ret.device.Trusted and icondir .. 'untrusted.svg' or icondir .. 'trusted.svg',
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_trusted()
|
||||
end,
|
||||
id = "trusted"
|
||||
id = 'trusted',
|
||||
},
|
||||
{ -- Rename a device
|
||||
name = "Rename",
|
||||
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
name = 'Rename',
|
||||
icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
inputbox:focus()
|
||||
inputbox:connect_signal("submit", function(text)
|
||||
inputbox:connect_signal('submit', function(text)
|
||||
text = text:get_text()
|
||||
inputbox.markup = ret:rename(text)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{ -- Remove a device
|
||||
name = "Remove",
|
||||
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
name = 'Remove',
|
||||
icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
args.remove_callback(ret.device)
|
||||
end
|
||||
}
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cm:connect_signal('mouse::leave', function()
|
||||
cm.visible = false
|
||||
end)
|
||||
|
||||
ret:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
-- Toggle the connection state
|
||||
@@ -281,19 +288,19 @@ function device.new(args)
|
||||
abutton({}, 3, function()
|
||||
-- Show the context menu and update its entrie names
|
||||
for _, value in ipairs(cm.widget.children) do
|
||||
value.id = value.id or ""
|
||||
if value.id:match("connected") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Connected and "Disconnect" or "Connect"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Connected and
|
||||
icondir .. "bluetooth-off.svg" or icondir .. "bluetooth-on.svg",
|
||||
value.id = value.id or ''
|
||||
if value.id:match('connected') then
|
||||
value:get_children_by_id('text_role')[1].text = ret.device.Connected and 'Disconnect' or 'Connect'
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Connected and
|
||||
icondir .. 'bluetooth-off.svg' or icondir .. 'bluetooth-on.svg',
|
||||
Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("trusted") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Trusted and "Untrust" or "Trust"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Trusted and
|
||||
icondir .. "untrusted.svg" or icondir .. "trusted.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("paired") then
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Paired and
|
||||
icondir .. "link-off.svg" or icondir .. "link.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match('trusted') then
|
||||
value:get_children_by_id('text_role')[1].text = ret.device.Trusted and 'Untrust' or 'Trust'
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Trusted and
|
||||
icondir .. 'untrusted.svg' or icondir .. 'trusted.svg', Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match('paired') then
|
||||
value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Paired and
|
||||
icondir .. 'link-off.svg' or icondir .. 'link.svg', Theme_config.bluetooth_controller.icon_color)
|
||||
end
|
||||
end
|
||||
cm:toggle()
|
||||
@@ -301,13 +308,13 @@ function device.new(args)
|
||||
))
|
||||
|
||||
-- Update the updated device icon
|
||||
capi.awesome.connect_signal(ret.device.object_path .. "_updated", function(d)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(d.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
capi.awesome.connect_signal(ret.device.object_path .. '_updated', function(d)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(d.Connected and icondir .. 'link.svg' or
|
||||
icondir .. 'link-off.svg',
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
end)
|
||||
|
||||
Hover_signal(ret)
|
||||
hover.bg_hover { widget = ret }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
--------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local aspawn = require("awful.spawn")
|
||||
local base = require("wibox.widget.base")
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears").color
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gshape = require("gears").shape
|
||||
local gtable = require("gears").table
|
||||
local gtimer = require("gears.timer")
|
||||
local lgi = require("lgi")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aspawn = require('awful.spawn')
|
||||
local base = require('wibox.widget.base')
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears').color
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gshape = require('gears').shape
|
||||
local gtable = require('gears').table
|
||||
local gtimer = require('gears.timer')
|
||||
local lgi = require('lgi')
|
||||
local naughty = require('naughty')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require("src.lib.rubato")
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Own libs
|
||||
local bt_device = require("src.modules.bluetooth.device")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local bt_device = require('src.modules.bluetooth.device')
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -61,13 +62,13 @@ end
|
||||
---Get the list of paired devices
|
||||
---@return table devices table of paired devices
|
||||
function bluetooth:get_paired_devices()
|
||||
return self:get_children_by_id("connected_device_list")[1].children
|
||||
return self:get_children_by_id('connected_device_list')[1].children
|
||||
end
|
||||
|
||||
---Get the list of discovered devices
|
||||
---@return table devices table of discovered devices
|
||||
function bluetooth:get_discovered_devices()
|
||||
return self:get_children_by_id("discovered_device_list")[1].children
|
||||
return self:get_children_by_id('discovered_device_list')[1].children
|
||||
end
|
||||
|
||||
--- Remove a device by first disconnecting it async then removing it
|
||||
@@ -81,8 +82,8 @@ end
|
||||
function bluetooth:add_device(device, object_path)
|
||||
|
||||
-- Get a reference to both lists
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
local plist = self:get_children_by_id('connected_device_list')[1]
|
||||
local dlist = self:get_children_by_id('discovered_device_list')[1]
|
||||
|
||||
-- For the first list check if the device already exists and if its connection state changed
|
||||
-- if it changed then remove it from the current list and put it into the other one
|
||||
@@ -117,6 +118,7 @@ function bluetooth:add_device(device, object_path)
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
self:emit_signal('device::added_connected')
|
||||
else
|
||||
dlist:add(bt_device {
|
||||
device = device,
|
||||
@@ -125,22 +127,25 @@ function bluetooth:add_device(device, object_path)
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
self:emit_signal('device::added_discovered')
|
||||
end
|
||||
end
|
||||
|
||||
---Remove a device from any list
|
||||
---@param object_path string the object path of the device
|
||||
function bluetooth:remove_device(object_path)
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
local plist = self:get_children_by_id('connected_device_list')[1]
|
||||
local dlist = self:get_children_by_id('discovered_device_list')[1]
|
||||
for _, d in ipairs(dlist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
dlist:remove_widgets(d)
|
||||
self:emit_signal('device::removed_discovered')
|
||||
end
|
||||
end
|
||||
for _, d in ipairs(plist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
if d.device.object_path == object_path and (not d.device.Paired) then
|
||||
plist:remove_widgets(d)
|
||||
self:emit_signal('device::removed_connected')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -159,42 +164,42 @@ end
|
||||
function bluetooth:toggle()
|
||||
local powered = self._private.Adapter1.Powered
|
||||
|
||||
self._private.Adapter1:Set("org.bluez.Adapter1", "Powered", lgi.GLib.Variant("b", not powered))
|
||||
self._private.Adapter1:Set('org.bluez.Adapter1', 'Powered', lgi.GLib.Variant('b', not powered))
|
||||
self._private.Adapter1.Powered = {
|
||||
signature = "b",
|
||||
value = not powered
|
||||
signature = 'b',
|
||||
value = not powered,
|
||||
}
|
||||
end
|
||||
|
||||
--- Open blueman-manager
|
||||
function bluetooth:open_settings()
|
||||
aspawn("blueman-manager")
|
||||
aspawn('blueman-manager')
|
||||
end
|
||||
|
||||
---Get a new device proxy and connect a PropertyChanged signal to it and
|
||||
---add the device to the list
|
||||
---@param object_path string the object path of the device
|
||||
function bluetooth:get_device_info(object_path)
|
||||
if (not object_path) or (not object_path:match("/org/bluez/hci0/dev")) then return end
|
||||
if (not object_path) or (not object_path:match('/org/bluez/hci0/dev')) then return end
|
||||
|
||||
-- New Device1 proxy
|
||||
local Device1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Device1",
|
||||
path = object_path
|
||||
name = 'org.bluez',
|
||||
interface = 'org.bluez.Device1',
|
||||
path = object_path,
|
||||
}
|
||||
|
||||
-- New Properties proxy for the object_path
|
||||
local Device1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = object_path
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = object_path,
|
||||
}
|
||||
|
||||
-- Just return if the Device1 has no name, this usually means random devices with just a mac address
|
||||
if (not Device1.Name) or (Device1.Name == "") then return end
|
||||
if (not Device1.Name) or (Device1.Name == '') then return end
|
||||
|
||||
-- For some reason it notifies twice or thrice
|
||||
local just_notified = false
|
||||
@@ -205,29 +210,29 @@ function bluetooth:get_device_info(object_path)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
just_notified = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
-- Connect the PropertyChanged signal to update the device when a property changes and send a notification
|
||||
Device1Properties:connect_signal(function(_, _, changed_props)
|
||||
if changed_props["Connected"] ~= nil then
|
||||
if changed_props['Connected'] ~= nil then
|
||||
if not just_notified then
|
||||
naughty.notification({
|
||||
app_icon = icondir .. "bluetooth-on.svg",
|
||||
app_name = "Bluetooth",
|
||||
naughty.notification {
|
||||
app_icon = icondir .. 'bluetooth-on.svg',
|
||||
app_name = 'Bluetooth',
|
||||
title = Device1.Name,
|
||||
icon = gcolor.recolor_image(icondir .. Device1.Icon .. ".svg", Theme_config.bluetooth_controller.icon_color),
|
||||
icon = icondir .. Device1.Icon .. '.svg',
|
||||
timeout = 5,
|
||||
message = "Device " ..
|
||||
Device1.Name .. " is now " .. (changed_props["Connected"] and "connected" or "disconnected"),
|
||||
category = Device1.Connected and "device.added" or "device.removed",
|
||||
})
|
||||
message = 'Device ' ..
|
||||
Device1.Name .. ' is now ' .. (changed_props['Connected'] and 'connected' or 'disconnected'),
|
||||
category = Device1.Connected and 'device.added' or 'device.removed',
|
||||
}
|
||||
just_notified = true
|
||||
notify_timer:start()
|
||||
end
|
||||
end
|
||||
capi.awesome.emit_signal(object_path .. "_updated", Device1)
|
||||
end, "PropertiesChanged")
|
||||
capi.awesome.emit_signal(object_path .. '_updated', Device1)
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
self:add_device(Device1, object_path)
|
||||
end
|
||||
@@ -236,13 +241,12 @@ end
|
||||
---@param powered boolean the powered state of the adapter
|
||||
local function send_state_notification(powered)
|
||||
naughty.notification {
|
||||
app_icon = gcolor.recolor_image(icondir .. "bluetooth-on.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
app_name = "Bluetooth",
|
||||
title = "Bluetooth",
|
||||
message = powered and "Enabled" or "Disabled",
|
||||
icon = gcolor.recolor_image(powered and icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
category = powered and "device.added" or "device.removed",
|
||||
app_icon = icondir .. 'bluetooth-on.svg',
|
||||
app_name = 'Bluetooth',
|
||||
title = 'Bluetooth',
|
||||
message = powered and 'Enabled' or 'Disabled',
|
||||
icon = powered and icondir .. 'bluetooth-on.svg' or icondir .. 'bluetooth-off.svg',
|
||||
category = powered and 'device.added' or 'device.removed',
|
||||
}
|
||||
end
|
||||
|
||||
@@ -250,7 +254,7 @@ function bluetooth.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- For some reason the first widget isn't read so the first container is a duplicate
|
||||
local ret = base.make_widget_from_value({
|
||||
local ret = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -258,128 +262,132 @@ function bluetooth.new(args)
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "connected_icon"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'connected_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Paired Devices",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
text = 'Paired Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
bg = Theme_config.bluetooth_controller.connected_bg,
|
||||
fg = Theme_config.bluetooth_controller.connected_fg,
|
||||
shape = Theme_config.bluetooth_controller.connected_shape,
|
||||
widget = wibox.container.background,
|
||||
id = "connected_bg"
|
||||
id = 'connected_bg',
|
||||
},
|
||||
id = "connected_margin",
|
||||
widget = wibox.container.margin
|
||||
id = 'connected_margin',
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
scrollbar_width = 0,
|
||||
id = "connected_device_list"
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
id = 'connected_device_list',
|
||||
},
|
||||
id = 'margin',
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0,
|
||||
id = "connected_list",
|
||||
widget = wibox.container.constraint,
|
||||
strategy = 'exact',
|
||||
height = 0,
|
||||
id = 'connected_list',
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "discovered_icon",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'discovered_icon',
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Nearby Devices",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
text = 'Nearby Devices',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "discovered_bg",
|
||||
id = 'discovered_bg',
|
||||
bg = Theme_config.bluetooth_controller.discovered_bg,
|
||||
fg = Theme_config.bluetooth_controller.discovered_fg,
|
||||
shape = Theme_config.bluetooth_controller.discovered_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "discovered_margin",
|
||||
id = 'discovered_margin',
|
||||
top = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "discovered_device_list",
|
||||
id = 'discovered_device_list',
|
||||
spacing = dpi(10),
|
||||
step = dpi(50),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.bluetooth_controller.con_device_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.con_device_border_width,
|
||||
shape = Theme_config.bluetooth_controller.con_device_shape,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0,
|
||||
id = "discovered_list",
|
||||
id = 'discovered_list',
|
||||
},
|
||||
{
|
||||
{ -- action buttons
|
||||
{
|
||||
dnd_widget {
|
||||
color = Theme_config.bluetooth_controller.power_bg,
|
||||
size = dpi(40)
|
||||
size = dpi(40),
|
||||
},
|
||||
id = "dnd",
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
nil,
|
||||
{ -- refresh
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. "refresh.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'refresh.svg',
|
||||
Theme_config.bluetooth_controller.refresh_icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
@@ -387,28 +395,30 @@ function bluetooth.new(args)
|
||||
},
|
||||
shape = Theme_config.bluetooth_controller.refresh_shape,
|
||||
bg = Theme_config.bluetooth_controller.refresh_bg,
|
||||
id = "scan",
|
||||
widget = wibox.container.background
|
||||
id = 'scan',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
}
|
||||
|
||||
assert(type(ret) == 'table', 'bluetooth_controller: ret is not a table')
|
||||
|
||||
-- Get a reference to the dnd button
|
||||
local dnd = ret:get_children_by_id("dnd")[1]:get_widget()
|
||||
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
|
||||
|
||||
-- Toggle bluetooth on or off
|
||||
dnd:connect_signal("dnd::toggle", function(enable)
|
||||
dnd:connect_signal('dnd::toggle', function()
|
||||
ret:toggle()
|
||||
end)
|
||||
|
||||
@@ -418,36 +428,38 @@ function bluetooth.new(args)
|
||||
-- Create a proxy for the freedesktop ObjectManager
|
||||
ret._private.ObjectManager = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.ObjectManager",
|
||||
path = "/"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.ObjectManager',
|
||||
path = '/',
|
||||
}
|
||||
|
||||
-- Create a proxy for the bluez Adapter1 interface
|
||||
ret._private.Adapter1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Adapter1",
|
||||
path = "/org/bluez/hci0"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.bluez.Adapter1',
|
||||
path = '/org/bluez/hci0',
|
||||
}
|
||||
|
||||
if not ret._private.Adapter1.Powered then return end
|
||||
|
||||
-- Create a proxy for the bluez Adapter1 Properties interface
|
||||
ret._private.Adapter1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = "/org/bluez/hci0"
|
||||
name = 'org.bluez',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = '/org/bluez/hci0',
|
||||
}
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesAdded signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:get_device_info(interface)
|
||||
end, "InterfacesAdded")
|
||||
end, 'InterfacesAdded')
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesRemoved signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:remove_device(interface)
|
||||
end, "InterfacesRemoved")
|
||||
end, 'InterfacesRemoved')
|
||||
|
||||
-- Connect to the Adapter1's PropertiesChanged signal
|
||||
ret._private.Adapter1Properties:connect_signal(function(_, _, data)
|
||||
@@ -459,9 +471,9 @@ function bluetooth.new(args)
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", data.Powered)
|
||||
ret:emit_signal('bluetooth::status', data.Powered)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
gtimer.delayed_call(function()
|
||||
for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do
|
||||
@@ -473,100 +485,160 @@ function bluetooth.new(args)
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", ret._private.Adapter1.Powered)
|
||||
ret:emit_signal('bluetooth::status', ret._private.Adapter1.Powered)
|
||||
send_state_notification(ret._private.Adapter1.Powered)
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
--#region Dropdown logic
|
||||
local connected_margin = ret:get_children_by_id("connected_margin")[1]
|
||||
local connected_list = ret:get_children_by_id("connected_list")[1]
|
||||
local connected_icon = ret:get_children_by_id("connected_icon")[1]
|
||||
local connected_margin = ret:get_children_by_id('connected_margin')[1]
|
||||
local connected_list = ret:get_children_by_id('connected_list')[1]
|
||||
local connected_icon = ret:get_children_by_id('connected_icon')[1]
|
||||
|
||||
local connected_animation = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = connected_list.height,
|
||||
clamp_position = true,
|
||||
subscribed = function(v)
|
||||
connected_list.height = v
|
||||
end,
|
||||
}
|
||||
|
||||
ret:connect_signal('device::added_connected', function(device)
|
||||
if device.Connected then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
connected_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = connected_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
connected_list.forced_height = v
|
||||
end
|
||||
}
|
||||
if connected_list.forced_height == 0 then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
rubato_timer.target = dpi(size)
|
||||
end
|
||||
if size > 0 then
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
local discovered_margin = ret:get_children_by_id("discovered_margin")[1]
|
||||
local discovered_list = ret:get_children_by_id("discovered_list")[1]
|
||||
local discovered_bg = ret:get_children_by_id("discovered_bg")[1]
|
||||
local discovered_icon = ret:get_children_by_id("discovered_icon")[1]
|
||||
ret:connect_signal('device::removed_connected', function(device)
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
discovered_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = discovered_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
discovered_list.forced_height = v
|
||||
end
|
||||
}
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
|
||||
if discovered_list.forced_height == 0 then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
connected_margin:connect_signal('button::press', function()
|
||||
if connected_list.height == 0 then
|
||||
local size = (#ret:get_paired_devices() * 60)
|
||||
if size < 210 then
|
||||
connected_animation.target = dpi(size)
|
||||
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
if size > 0 then
|
||||
rubato_timer.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
else
|
||||
connected_animation.target = 0
|
||||
connected_margin.connected_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
|
||||
connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.connected_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
local discovered_margin = ret:get_children_by_id('discovered_margin')[1]
|
||||
local discovered_list = ret:get_children_by_id('discovered_list')[1]
|
||||
local discovered_bg = ret:get_children_by_id('discovered_bg')[1]
|
||||
local discovered_icon = ret:get_children_by_id('discovered_icon')[1]
|
||||
|
||||
local discovered_animation = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = discovered_list.forced_height,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
discovered_list.forced_height = v
|
||||
end,
|
||||
}
|
||||
|
||||
ret:connect_signal('device::added_discovered', function(device)
|
||||
if not device.Connected then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
discovered_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
ret:connect_signal('device::removed_discovered', function(device)
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end)
|
||||
|
||||
discovered_margin:connect_signal('button::press', function()
|
||||
if discovered_list.forced_height == 0 then
|
||||
local size = (#ret:get_discovered_devices() * 60)
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
if size > 0 then
|
||||
discovered_animation.target = dpi(size)
|
||||
discovered_margin.discovered_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
else
|
||||
discovered_animation.target = 0
|
||||
discovered_bg.shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 4)
|
||||
end
|
||||
discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.bluetooth_controller.discovered_icon_color))
|
||||
end
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
-- Add buttons to the scan button
|
||||
ret:get_children_by_id("scan")[1]:buttons({
|
||||
ret:get_children_by_id('scan')[1]:buttons {
|
||||
abutton({}, 1, function()
|
||||
ret:scan()
|
||||
end)
|
||||
})
|
||||
end),
|
||||
}
|
||||
|
||||
Hover_signal(ret:get_children_by_id("scan")[1])
|
||||
hover.bg_hover { widget = ret:get_children_by_id('scan')[1] }
|
||||
hover.bg_hover { widget = connected_margin.connected_bg }
|
||||
hover.bg_hover { widget = discovered_bg }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
---------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local gtimer = require("gears.timer")
|
||||
local wibox = require("wibox")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local backlight_helper = require("src.tools.helpers.backlight")
|
||||
local backlight_helper = require('src.tools.helpers.backlight')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -21,125 +21,119 @@ local capi = {
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/brightness/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/brightness/'
|
||||
|
||||
local brightness_osd = { mt = {} }
|
||||
|
||||
-- Hide the brightness_osd after 3 seconds
|
||||
function brightness_osd:hide()
|
||||
self.timer:stop(false)
|
||||
end
|
||||
|
||||
-- Rerun the timer
|
||||
function brightness_osd:rerun()
|
||||
function brightness_osd:run()
|
||||
self.visible = true
|
||||
self.timer:again(true)
|
||||
end
|
||||
|
||||
-- Show the brightness_osd for 3 seconds
|
||||
function brightness_osd:show()
|
||||
self.visible = true
|
||||
self.timer:start(true)
|
||||
if self.timer.started then
|
||||
self.timer:again()
|
||||
else
|
||||
self.timer:start()
|
||||
end
|
||||
end
|
||||
|
||||
function brightness_osd.new(args)
|
||||
args = args or {}
|
||||
|
||||
local osd = apopup {
|
||||
local w = apopup {
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{ -- Brightness Icon
|
||||
image = gcolor.recolor_image(icondir .. "brightness-high.svg", Theme_config.brightness_osd.icon_color),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false,
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.brightness_ods.icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact'
|
||||
},
|
||||
{ -- Brightness Bar
|
||||
{
|
||||
{
|
||||
id = "progressbar1",
|
||||
color = Theme_config.brightness_osd.bar_bg_active,
|
||||
background_color = Theme_config.brightness_osd.bar_bg,
|
||||
id = 'progressbar',
|
||||
color = Theme_config.brightness_ods.bar_bg_active,
|
||||
background_color = Theme_config.brightness_ods.bar_bg,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(6),
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_bar(cr, width, height, dpi(6))
|
||||
end,
|
||||
shape = gshape.rounded_rect,
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "progressbar_container2",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
height = dpi(5),
|
||||
},
|
||||
id = "progressbar_container",
|
||||
width = dpi(240),
|
||||
heigth = dpi(20),
|
||||
stragety = "max",
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ -- Brightness text
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'text_role',
|
||||
text = '0',
|
||||
valign = 'center',
|
||||
halign = 'center'
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(10),
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(20),
|
||||
bottom = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
forced_width = dpi(300),
|
||||
forced_height = dpi(80),
|
||||
border_color = Theme_config.brightness_osd.border_color,
|
||||
border_width = Theme_config.brightness_osd.border_width,
|
||||
fg = Theme_config.brightness_osd.fg,
|
||||
bg = Theme_config.brightness_osd.bg,
|
||||
shape = Theme_config.brightness_ods.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
ontop = true,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
placement = function(c) aplacement.bottom_left(c, { margins = dpi(20) }) end,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(14))
|
||||
border_color = Theme_config.brightness_ods.border_color,
|
||||
border_width = Theme_config.brightness_ods.border_width,
|
||||
fg = Theme_config.brightness_ods.fg,
|
||||
bg = Theme_config.brightness_ods.bg,
|
||||
screen = 1,
|
||||
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
|
||||
}
|
||||
|
||||
gtable.crush(w, brightness_osd, true)
|
||||
|
||||
w.timer = gtimer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
w.visible = false
|
||||
end
|
||||
}
|
||||
|
||||
gtable.crush(osd, brightness_osd, true)
|
||||
backlight_helper:connect_signal('brightness_changed', function()
|
||||
backlight_helper:brightness_get_async(function(brightness)
|
||||
brightness = brightness / (backlight_helper.brightness_max or 24000) * 100
|
||||
w.widget:get_children_by_id('progressbar')[1].value = brightness
|
||||
|
||||
-- Called when the brightness changes, updates the brightness osd and icon
|
||||
capi.awesome.connect_signal("brightness::changed", function(brightness)
|
||||
if not capi.mouse.screen == args.screen then return end
|
||||
assert(type(brightness) == "number", "brightness must be a number")
|
||||
local icon = icondir .. 'brightness'
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. '-low.svg'
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. '-medium.svg'
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. '-high.svg'
|
||||
end
|
||||
|
||||
brightness = (brightness - 0) / ((backlight_helper.brightness_max or 24000) - 0) * 100
|
||||
osd.widget:get_children_by_id("progressbar1")[1].value = brightness
|
||||
|
||||
local icon = icondir .. "brightness"
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. "-low.svg"
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. "-medium.svg"
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. "-high.svg"
|
||||
end
|
||||
|
||||
osd:rerun(true)
|
||||
osd.widget:get_children_by_id("icon")[1]:set_image(gcolor.recolor_image(icon,
|
||||
Theme_config.brightness_osd.icon_color))
|
||||
w.widget:get_children_by_id('icon')[1]:set_image(gcolor.recolor_image(icon, Theme_config.brightness_osd.icon_color))
|
||||
w.widget:get_children_by_id('text_role')[1].text = brightness
|
||||
w:run()
|
||||
end)
|
||||
end)
|
||||
|
||||
-- osd timer
|
||||
osd.timer = gtimer {
|
||||
timeout = 3,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
osd.visible = false
|
||||
end
|
||||
}
|
||||
return w
|
||||
end
|
||||
|
||||
function brightness_osd.mt:__call(...)
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gobject = require("gears.object")
|
||||
local gshape = require("gears.shape")
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local ical_parser = require("src.tools.ical_parser")()
|
||||
local task_info = require("src.modules.calendar.task_info")
|
||||
local ical_parser = require('src.tools.ical_parser')()
|
||||
local task_info = require('src.modules.calendar.task_info')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/'
|
||||
|
||||
local calendar = { mt = {} }
|
||||
calendar.tasks = {}
|
||||
@@ -27,36 +25,36 @@ calendar._private = {}
|
||||
|
||||
-- Month lookup table
|
||||
calendar._private.months = {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December',
|
||||
}
|
||||
|
||||
-- Weeks shortname lookup table
|
||||
calendar._private.weeks = {
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
"Sun"
|
||||
'Mon',
|
||||
'Tue',
|
||||
'Wed',
|
||||
'Thu',
|
||||
'Fri',
|
||||
'Sat',
|
||||
'Sun',
|
||||
}
|
||||
|
||||
--- A date table to keep track of the needed date
|
||||
calendar.date = {
|
||||
day = tonumber(os.date("%d")) or 1,
|
||||
month = tonumber(os.date("%m")) or 1,
|
||||
year = tonumber(os.date("%Y")) or 1970
|
||||
day = tonumber(os.date('%d')) or 1,
|
||||
month = tonumber(os.date('%m')) or 1,
|
||||
year = tonumber(os.date('%Y')) or 1970,
|
||||
}
|
||||
|
||||
--#region base widget functions
|
||||
@@ -67,7 +65,7 @@ function calendar:layout(_, width, height)
|
||||
end
|
||||
|
||||
function calendar:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
local w, h = 0, 0 ---@type number|nil, number|nil
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
@@ -102,7 +100,7 @@ function calendar:get_last_day_in_month(month, year)
|
||||
[9] = 30,
|
||||
[10] = 31,
|
||||
[11] = 30,
|
||||
[12] = 31
|
||||
[12] = 31,
|
||||
}
|
||||
|
||||
if (month == 2) and (math.floor(year % 4) == 0) then
|
||||
@@ -136,10 +134,10 @@ function calendar:weekday_for_day(day, month, year)
|
||||
end
|
||||
|
||||
-- Forgot what the algorithm was called
|
||||
local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) +
|
||||
tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) +
|
||||
math.floor(tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) / 4) +
|
||||
math.floor(tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) / 4)) % 7)
|
||||
local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) +
|
||||
tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) +
|
||||
math.floor(tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) / 4) +
|
||||
math.floor(tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) / 4)) % 7)
|
||||
|
||||
-- If the week should start on monday, sunday is default. Since the function returns 0 - 6, we have to add 1 for lua's tables
|
||||
if w == 0 then w = 7 end
|
||||
@@ -181,7 +179,7 @@ function calendar:get_tasks()
|
||||
day = start_date.d,
|
||||
hour = start_date.hour or 0,
|
||||
min = start_date.min or 0,
|
||||
sec = start_date.sec or 0
|
||||
sec = start_date.sec or 0,
|
||||
},
|
||||
date_end = {
|
||||
year = end_date.y,
|
||||
@@ -189,7 +187,7 @@ function calendar:get_tasks()
|
||||
day = end_date.d,
|
||||
hour = end_date.hour or 0,
|
||||
min = end_date.min or 0,
|
||||
sec = end_date.sec or 0
|
||||
sec = end_date.sec or 0,
|
||||
},
|
||||
summary = sum,
|
||||
location = loc,
|
||||
@@ -219,12 +217,12 @@ function calendar:get_tasks()
|
||||
day = start_time.day,
|
||||
hour = start_time.hour,
|
||||
min = start_time.min,
|
||||
sec = start_time.sec
|
||||
sec = start_time.sec,
|
||||
}
|
||||
end
|
||||
-- Get repeat cases
|
||||
if event.RRULE then
|
||||
if event.RRULE.FREQ == "DAILY" then
|
||||
if event.RRULE.FREQ == 'DAILY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
@@ -235,14 +233,14 @@ function calendar:get_tasks()
|
||||
d = day_counter,
|
||||
hour = start_time.hour,
|
||||
min = start_time.min,
|
||||
sec = start_time.sec
|
||||
sec = start_time.sec,
|
||||
}, {
|
||||
y = year_counter,
|
||||
m = month_counter,
|
||||
d = day_counter,
|
||||
hour = end_time.hour,
|
||||
min = end_time.min,
|
||||
sec = end_time.sec
|
||||
sec = end_time.sec,
|
||||
}, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
|
||||
day_counter = day_counter + 1
|
||||
@@ -255,14 +253,14 @@ function calendar:get_tasks()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "WEEKLY" then
|
||||
elseif event.RRULE.FREQ == 'WEEKLY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
(day_counter <= event.RRULE.UNTIL.day) do
|
||||
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
day_counter = day_counter + 7
|
||||
local month_length = calendar:get_last_day_in_month(month_counter, year_counter)
|
||||
@@ -275,14 +273,14 @@ function calendar:get_tasks()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "MONTHLY" then
|
||||
elseif event.RRULE.FREQ == 'MONTHLY' then
|
||||
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
|
||||
start_time.day
|
||||
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
|
||||
(day_counter <= event.RRULE.UNTIL.day) do
|
||||
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter,
|
||||
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
month_counter = month_counter + 1
|
||||
if month_counter > 12 then
|
||||
@@ -290,27 +288,27 @@ function calendar:get_tasks()
|
||||
year_counter = year_counter + 1
|
||||
end
|
||||
end
|
||||
elseif event.RRULE.FREQ == "YEARLY" then
|
||||
elseif event.RRULE.FREQ == 'YEARLY' then
|
||||
end_time = event.RRULE.UNTIL
|
||||
if not event.RRULE.UNTIL then
|
||||
end_time = {
|
||||
year = start_time.year + 1000,
|
||||
month = start_time.month,
|
||||
day = start_time.day
|
||||
day = start_time.day,
|
||||
}
|
||||
end
|
||||
for i = start_time.year, end_time.year, 1 do
|
||||
task_factory({ y = i, m = start_time.month, d = start_time.day, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = i, m = end_time.month, d = end_time.day,
|
||||
hour = end_time.hour, min = end_time.min, sec = end_time.sec }, event.SUMMARY,
|
||||
min = start_time.min, sec = start_time.sec, }, { y = i, m = end_time.month, d = end_time.day,
|
||||
hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY,
|
||||
event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
end
|
||||
end
|
||||
-- If RRULE is empty we just add a single day event
|
||||
else
|
||||
task_factory({ y = start_time.year, m = start_time.month, d = start_time.day, hour = start_time.hour,
|
||||
min = start_time.min, sec = start_time.sec }, { y = end_time.year, m = end_time.month,
|
||||
d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
|
||||
min = start_time.min, sec = start_time.sec, }, { y = end_time.year, m = end_time.month,
|
||||
d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec, },
|
||||
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
|
||||
end
|
||||
if event.VALARM then
|
||||
@@ -323,7 +321,7 @@ function calendar:get_tasks()
|
||||
table.insert(self.tasks, tasks)
|
||||
table.insert(self.calendars, {
|
||||
tasks = self.tasks,
|
||||
color = cal.color
|
||||
color = cal.color,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -344,19 +342,19 @@ function calendar:create_calendar_weeks_widget()
|
||||
{
|
||||
{
|
||||
text = i,
|
||||
id = "num",
|
||||
align = "center",
|
||||
valign = "top",
|
||||
id = 'num',
|
||||
align = 'center',
|
||||
valign = 'top',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
height = dpi(120),
|
||||
width = dpi(40),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -369,8 +367,8 @@ function calendar:create_weekdays_widget()
|
||||
self._private.weekdays:add(wibox.widget {
|
||||
{
|
||||
text = self._private.weeks[i],
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
bg = Theme_config.calendar.weekdays.bg,
|
||||
@@ -404,10 +402,10 @@ function calendar:create_calendar_widget()
|
||||
local function get_tasks_for_day(day, month, year)
|
||||
if not self.tasks or #self.tasks == 0 then return end
|
||||
local tasks_layout = {
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(50),
|
||||
spacing = dpi(2)
|
||||
spacing = dpi(2),
|
||||
}
|
||||
|
||||
local function task_factory(task, bg)
|
||||
@@ -415,19 +413,19 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{
|
||||
text = task.summary,
|
||||
align = "left",
|
||||
halign = "center",
|
||||
font = "JetBrainsMono Nerd Font, bold 10",
|
||||
widget = wibox.widget.textbox
|
||||
align = 'left',
|
||||
halign = 'center',
|
||||
font = 'JetBrainsMono Nerd Font, bold 10',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
fg = Theme_config.calendar.task.fg,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.task.shape,
|
||||
forced_height = dpi(20),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -442,7 +440,7 @@ function calendar:create_calendar_widget()
|
||||
(
|
||||
task.date_start.year == self.date.year and task.date_start.month == self.date.month and
|
||||
task.date_start.day < self.date.day) then
|
||||
tw = task_factory(task, cal.color .. "55")
|
||||
tw = task_factory(task, cal.color .. '55')
|
||||
else
|
||||
tw = task_factory(task, cal.color)
|
||||
end
|
||||
@@ -466,10 +464,10 @@ function calendar:create_calendar_widget()
|
||||
widget = ti,
|
||||
ontop = true,
|
||||
visible = false,
|
||||
bg = "#00000000",
|
||||
bg = '#00000000',
|
||||
x = capi.mouse.coords().x,
|
||||
y = capi.mouse.coords().y,
|
||||
screen = self.screen
|
||||
screen = capi.mouse.screen,
|
||||
}
|
||||
|
||||
tw:buttons(
|
||||
@@ -482,11 +480,11 @@ function calendar:create_calendar_widget()
|
||||
)
|
||||
)
|
||||
|
||||
tw:connect_signal("mouse::leave", function()
|
||||
tw:connect_signal('mouse::leave', function()
|
||||
task_popup.visible = false
|
||||
end)
|
||||
|
||||
Hover_signal(tw)
|
||||
hover.bg_hover { widget = tw }
|
||||
|
||||
table.insert(tasks_layout, tw)
|
||||
end
|
||||
@@ -514,8 +512,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg_unfocus
|
||||
local fg = Theme_config.calendar.day.fg_unfocus
|
||||
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
local m = tonumber(os.date('%m'))
|
||||
|
||||
if (i == self.date.day) and (m == last_month) and (y == year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
@@ -531,39 +529,39 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), last_month, year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4),
|
||||
id = "day_tasks",
|
||||
id = 'day_tasks',
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg_unfocus,
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
@@ -571,11 +569,11 @@ function calendar:create_calendar_widget()
|
||||
border_width = Theme_config.calendar.day.border_width,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
},
|
||||
id = "day",
|
||||
id = 'day',
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
self._private.calendar_matrix:add_widget_at(day, 1, column)
|
||||
@@ -592,8 +590,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg
|
||||
local fg = Theme_config.calendar.day.fg
|
||||
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date('%m'))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
if (i == self.date.day) and (m == self.date.month) and (y == self.date.year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
fg = Theme_config.calendar.day.fg_focus
|
||||
@@ -608,37 +606,37 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), self.date.month, self.date.year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg,
|
||||
fg = Theme_config.calendar.day.fg,
|
||||
@@ -649,7 +647,7 @@ function calendar:create_calendar_widget()
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
self._private.calendar_matrix:add_widget_at(day, row, col)
|
||||
@@ -674,8 +672,8 @@ function calendar:create_calendar_widget()
|
||||
local bg = Theme_config.calendar.day.bg_unfocus
|
||||
local fg = Theme_config.calendar.day.fg_unfocus
|
||||
|
||||
local m = tonumber(os.date("%m"))
|
||||
local y = tonumber(os.date("%Y"))
|
||||
local m = tonumber(os.date('%m'))
|
||||
local y = tonumber(os.date('%Y'))
|
||||
if (i == self.date.day) and (m == next_month) and (y == year) then
|
||||
bg = Theme_config.calendar.day.bg_focus
|
||||
fg = Theme_config.calendar.day.fg_focus
|
||||
@@ -689,37 +687,37 @@ function calendar:create_calendar_widget()
|
||||
{
|
||||
{ -- Day
|
||||
widget = wibox.widget.textbox,
|
||||
align = "center",
|
||||
valign = "center",
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = math.floor(i),
|
||||
id = "day_text",
|
||||
id = 'day_text',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(2),
|
||||
},
|
||||
id = "day_bg",
|
||||
id = 'day_bg',
|
||||
widget = wibox.container.background,
|
||||
bg = bg,
|
||||
shape = Theme_config.calendar.day.shape,
|
||||
fg = fg,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
get_tasks_for_day(math.floor(i), next_month, year),
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
id = "tasks",
|
||||
id = 'tasks',
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(4)
|
||||
top = dpi(4),
|
||||
},
|
||||
id = "background",
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.day.bg_unfocus,
|
||||
fg = Theme_config.calendar.day.fg_unfocus,
|
||||
@@ -730,7 +728,7 @@ function calendar:create_calendar_widget()
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(100),
|
||||
height = dpi(120),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
}
|
||||
self._private.calendar_matrix:add_widget_at(day, months_t[self.date.month].weeks,
|
||||
months_t[self.date.month].last_day + i)
|
||||
@@ -754,44 +752,44 @@ function calendar.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "add_ical.svg", Theme_config.calendar.add_ical.fg_focus),
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
image = gcolor.recolor_image(icondir .. 'add_ical.svg', Theme_config.calendar.add_ical.fg_focus),
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
id = "add_ical",
|
||||
id = 'add_ical',
|
||||
shape = Theme_config.calendar.add_ical.shape,
|
||||
bg = Theme_config.calendar.add_ical.bg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
{ -- New task button
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "add_task.svg", Theme_config.calendar.add_task.fg),
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
image = gcolor.recolor_image(icondir .. 'add_task.svg', Theme_config.calendar.add_task.fg),
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
id = "add_task",
|
||||
id = 'add_task',
|
||||
shape = Theme_config.calendar.add_task.shape,
|
||||
bg = Theme_config.calendar.add_task.bg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(4)
|
||||
margins = dpi(4),
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
height = dpi(75)
|
||||
strategy = 'exact',
|
||||
height = dpi(75),
|
||||
},
|
||||
ret._private.calendar_weeks_widget,
|
||||
id = "weekdaysnum",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
id = 'weekdaysnum',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
{
|
||||
{
|
||||
@@ -800,88 +798,88 @@ function calendar.new(args)
|
||||
{ -- Prev arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-left.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "prev_month",
|
||||
image = icondir .. 'chevron-left.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev_month',
|
||||
},
|
||||
{
|
||||
{ -- Month
|
||||
widget = wibox.widget.textbox,
|
||||
text = ret._private.months[ret.date.month],
|
||||
id = "month",
|
||||
valign = "center",
|
||||
align = "center"
|
||||
id = 'month',
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
width = dpi(150)
|
||||
strategy = 'exact',
|
||||
width = dpi(150),
|
||||
},
|
||||
{ -- Next year arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-right.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "next_month",
|
||||
image = icondir .. 'chevron-right.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next_month',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{ -- Year year switcher
|
||||
{ -- Prev arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-left.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "prev_year"
|
||||
image = icondir .. 'chevron-left.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev_year',
|
||||
},
|
||||
{
|
||||
{ -- Year
|
||||
widget = wibox.widget.textbox,
|
||||
text = calendar.date.year,
|
||||
id = "year",
|
||||
valign = "center",
|
||||
align = "center"
|
||||
id = 'year',
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
width = dpi(150)
|
||||
strategy = 'exact',
|
||||
width = dpi(150),
|
||||
},
|
||||
{ -- Next year arrow
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
image = icondir .. "chevron-right.svg",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "next_year"
|
||||
image = icondir .. 'chevron-right.svg',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next_year',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(40),
|
||||
strategy = "exact"
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Weekdays
|
||||
ret._private.weekdays,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
ret._private.calendar_matrix,
|
||||
id = "calendar",
|
||||
id = 'calendar',
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "lay1",
|
||||
id = 'lay1',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.calendar.bg,
|
||||
border_color = Theme_config.calendar.border_color,
|
||||
border_width = Theme_config.calendar.border_width,
|
||||
border_strategy = "inner",
|
||||
border_strategy = 'inner',
|
||||
fg = Theme_config.calendar.fg,
|
||||
shape = Theme_config.calendar.shape,
|
||||
})
|
||||
@@ -893,13 +891,13 @@ function calendar.new(args)
|
||||
ret:create_weekdays_widget()
|
||||
ret:create_calendar_weeks_widget()
|
||||
|
||||
ret:get_widget():get_children_by_id("add_ical")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('add_ical')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"zenity --file-selection --title='Select an ICalendar file' --file-filter='iCalendar File | *.ics'",
|
||||
function(path_to_file)
|
||||
path_to_file = string.gsub(path_to_file, "\n", "")
|
||||
if (not path_to_file) or (path_to_file == "") then return end
|
||||
path_to_file = string.gsub(path_to_file, '\n', '')
|
||||
if (not path_to_file) or (path_to_file == '') then return end
|
||||
ical_parser:add_calendar(path_to_file)
|
||||
ret:get_tasks()
|
||||
ret:create_calendar_widget()
|
||||
@@ -908,7 +906,7 @@ function calendar.new(args)
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("add_task")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('add_task')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"zenity --info --text='Soon TM'",
|
||||
@@ -919,54 +917,57 @@ function calendar.new(args)
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("prev_month")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('prev_month')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.month = ret.date.month - 1
|
||||
if ret.date.month == 0 then
|
||||
ret.date.month = 12
|
||||
ret.date.year = ret.date.year - 1
|
||||
end
|
||||
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
ret:get_widget():get_children_by_id("next_month")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('next_month')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.month = ret.date.month + 1
|
||||
if ret.date.month == 13 then
|
||||
ret.date.month = 1
|
||||
ret.date.year = ret.date.year + 1
|
||||
end
|
||||
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month]
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
--- Calendar switch year back
|
||||
ret:get_widget():get_children_by_id("prev_year")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('prev_year')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.year = ret.date.year - 1
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
--- Calendar switch year forward
|
||||
ret:get_widget():get_children_by_id("next_year")[1]:buttons(gtable.join(
|
||||
ret:get_widget():get_children_by_id('next_year')[1]:buttons(gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
ret.date.year = ret.date.year + 1
|
||||
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
|
||||
ret:get_widget():get_children_by_id('year')[1].text = ret.date.year
|
||||
ret:create_calendar_weeks_widget()
|
||||
ret:create_calendar_widget()
|
||||
end)
|
||||
))
|
||||
|
||||
hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_ical')[1] }
|
||||
hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_task')[1] }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local gobject = require("gears.object")
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gtable = require('gears.table')
|
||||
local gshape = require('gears.shape')
|
||||
local gobject = require('gears.object')
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
}
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/'
|
||||
|
||||
local task_info = { mt = {} }
|
||||
task_info._private = {}
|
||||
@@ -23,124 +21,126 @@ function task_info.new(args)
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, task_info, true)
|
||||
|
||||
args.color = args.color or "#ffffff"
|
||||
args.color = args.color or '#ffffff'
|
||||
|
||||
local date_long_written = os.date("%A, %d. %B %Y", os.time(args.date_start))
|
||||
local date_long_written = os.date('%A, %d. %B %Y', os.time(args.date_start))
|
||||
|
||||
local from_to = os.date('%H:%M', os.time(args.date_start)) .. ' - ' .. os.date('%H:%M', os.time(args.date_end))
|
||||
|
||||
local from_to = os.date("%H:%M", os.time(args.date_start)) .. " - " .. os.date("%H:%M", os.time(args.date_end))
|
||||
|
||||
local task_info_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Task detail
|
||||
{ -- Calendar color
|
||||
widget = wibox.container.background,
|
||||
bg = args.color,
|
||||
forced_width = dpi(10),
|
||||
shape = function(cr, _, height)
|
||||
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
|
||||
end,
|
||||
{ -- Task detail
|
||||
{ -- Calendar color
|
||||
widget = wibox.container.background,
|
||||
bg = args.color,
|
||||
forced_width = dpi(10),
|
||||
shape = function(cr, _, height)
|
||||
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
|
||||
end,
|
||||
},
|
||||
{
|
||||
{ -- Summary
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.summary:sub(1, -2) or 'NO SUMMARY',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'summary',
|
||||
},
|
||||
{ -- Date long
|
||||
widget = wibox.widget.textbox,
|
||||
text = date_long_written or '01.12.1970',
|
||||
valign = 'center',
|
||||
halign = 'right',
|
||||
id = 'date_long',
|
||||
},
|
||||
{ -- From - To
|
||||
widget = wibox.widget.textbox,
|
||||
text = from_to or '',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'from_to',
|
||||
},
|
||||
{ -- Repeat information
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.freq or '0',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'repeat_info',
|
||||
}, -- Year
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.date_start.year or '1970',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'year',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(9),
|
||||
},
|
||||
{
|
||||
{ -- Summary
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.summary:sub(1, -2) or "NO SUMMARY",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "summary",
|
||||
{ -- Location
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'location.svg', args.color),
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{ -- Date long
|
||||
widget = wibox.widget.textbox,
|
||||
text = date_long_written or "01.12.1970",
|
||||
valign = "center",
|
||||
halign = "right",
|
||||
id = "date_long",
|
||||
},
|
||||
{ -- From - To
|
||||
widget = wibox.widget.textbox,
|
||||
text = from_to or "",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "from_to",
|
||||
},
|
||||
{ -- Repeat information
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.freq or "0",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "repeat_info",
|
||||
}, -- Year
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.date_start.year or "1970",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "year",
|
||||
text = args.location:sub(1, -2) or 'F303',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'location',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
id = 'location_container',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
{ -- Alarm
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. 'alarm.svg', args.color),
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.alarm or 'NO ALARM',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'alarm',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = 'alarm_container',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = 'task_detail',
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(9)
|
||||
},
|
||||
{ -- Location
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "location.svg", args.color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.location:sub(1, -2) or "F303",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "location",
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "location_container",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{ -- Alarm
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "alarm.svg", args.color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = args.alarm or "NO ALARM",
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "alarm",
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "alarm_container",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "task_detail",
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
left = dpi(6),
|
||||
right = dpi(15),
|
||||
top = dpi(15),
|
||||
bottom = dpi(15),
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(6),
|
||||
right = dpi(15),
|
||||
top = dpi(15),
|
||||
bottom = dpi(15),
|
||||
},
|
||||
bg = Theme_config.calendar.task_info.bg,
|
||||
fg = Theme_config.calendar.task_info.fg,
|
||||
shape = Theme_config.calendar.task_info.shape,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = task_info_widget }
|
||||
|
||||
ret.widget = task_info_widget
|
||||
|
||||
return ret.widget
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
-- This is the brightness_osd module --
|
||||
---------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local awful = require('awful')
|
||||
local abutton = awful.button
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local base = require("wibox.widget.base")
|
||||
local wibox = require("wibox")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gobject = require("gears.object")
|
||||
local gcolor = require("gears.color")
|
||||
local gtimer = require("gears.timer")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local base = require('wibox.widget.base')
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gcolor = require('gears.color')
|
||||
local gtimer = require('gears.timer')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/'
|
||||
|
||||
local context_menu = {
|
||||
mt = {}
|
||||
mt = {},
|
||||
}
|
||||
|
||||
function context_menu:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return {
|
||||
base.place_widget_at(self._private.widget, 0, 0, width, height)
|
||||
base.place_widget_at(self._private.widget, 0, 0, width, height),
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -45,7 +46,7 @@ context_menu.set_widget = base.set_widget_common
|
||||
function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
local menu_entries = {
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = spacing
|
||||
spacing = spacing,
|
||||
}
|
||||
|
||||
if not wtemplate then
|
||||
@@ -53,8 +54,7 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
end
|
||||
|
||||
for key, entry in pairs(entries) do
|
||||
-- TODO: Figure out how to make a new widget from etemplate
|
||||
local menu_entry = wibox.widget {
|
||||
local menu_entry = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -62,72 +62,74 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "arrow_role"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'arrow_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.desktop.context_menu.entry_bg,
|
||||
fg = Theme_config.desktop.context_menu.entry_fg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
Hover_signal(menu_entry)
|
||||
assert(type(menu_entry) == 'table', 'Entry must be a table')
|
||||
|
||||
menu_entry:get_children_by_id("icon_role")[1].image = entry.icon
|
||||
menu_entry:get_children_by_id("text_role")[1].text = entry.name
|
||||
hover.bg_hover { widget = menu_entry }
|
||||
|
||||
menu_entry:get_children_by_id('icon_role')[1].image = entry.icon
|
||||
menu_entry:get_children_by_id('text_role')[1].text = entry.name
|
||||
if entry.submenu then
|
||||
menu_entry:get_children_by_id("arrow_role")[1].image =
|
||||
gcolor.recolor_image(icondir .. "entry.svg", Theme_config.desktop.context_menu.entry_fg)
|
||||
menu_entry:get_children_by_id('arrow_role')[1].image =
|
||||
gcolor.recolor_image(icondir .. 'entry.svg', Theme_config.desktop.context_menu.entry_fg)
|
||||
end
|
||||
gtable.crush(menu_entry, entry, true)
|
||||
|
||||
menu_entry:buttons(gtable.join {
|
||||
abutton({
|
||||
abutton {
|
||||
modifiers = {},
|
||||
button = 1,
|
||||
on_release = function()
|
||||
if not entry.submenu then
|
||||
entry.callback()
|
||||
end
|
||||
capi.awesome.emit_signal("submenu::close")
|
||||
capi.awesome.emit_signal("cm::hide")
|
||||
end
|
||||
})
|
||||
capi.awesome.emit_signal('submenu::close')
|
||||
capi.awesome.emit_signal('cm::hide')
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
if entry.submenu then
|
||||
@@ -139,7 +141,7 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
border_width = Theme_config.desktop.context_menu.border_width,
|
||||
border_color = Theme_config.desktop.context_menu.border_color,
|
||||
shape = Theme_config.desktop.context_menu.shape,
|
||||
visible = false
|
||||
visible = false,
|
||||
}
|
||||
|
||||
local hide_timer = gtimer {
|
||||
@@ -148,25 +150,25 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
menu_entry.popup.visible = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
menu_entry:connect_signal("mouse::enter", function()
|
||||
menu_entry:connect_signal('mouse::enter', function()
|
||||
-- place widget right of parent
|
||||
menu_entry.popup:move_next_to(capi.mouse.current_widget_geometry)
|
||||
hide_timer:stop()
|
||||
menu_entry.popup.visible = true
|
||||
end)
|
||||
menu_entry.popup:connect_signal("mouse::leave", function()
|
||||
menu_entry.popup:connect_signal('mouse::leave', function()
|
||||
hide_timer:again()
|
||||
end)
|
||||
menu_entry.popup:connect_signal("mouse::enter", function()
|
||||
menu_entry.popup:connect_signal('mouse::enter', function()
|
||||
hide_timer:stop()
|
||||
end)
|
||||
menu_entry:connect_signal("mouse::leave", function()
|
||||
menu_entry:connect_signal('mouse::leave', function()
|
||||
hide_timer:again()
|
||||
end)
|
||||
capi.awesome.connect_signal("submenu::close", function()
|
||||
capi.awesome.connect_signal('submenu::close', function()
|
||||
menu_entry.popup.visible = false
|
||||
end)
|
||||
end
|
||||
@@ -176,8 +178,11 @@ function context_menu:make_entries(wtemplate, entries, spacing)
|
||||
end
|
||||
|
||||
function context_menu:toggle()
|
||||
self.x = capi.mouse.coords().x
|
||||
self.y = capi.mouse.coords().y
|
||||
self.x = capi.mouse.coords().x - dpi(5)
|
||||
self.y = capi.mouse.coords().y - dpi(5)
|
||||
if self.y + self.height > capi.mouse.screen.geometry.height then
|
||||
self.y = self.y - self.height + dpi(10)
|
||||
end
|
||||
self.visible = not self.visible
|
||||
end
|
||||
|
||||
@@ -190,8 +195,10 @@ function context_menu.new(args)
|
||||
|
||||
gtable.crush(ret, context_menu, true)
|
||||
|
||||
local entries = ret:make_entries(args.widget_template, args.entries, args.spacing)
|
||||
|
||||
ret = awful.popup {
|
||||
widget = ret:make_entries(args.widget_template, args.entries, args.spacing),
|
||||
widget = entries,
|
||||
bg = Theme_config.desktop.context_menu.bg,
|
||||
fg = Theme_config.desktop.context_menu.fg,
|
||||
ontop = true,
|
||||
@@ -200,11 +207,11 @@ function context_menu.new(args)
|
||||
shape = Theme_config.desktop.context_menu.shape,
|
||||
visible = false,
|
||||
x = capi.mouse.coords().x + 10,
|
||||
y = capi.mouse.coords().y - 10
|
||||
y = capi.mouse.coords().y - 10,
|
||||
}
|
||||
|
||||
-- I literally have no clue how to do it better, it doesn't really matter anyways
|
||||
capi.awesome.connect_signal("cm::hide", function()
|
||||
capi.awesome.connect_signal('cm::hide', function()
|
||||
ret.visible = false
|
||||
end)
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -17,7 +17,7 @@ return function(s, widgets)
|
||||
local function prepare_widgets(w)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(w) do
|
||||
if i == 1 then
|
||||
@@ -28,7 +28,7 @@ return function(s, widgets)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #w then
|
||||
table.insert(layout,
|
||||
@@ -38,7 +38,7 @@ return function(s, widgets)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -48,28 +48,28 @@ return function(s, widgets)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
return layout
|
||||
end
|
||||
|
||||
local top_center = awful.popup {
|
||||
local top_center = apopup {
|
||||
screen = s,
|
||||
widget = prepare_widgets(widgets),
|
||||
ontop = false,
|
||||
bg = Theme_config.center_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(500),
|
||||
placement = function(c) awful.placement.top(c, { margins = dpi(10) }) end
|
||||
placement = function(c) aplacement.top(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_center:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
capi.client.connect_signal("manage", function(c)
|
||||
capi.client.connect_signal('manage', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -77,7 +77,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal("unmanage", function(c)
|
||||
capi.client.connect_signal('unmanage', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -85,7 +85,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.client.connect_signal("property::selected", function(c)
|
||||
capi.client.connect_signal('property::selected', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
@@ -93,7 +93,7 @@ return function(s, widgets)
|
||||
end
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("refresh", function(c)
|
||||
capi.awesome.connect_signal('refresh', function(c)
|
||||
if #s.selected_tag:clients() < 1 then
|
||||
top_center.visible = false
|
||||
else
|
||||
|
||||
@@ -10,42 +10,42 @@ return function(s)
|
||||
local widget_table = {}
|
||||
if widgets then
|
||||
for _, widget in ipairs(widgets) do
|
||||
if widget == "Audio" then
|
||||
table.insert(widget_table, require("src.widgets.audio")(s))
|
||||
elseif widget == "Battery" then
|
||||
table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind))
|
||||
elseif widget == "Bluetooth" then
|
||||
table.insert(widget_table, require("src.widgets.bluetooth")(s))
|
||||
elseif widget == "Clock" then
|
||||
table.insert(widget_table, require("src.widgets.clock")())
|
||||
elseif widget == "Cpu Frequency" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("freq"))
|
||||
elseif widget == "Cpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("temp"))
|
||||
elseif widget == "Cpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
|
||||
elseif widget == "Date" then
|
||||
table.insert(widget_table, require("src.widgets.date")(s))
|
||||
elseif widget == "Gpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
|
||||
elseif widget == "Gpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("usage"))
|
||||
elseif widget == "Keyboard Layout" then
|
||||
table.insert(widget_table, require("src.widgets.kblayout")(s))
|
||||
elseif widget == "Tiling Layout" then
|
||||
table.insert(widget_table, require("src.widgets.layout_list")())
|
||||
elseif widget == "Network" then
|
||||
table.insert(widget_table, require("src.widgets.network") { screen = s })
|
||||
elseif widget == "Power Button" then
|
||||
table.insert(widget_table, require("src.widgets.power")())
|
||||
elseif widget == "Ram Usage" then
|
||||
table.insert(widget_table, require("src.widgets.ram_info")())
|
||||
elseif widget == "Systray" then
|
||||
table.insert(widget_table, require("src.widgets.systray")(s))
|
||||
elseif widget == "Taglist" then
|
||||
table.insert(widget_table, require("src.widgets.taglist")(s))
|
||||
elseif widget == "Tasklist" then
|
||||
table.insert(widget_table, require("src.widgets.tasklist")(s))
|
||||
if widget == 'Audio' then
|
||||
table.insert(widget_table, require('src.widgets.audio')(s))
|
||||
elseif widget == 'Battery' then
|
||||
table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind))
|
||||
elseif widget == 'Bluetooth' then
|
||||
table.insert(widget_table, require('src.widgets.bluetooth')(s))
|
||||
elseif widget == 'Clock' then
|
||||
table.insert(widget_table, require('src.widgets.clock')())
|
||||
elseif widget == 'Cpu Frequency' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('freq'))
|
||||
elseif widget == 'Cpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('temp'))
|
||||
elseif widget == 'Cpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('usage'))
|
||||
elseif widget == 'Date' then
|
||||
table.insert(widget_table, require('src.widgets.date')(s))
|
||||
elseif widget == 'Gpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('temp'))
|
||||
elseif widget == 'Gpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('usage'))
|
||||
elseif widget == 'Keyboard Layout' then
|
||||
table.insert(widget_table, require('src.widgets.kblayout')(s))
|
||||
elseif widget == 'Tiling Layout' then
|
||||
table.insert(widget_table, require('src.widgets.layout_list')())
|
||||
elseif widget == 'Network' then
|
||||
table.insert(widget_table, require('src.widgets.network') { screen = s })
|
||||
elseif widget == 'Power Button' then
|
||||
table.insert(widget_table, require('src.widgets.power')())
|
||||
elseif widget == 'Ram Usage' then
|
||||
table.insert(widget_table, require('src.widgets.ram_info')())
|
||||
elseif widget == 'Systray' then
|
||||
table.insert(widget_table, require('src.widgets.systray')())
|
||||
elseif widget == 'Taglist' then
|
||||
table.insert(widget_table, require('src.widgets.taglist')(s))
|
||||
elseif widget == 'Tasklist' then
|
||||
table.insert(widget_table, require('src.widgets.tasklist')(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -56,16 +56,16 @@ return function(s)
|
||||
for index, screen in ipairs(User_config.crylia_bar) do
|
||||
if index == s.index then
|
||||
if screen.left_bar then
|
||||
require("src.modules.crylia_bar.left_bar")(s, get_widgets(screen.left_bar))
|
||||
require('src.modules.crylia_bar.left_bar')(s, get_widgets(screen.left_bar))
|
||||
end
|
||||
if screen.center_bar then
|
||||
require("src.modules.crylia_bar.center_bar")(s, get_widgets(screen.center_bar))
|
||||
require('src.modules.crylia_bar.center_bar')(s, get_widgets(screen.center_bar))
|
||||
end
|
||||
if screen.right_bar then
|
||||
require("src.modules.crylia_bar.right_bar")(s, get_widgets(screen.right_bar))
|
||||
require('src.modules.crylia_bar.right_bar')(s, get_widgets(screen.right_bar))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
require("src.modules.crylia_bar.dock")(s)
|
||||
require('src.modules.crylia_bar.dock') { screen = s }
|
||||
end
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
return function(s, w)
|
||||
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -22,7 +21,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -32,7 +31,7 @@ return function(s, w)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -42,7 +41,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -50,17 +49,17 @@ return function(s, w)
|
||||
end
|
||||
|
||||
local top_left = awful.popup {
|
||||
screen = s,
|
||||
widget = prepare_widgets(w),
|
||||
ontop = false,
|
||||
bg = Theme_config.left_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(650),
|
||||
placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end
|
||||
}
|
||||
screen = s,
|
||||
widget = prepare_widgets(w),
|
||||
ontop = false,
|
||||
bg = Theme_config.left_bar.bg,
|
||||
visible = true,
|
||||
maximum_width = dpi(650),
|
||||
placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_left:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.top_struts = dpi(55)
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
|
||||
return function(s, w)
|
||||
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -22,7 +21,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -32,7 +31,7 @@ return function(s, w)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -42,7 +41,7 @@ return function(s, w)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -55,11 +54,11 @@ return function(s, w)
|
||||
bg = Theme_config.right_bar.bg,
|
||||
visible = true,
|
||||
screen = s,
|
||||
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end
|
||||
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end,
|
||||
}
|
||||
|
||||
top_right:struts {
|
||||
top = dpi(55)
|
||||
top = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.top_struts = top_right
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
local wibox = require("wibox")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gshape = require("gears.shape")
|
||||
local wibox = require('wibox')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gshape = require('gears.shape')
|
||||
|
||||
return function(s)
|
||||
---Lookup function to return the widget from its easy name string
|
||||
@@ -13,42 +13,42 @@ return function(s)
|
||||
local widget_table = {}
|
||||
if widgets then
|
||||
for _, widget in ipairs(widgets) do
|
||||
if widget == "Audio" then
|
||||
table.insert(widget_table, require("src.widgets.audio")(s))
|
||||
elseif widget == "Battery" then
|
||||
table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind))
|
||||
elseif widget == "Bluetooth" then
|
||||
table.insert(widget_table, require("src.widgets.bluetooth")())
|
||||
elseif widget == "Clock" then
|
||||
table.insert(widget_table, require("src.widgets.clock")())
|
||||
elseif widget == "Cpu Frequency" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("freq", User_config.cpu_frequency))
|
||||
elseif widget == "Cpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("temp"))
|
||||
elseif widget == "Cpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
|
||||
elseif widget == "Date" then
|
||||
table.insert(widget_table, require("src.widgets.date")())
|
||||
elseif widget == "Gpu Temperature" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
|
||||
elseif widget == "Gpu Usage" then
|
||||
table.insert(widget_table, require("src.widgets.gpu_info")("usage"))
|
||||
elseif widget == "Keyboard Layout" then
|
||||
table.insert(widget_table, require("src.widgets.kblayout")(s))
|
||||
elseif widget == "Tiling Layout" then
|
||||
table.insert(widget_table, require("src.widgets.layout_list")())
|
||||
elseif widget == "Network" then
|
||||
table.insert(widget_table, require("src.widgets.network")())
|
||||
elseif widget == "Power Button" then
|
||||
table.insert(widget_table, require("src.widgets.power")())
|
||||
elseif widget == "Ram Usage" then
|
||||
table.insert(widget_table, require("src.widgets.ram_info")())
|
||||
elseif widget == "Systray" then
|
||||
table.insert(widget_table, require("src.widgets.systray")(s))
|
||||
elseif widget == "Taglist" then
|
||||
table.insert(widget_table, require("src.widgets.taglist")(s))
|
||||
elseif widget == "Tasklist" then
|
||||
table.insert(widget_table, require("src.widgets.tasklist")(s))
|
||||
if widget == 'Audio' then
|
||||
table.insert(widget_table, require('src.widgets.audio')(s))
|
||||
elseif widget == 'Battery' then
|
||||
table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind))
|
||||
elseif widget == 'Bluetooth' then
|
||||
table.insert(widget_table, require('src.widgets.bluetooth')())
|
||||
elseif widget == 'Clock' then
|
||||
table.insert(widget_table, require('src.widgets.clock')())
|
||||
elseif widget == 'Cpu Frequency' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('freq', User_config.cpu_frequency))
|
||||
elseif widget == 'Cpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('temp'))
|
||||
elseif widget == 'Cpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.cpu_info')('usage'))
|
||||
elseif widget == 'Date' then
|
||||
table.insert(widget_table, require('src.widgets.date')())
|
||||
elseif widget == 'Gpu Temperature' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('temp'))
|
||||
elseif widget == 'Gpu Usage' then
|
||||
table.insert(widget_table, require('src.widgets.gpu_info')('usage'))
|
||||
elseif widget == 'Keyboard Layout' then
|
||||
table.insert(widget_table, require('src.widgets.kblayout')(s))
|
||||
elseif widget == 'Tiling Layout' then
|
||||
table.insert(widget_table, require('src.widgets.layout_list')())
|
||||
elseif widget == 'Network' then
|
||||
table.insert(widget_table, require('src.widgets.network')())
|
||||
elseif widget == 'Power Button' then
|
||||
table.insert(widget_table, require('src.widgets.power')())
|
||||
elseif widget == 'Ram Usage' then
|
||||
table.insert(widget_table, require('src.widgets.ram_info')())
|
||||
elseif widget == 'Systray' then
|
||||
table.insert(widget_table, require('src.widgets.systray')())
|
||||
elseif widget == 'Taglist' then
|
||||
table.insert(widget_table, require('src.widgets.taglist')(s))
|
||||
elseif widget == 'Tasklist' then
|
||||
table.insert(widget_table, require('src.widgets.tasklist')(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -61,7 +61,7 @@ return function(s)
|
||||
local function prepare_widgets(widgets)
|
||||
local layout = {
|
||||
forced_height = dpi(50),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
for i, widget in pairs(widgets) do
|
||||
if i == 1 then
|
||||
@@ -72,7 +72,7 @@ return function(s)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
elseif i == #widgets then
|
||||
table.insert(layout,
|
||||
@@ -82,7 +82,7 @@ return function(s)
|
||||
right = dpi(6),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
else
|
||||
table.insert(layout,
|
||||
@@ -92,7 +92,7 @@ return function(s)
|
||||
right = dpi(3),
|
||||
top = dpi(6),
|
||||
bottom = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -109,17 +109,17 @@ return function(s)
|
||||
visible = true,
|
||||
x = 0,
|
||||
y = 1035,
|
||||
type = "desktop",
|
||||
type = 'desktop',
|
||||
height = dpi(55),
|
||||
width = 1920,
|
||||
bg = "#212121",
|
||||
bg = '#212121',
|
||||
shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, 8)
|
||||
end,
|
||||
}
|
||||
|
||||
w:struts {
|
||||
bottom = dpi(55)
|
||||
bottom = dpi(55),
|
||||
}
|
||||
|
||||
Global_config.bottom_struts = dpi(55)
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local awful = require("awful")
|
||||
local gtable = require("gears.table")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gcolor = require("gears.color")
|
||||
local wibox = require("wibox")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gobject = require("gears.object")
|
||||
|
||||
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
|
||||
local context_menu = { mt = {} }
|
||||
context_menu._private = {}
|
||||
|
||||
function context_menu:toggle()
|
||||
self._private.popup.x = mouse.coords().x - 10
|
||||
self._private.popup.y = mouse.coords().y - 10
|
||||
self._private.popup.visible = not self._private.popup.visible
|
||||
end
|
||||
|
||||
function context_menu.new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, context_menu, true)
|
||||
|
||||
capi.awesome.connect_signal("context_menu:show", function()
|
||||
ret:toggle()
|
||||
mousegrabber.run(function()
|
||||
if mouse.current_wibox ~= ret._private.popup then
|
||||
ret:toggle()
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end, nil)
|
||||
end)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function context_menu.mt:__call(...)
|
||||
return context_menu.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(context_menu, context_menu.mt)
|
||||
@@ -1,33 +1,30 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gshape = require("gears.shape")
|
||||
local grid = require("wibox.layout.grid")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require("awful.button")
|
||||
local awful = require("awful")
|
||||
local gcolor = require("gears.color")
|
||||
local json = require("src.lib.json-lua.json-lua")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local Gio = require("lgi").Gio
|
||||
local Gio = require('lgi').Gio
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local grid = require('wibox.layout.grid')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local element = require("src.modules.desktop.element")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
local config = require('src.tools.config')
|
||||
local element = require('src.modules.desktop.element')
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
awesome = awesome,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/desktop/'
|
||||
|
||||
local desktop = { mt = {} }
|
||||
|
||||
function desktop:save_layout()
|
||||
local layout = {}
|
||||
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config/files/desktop/icons/"
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config/files/desktop/icons/'
|
||||
if not gfilesystem.dir_readable(dir) then
|
||||
gfilesystem.make_directories(dir)
|
||||
end
|
||||
@@ -40,54 +37,45 @@ function desktop:save_layout()
|
||||
col = pos.col,
|
||||
widget = {
|
||||
icon = widget.icon,
|
||||
label = widget:get_children_by_id("text_role")[1].text,
|
||||
label = widget.label,
|
||||
exec = widget.exec,
|
||||
icon_size = widget.icon_size
|
||||
}
|
||||
icon_size = widget.icon_size,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json'
|
||||
gfilesystem.make_directories(dir)
|
||||
if not gfilesystem.file_readable(dir .. "/desktop.json") then
|
||||
os.execute("touch " .. dir .. "/desktop.json")
|
||||
end
|
||||
local handler = io.open(dir .. "/desktop.json", "w")
|
||||
if not handler then return end
|
||||
|
||||
handler:write(json:encode(layout))
|
||||
handler:close()
|
||||
config.write_json(dir, layout)
|
||||
end
|
||||
|
||||
function desktop:load_layout()
|
||||
local dir = gfilesystem.get_configuration_dir() .. "src/config"
|
||||
if not gfilesystem.file_readable(dir .. "/desktop.json") then
|
||||
return
|
||||
end
|
||||
local handler = io.open(dir .. "/desktop.json", "r")
|
||||
if not handler then return end
|
||||
local dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json'
|
||||
if not gfilesystem.file_readable(dir) then return end
|
||||
|
||||
local layout = json:decode(handler:read("*all"))
|
||||
handler:close()
|
||||
if not layout then return end
|
||||
for i, value in pairs(layout) do
|
||||
local data = config.read_json(dir)
|
||||
if not data then return end
|
||||
for _, value in pairs(data) do
|
||||
self:add_element(value.widget, { x = value.row, y = value.col })
|
||||
end
|
||||
end
|
||||
|
||||
function desktop:get_element_at(x, y)
|
||||
return self.widget.mrgn.grid:get_widgets_at(x, y)[1]
|
||||
local w = self.widget.mrgn.grid:get_widgets_at(x, y)
|
||||
return w and w[1] or nil
|
||||
end
|
||||
|
||||
function desktop:add_desktop_file(app_info)
|
||||
self:add_element({
|
||||
self:add_element {
|
||||
icon = app_info.icon,
|
||||
label = app_info.label,
|
||||
exec = app_info.exec,
|
||||
icon_size = dpi(96),
|
||||
icon_size = dpi(48),
|
||||
desktop_file = app_info.desktop_file,
|
||||
parent = self.widget.mrgn.grid,
|
||||
})
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
end
|
||||
|
||||
--[[
|
||||
@@ -98,18 +86,17 @@ function desktop:remove_element(e)
|
||||
end
|
||||
|
||||
function desktop:get_grid_index_at(y, x)
|
||||
local col, row = 1, 1
|
||||
local margin_x, margin_y = dpi(10), dpi(10)
|
||||
local screen_width, screen_height = self.args.screen.geometry.width - margin_x * 2, self.args.screen.geometry.height - dpi(75) - dpi(95) - margin_y * 2
|
||||
local cell_width, cell_height = screen_width / 20, screen_height / 11
|
||||
|
||||
local width = dpi(96) * 1.75 * (4 / 3)
|
||||
local height = dpi(96) * 1.75
|
||||
local spacing = dpi(10)
|
||||
local col = math.floor((x - margin_x) / cell_width) + 1
|
||||
col = math.min(col, 20)
|
||||
col = math.max(col, 1)
|
||||
|
||||
while width * col + spacing * (col - 1) < x do
|
||||
col = col + 1
|
||||
end
|
||||
while height * row + spacing * (row - 1) < y do
|
||||
row = row + 1
|
||||
end
|
||||
local row = math.floor((y - margin_y) / cell_height) + 1
|
||||
row = math.min(row, 11)
|
||||
row = math.max(row, 1)
|
||||
|
||||
return col, row
|
||||
end
|
||||
@@ -133,7 +120,9 @@ function desktop:add_element(args, pos)
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
desktop_file = args.desktop_file,
|
||||
parent = args.parent
|
||||
parent = args.parent,
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
|
||||
local cm_popup = cm {
|
||||
@@ -144,106 +133,98 @@ function desktop:add_element(args, pos)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Open with",
|
||||
icon = gcolor.recolor_image(icondir .. "launch.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Open with',
|
||||
icon = gcolor.recolor_image(icondir .. 'launch.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
--!TODO: Fetch programs and add them as entries
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "Copy",
|
||||
icon = gcolor.recolor_image(icondir .. "copy.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Copy',
|
||||
icon = gcolor.recolor_image(icondir .. 'copy.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Cut",
|
||||
icon = gcolor.recolor_image(icondir .. "cut.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Cut',
|
||||
icon = gcolor.recolor_image(icondir .. 'cut.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Rename",
|
||||
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Rename',
|
||||
icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Remove",
|
||||
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Remove',
|
||||
icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
self:remove_element(e)
|
||||
self:save_layout()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Actions",
|
||||
icon = gcolor.recolor_image(icondir .. "dots-vertical.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Actions',
|
||||
icon = gcolor.recolor_image(icondir .. 'dots-vertical.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
-- TODO: fetch actions from desktop file
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cm_popup:connect_signal("mouse::leave", function()
|
||||
cm_popup:connect_signal('mouse::leave', function()
|
||||
cm_popup.visible = false
|
||||
end)
|
||||
|
||||
local cols = math.floor(self.args.screen.geometry.width / (args.icon_size * 1.75 * (4 / 3)))
|
||||
local rows = math.floor((self.args.screen.geometry.height - 75 + 95) / (args.icon_size * 1.75))
|
||||
print(cols, rows)
|
||||
-- While the mouse is down, remove the element from the grid and add it to manual then move it
|
||||
-- until the mouse is released and then add it back to the grid.
|
||||
e:connect_signal("button::press", function(_, _, _, b)
|
||||
local start_pos = mouse.coords()
|
||||
|
||||
e:connect_signal('button::press', function(_, _, _, b)
|
||||
if not mousegrabber.isrunning() then
|
||||
|
||||
local width = (self.args.screen.geometry.width - 20 - ((cols - 1) * 10)) / cols
|
||||
local height = (self.args.screen.geometry.height - 170 - 20) / rows
|
||||
|
||||
local dnd_widget = element {
|
||||
icon = args.icon,
|
||||
label = args.label,
|
||||
on_click = args.on_click,
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
desktop_file = args.desktop_file,
|
||||
parent = args.parent,
|
||||
width = width,
|
||||
height = height,
|
||||
width = self.widget_width,
|
||||
height = self.widget_height,
|
||||
}
|
||||
dnd_widget.visible = false
|
||||
|
||||
dnd_widget:get_children_by_id("icon_role")[1].opacity = 0.6
|
||||
|
||||
local xp, yp = capi.mouse.coords()
|
||||
dnd_widget.point = { x = xp, y = yp }
|
||||
dnd_widget:get_children_by_id('icon_role')[1].opacity = 0.6
|
||||
|
||||
local start_pos = capi.mouse.coords()
|
||||
dnd_widget.point = { x = math.floor(start_pos.x - self.args.screen.geometry.x), y = math.floor(start_pos.y - self.args.screen.geometry.y) }
|
||||
local old_pos = self.widget.mrgn.grid:get_widget_position(e)
|
||||
self.widget.manual:add(dnd_widget)
|
||||
mousegrabber.run(function(m)
|
||||
@@ -254,22 +235,29 @@ function desktop:add_element(args, pos)
|
||||
m.buttons[1] then
|
||||
self:remove_element(e)
|
||||
dnd_widget.visible = true
|
||||
dnd_widget.bg = gcolor("#0ffff088")
|
||||
dnd_widget.border_color = gcolor("#0ffff0")
|
||||
self.widget.manual:move_widget(dnd_widget, { x = m.x - dnd_widget.width / 2, y = m.y - dnd_widget.height / 2 })
|
||||
dnd_widget.bg = gcolor('#0ffff088')
|
||||
dnd_widget.border_color = gcolor('#0ffff0')
|
||||
|
||||
self.widget.manual:move_widget(dnd_widget, {
|
||||
x = (m.x - dnd_widget.width / 2) - self.args.screen.geometry.x,
|
||||
y = (m.y - dnd_widget.height / 2) - self.args.screen.geometry.y,
|
||||
})
|
||||
end
|
||||
|
||||
if not m.buttons[1] then
|
||||
if b == 1 then
|
||||
dnd_widget.bg = gcolor("#0ffff088")
|
||||
dnd_widget.border_color = gcolor("#0ffff0")
|
||||
dnd_widget.bg = gcolor('#0ffff088')
|
||||
dnd_widget.border_color = gcolor('#0ffff0')
|
||||
|
||||
if dnd_widget.visible then
|
||||
dnd_widget.visible = false
|
||||
|
||||
local np_x, np_y = self:get_grid_index_at(m.y, m.x)
|
||||
if not self.widget.mrgn.grid:get_widgets_at(np_y, np_x) then
|
||||
self.widget.mrgn.grid:add_widget_at(e, np_y, np_x)
|
||||
local newp_x, newp_y = self:get_grid_index_at(
|
||||
(m.y - dnd_widget.height / 2) - self.args.screen.geometry.y,
|
||||
(m.x - dnd_widget.width / 2) - self.args.screen.geometry.x
|
||||
)
|
||||
if not self.widget.mrgn.grid:get_widgets_at(newp_y, newp_x) then
|
||||
self.widget.mrgn.grid:add_widget_at(e, newp_y, newp_x)
|
||||
self:save_layout()
|
||||
else
|
||||
self.widget.mrgn.grid:add_widget_at(e, old_pos.row, old_pos.col)
|
||||
@@ -286,7 +274,7 @@ function desktop:add_element(args, pos)
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, "left_ptr")
|
||||
end, 'left_ptr')
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -299,62 +287,83 @@ function desktop:draw_selector()
|
||||
if not mousegrabber.isrunning() then
|
||||
local selector = wibox.widget {
|
||||
widget = wibox.container.background,
|
||||
bg = gcolor("#0ffff088"),
|
||||
border_color = gcolor("#0ffff0"),
|
||||
bg = gcolor('#0ffff088'),
|
||||
border_color = gcolor('#0ffff0'),
|
||||
border_width = dpi(2),
|
||||
forced_width = 0,
|
||||
forced_height = 0,
|
||||
x = start_pos.x,
|
||||
y = start_pos.y,
|
||||
x = start_pos.x - self.args.screen.geometry.x,
|
||||
y = start_pos.y - self.args.screen.geometry.y,
|
||||
visible = true,
|
||||
shape = function(cr, w, h)
|
||||
gshape.rounded_rect(cr, w, h, dpi(10))
|
||||
end
|
||||
end,
|
||||
}
|
||||
selector.point = { x = start_pos.x, y = start_pos.y }
|
||||
selector.point = { x = start_pos.x - self.args.screen.geometry.x, y = start_pos.y - self.args.screen.geometry.y }
|
||||
self.widget.manual:add(selector)
|
||||
mousegrabber.run(function(m)
|
||||
if m.buttons[1] then
|
||||
selector.visible = true
|
||||
end
|
||||
if not m.buttons[1] then
|
||||
print("stop")
|
||||
mousegrabber.stop()
|
||||
selector.visible = false
|
||||
self.widget.manual:reset()
|
||||
end
|
||||
selector.forced_width = selector.forced_width + ((start_pos.x - m.x) * -1)
|
||||
selector.forced_height = selector.forced_width + ((start_pos.y - m.y) * -1)
|
||||
|
||||
print(selector.forced_width, selector.forced_height)
|
||||
local dx = m.x - start_pos.x
|
||||
local dy = m.y - start_pos.y
|
||||
local gx, gy = self:get_grid_index_at(math.abs(dy), math.abs(dx))
|
||||
selector.forced_width = math.abs(dx)
|
||||
selector.forced_height = math.abs(dy)
|
||||
--if the mouse is moving to the left, move the widget to the left
|
||||
if dx < 0 then
|
||||
selector.x = start_pos.x - self.args.screen.geometry.x + dx
|
||||
selector.point.x = start_pos.x - self.args.screen.geometry.x + dx
|
||||
gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x)
|
||||
end
|
||||
--if the mouse is moving up, move the widget up
|
||||
if dy < 0 then
|
||||
selector.y = start_pos.y - self.args.screen.geometry.y + dy
|
||||
selector.point.y = start_pos.y - self.args.screen.geometry.y + dy
|
||||
gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x)
|
||||
end
|
||||
-- check if a widget is inside the selector
|
||||
local w = self:get_element_at(gx, gy)
|
||||
if w then
|
||||
w.bg = gcolor('#0ffff088')
|
||||
w.border_color = gcolor('#0ffff0')
|
||||
end
|
||||
return m.buttons[1]
|
||||
end, "left_ptr")
|
||||
end, 'left_ptr')
|
||||
end
|
||||
end
|
||||
|
||||
function desktop:add_xdg()
|
||||
self:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg",
|
||||
label = "Papierkorb",
|
||||
exec = "nautilus trash:/",
|
||||
icon_size = 96,
|
||||
})
|
||||
self:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg',
|
||||
label = 'Papierkorb',
|
||||
exec = 'nautilus trash:/',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
|
||||
self:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg",
|
||||
label = "Persönlicher Ordner",
|
||||
exec = "nautilus file:/home/crylia",
|
||||
icon_size = 96,
|
||||
})
|
||||
self:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg',
|
||||
label = 'Persönlicher Ordner',
|
||||
exec = 'nautilus file:/home/crylia',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end
|
||||
|
||||
function desktop.new(args)
|
||||
args = args or {}
|
||||
|
||||
local icon_size = args.icon_size or dpi(96)
|
||||
args.icon_size = dpi(48)
|
||||
|
||||
local rows = 20
|
||||
local cols = 11
|
||||
local h_spacing = dpi(10)
|
||||
local v_spacing = dpi(20)
|
||||
|
||||
local cols = math.floor(args.screen.geometry.width / (icon_size * 1.75 * (4 / 3)))
|
||||
local rows = math.floor((args.screen.geometry.height - 75 + 95) / (icon_size * 1.75))
|
||||
--[[
|
||||
The wibox has a stacked layout with a manual layout over a grid.
|
||||
|
||||
@@ -368,10 +377,10 @@ function desktop.new(args)
|
||||
local w = wibox {
|
||||
ontop = false,
|
||||
visible = true,
|
||||
type = "desktop",
|
||||
type = 'desktop',
|
||||
input_passthrough = false,
|
||||
x = 0,
|
||||
y = 0,
|
||||
x = args.screen.geometry.x,
|
||||
y = args.screen.geometry.y,
|
||||
bg = gcolor.transparent,
|
||||
width = args.screen.geometry.width,
|
||||
height = args.screen.geometry.height,
|
||||
@@ -381,26 +390,27 @@ function desktop.new(args)
|
||||
{
|
||||
layout = grid,
|
||||
homogeneous = true,
|
||||
spacing = 10,
|
||||
expand = true,
|
||||
orientation = "horizontal",
|
||||
forced_num_cols = cols,
|
||||
forced_num_rows = rows,
|
||||
id = "grid",
|
||||
horizontal_spacing = h_spacing,
|
||||
vertical_spacing = v_spacing,
|
||||
expand = false,
|
||||
orientation = 'horizontal',
|
||||
forced_num_cols = rows,
|
||||
forced_num_rows = cols,
|
||||
id = 'grid',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = dpi(10),
|
||||
right = dpi(10),
|
||||
top = dpi(75),
|
||||
bottom = dpi(95),
|
||||
id = "mrgn"
|
||||
id = 'mrgn',
|
||||
},
|
||||
{
|
||||
layout = wibox.layout.manual,
|
||||
id = "manual",
|
||||
id = 'manual',
|
||||
},
|
||||
layout = wibox.layout.stack,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
w.args = args
|
||||
@@ -413,158 +423,158 @@ function desktop.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = "Create new",
|
||||
icon = gcolor.recolor_image(icondir .. "file_add.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Create new',
|
||||
icon = gcolor.recolor_image(icondir .. 'file_add.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
submenu = {
|
||||
{
|
||||
name = "Folder",
|
||||
icon = gcolor.recolor_image(icondir .. "folder.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Folder',
|
||||
icon = gcolor.recolor_image(icondir .. 'folder.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
--create a new folder and if it exists add a number to the end
|
||||
local folder_name = "New folder"
|
||||
local folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
|
||||
local folder_name = 'New folder'
|
||||
local folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name
|
||||
local i = 1
|
||||
while gfilesystem.dir_readable(folder_path) do
|
||||
folder_name = "New folder " .. "(" .. i .. ")"
|
||||
folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
|
||||
folder_name = 'New folder ' .. '(' .. i .. ')'
|
||||
folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name
|
||||
i = i + 1
|
||||
end
|
||||
gfilesystem.make_directories(folder_path)
|
||||
w:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/24x24/places/folder.svg",
|
||||
w:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/24x24/places/folder.svg',
|
||||
label = folder_name,
|
||||
exec = "nautilus file:\"" .. folder_path .. "\"",
|
||||
icon_size = icon_size,
|
||||
})
|
||||
end
|
||||
exec = 'nautilus file:\"' .. folder_path .. '\"',
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "File",
|
||||
icon = gcolor.recolor_image(icondir .. "file.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'File',
|
||||
icon = gcolor.recolor_image(icondir .. 'file.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
--create new text file and if it exists add a number to the end
|
||||
local file_name = "New file.txt"
|
||||
local file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
|
||||
local file_name = 'New file.txt'
|
||||
local file_path = os.getenv('HOME') .. '/Desktop/' .. file_name
|
||||
local i = 1
|
||||
while gfilesystem.file_readable(file_path) do
|
||||
file_name = "New file " .. "(" .. i .. ")"
|
||||
file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
|
||||
file_name = 'New file ' .. '(' .. i .. ')'
|
||||
file_path = os.getenv('HOME') .. '/Desktop/' .. file_name
|
||||
i = i + 1
|
||||
end
|
||||
awful.spawn.with_shell("touch " .. file_path)
|
||||
w:add_element({
|
||||
icon = "/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg",
|
||||
awful.spawn.with_shell('touch ' .. file_path)
|
||||
w:add_element {
|
||||
icon = '/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg',
|
||||
label = file_name,
|
||||
exec = "xdg-open " .. file_path,
|
||||
icon_size = icon_size,
|
||||
})
|
||||
end
|
||||
}
|
||||
}
|
||||
exec = 'xdg-open ' .. file_path,
|
||||
icon_size = dpi(48),
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "Terminal",
|
||||
icon = gcolor.recolor_image(icondir .. "terminal.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Terminal',
|
||||
icon = gcolor.recolor_image(icondir .. 'terminal.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.terminal)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Web Browser",
|
||||
icon = gcolor.recolor_image(icondir .. "web_browser.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Web Browser',
|
||||
icon = gcolor.recolor_image(icondir .. 'web_browser.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.web_browser)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "File Manager",
|
||||
icon = gcolor.recolor_image(icondir .. "file_manager.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'File Manager',
|
||||
icon = gcolor.recolor_image(icondir .. 'file_manager.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.file_manager)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Text Editor",
|
||||
icon = gcolor.recolor_image(icondir .. "text_editor.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Text Editor',
|
||||
icon = gcolor.recolor_image(icondir .. 'text_editor.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.text_editor)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Music Player",
|
||||
icon = gcolor.recolor_image(icondir .. "music_player.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Music Player',
|
||||
icon = gcolor.recolor_image(icondir .. 'music_player.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.music_player)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Applications",
|
||||
icon = gcolor.recolor_image(icondir .. "application.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Applications',
|
||||
icon = gcolor.recolor_image(icondir .. 'application.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "GTK Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "gtk_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'GTK Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'gtk_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.gtk_settings)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Energy Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "energy_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Energy Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'energy_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.energy_manager)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Screen Settings",
|
||||
icon = gcolor.recolor_image(icondir .. "screen_settings.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Screen Settings',
|
||||
icon = gcolor.recolor_image(icondir .. 'screen_settings.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
awful.spawn(User_config.screen_settings)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Reload Awesome",
|
||||
icon = gcolor.recolor_image(icondir .. "refresh.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Reload Awesome',
|
||||
icon = gcolor.recolor_image(icondir .. 'refresh.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
capi.awesome.restart()
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "Quit",
|
||||
icon = gcolor.recolor_image(icondir .. "quit.svg", Theme_config.desktop.context_menu.icon_color),
|
||||
name = 'Quit',
|
||||
icon = gcolor.recolor_image(icondir .. 'quit.svg', Theme_config.desktop.context_menu.icon_color),
|
||||
callback = function()
|
||||
capi.awesome.quit()
|
||||
end
|
||||
end,
|
||||
},
|
||||
--cm_awesome
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
w.widget.manual:buttons(gtable.join(
|
||||
@@ -583,9 +593,12 @@ function desktop.new(args)
|
||||
|
||||
gtable.crush(w, desktop, true)
|
||||
|
||||
w.widget_width = (args.screen.geometry.width - 20 - ((h_spacing - 1) * rows)) / rows
|
||||
w.widget_height = (args.screen.geometry.height - 170 - ((v_spacing - 1) * cols)) / cols
|
||||
|
||||
w:load_layout()
|
||||
|
||||
capi.awesome.connect_signal("desktop::add_to_desktop", function(args2)
|
||||
capi.awesome.connect_signal('desktop::add_to_desktop', function(args2)
|
||||
w:add_desktop_file(args2)
|
||||
end)
|
||||
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
local base = require("wibox.widget.base")
|
||||
local wibox = require("wibox")
|
||||
local gtable = require("gears.table")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gshape = require("gears.shape")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gcolor = require("gears.color")
|
||||
local abutton = require("awful.button")
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
|
||||
|
||||
local capi = {
|
||||
mouse = mouse
|
||||
}
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local lgi = require('lgi')
|
||||
local cairo = lgi.cairo
|
||||
local wibox = require('wibox')
|
||||
|
||||
local element = { mt = {} }
|
||||
|
||||
@@ -34,30 +28,174 @@ function element:get_widget()
|
||||
end
|
||||
|
||||
function element:on_hover()
|
||||
self:connect_signal("mouse::enter", function()
|
||||
self.bg = "#0ffff033"
|
||||
self.border_color = "#0ffff099"
|
||||
self:connect_signal('mouse::enter', function()
|
||||
self.bg = '#0ffff033'
|
||||
self.border_color = '#0ffff099'
|
||||
end)
|
||||
|
||||
--[[ self:connect_signal("mouse::leave", function()
|
||||
self:connect_signal('mouse::leave', function()
|
||||
self.bg = gcolor.transparent
|
||||
self.border_color = gcolor.transparent
|
||||
end) ]]
|
||||
|
||||
self:connect_signal("button::press", function()
|
||||
self.bg = "#0ffff088"
|
||||
self.border_color = "#0ffff0dd"
|
||||
end)
|
||||
|
||||
self:connect_signal("button::release", function()
|
||||
self.bg = "#0ffff033"
|
||||
self.border_color = "#0ffff099"
|
||||
self:connect_signal('button::press', function()
|
||||
self.bg = '#0ffff088'
|
||||
self.border_color = '#0ffff0dd'
|
||||
end)
|
||||
|
||||
self:connect_signal('button::release', function()
|
||||
self.bg = '#0ffff033'
|
||||
self.border_color = '#0ffff099'
|
||||
end)
|
||||
end
|
||||
|
||||
---Get the cairo extents for any text with its give size and font
|
||||
---@param font string A font
|
||||
---@param font_size number Font size
|
||||
---@param text string Text to get the extent for
|
||||
---@param args table Additional arguments
|
||||
---@return userdata cairo.Extent
|
||||
local function cairo_text_extents(font, font_size, text, args)
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
cr:set_antialias(cairo.Antialias.BEST)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
local function split_string(str, max_width)
|
||||
local line1 = ''
|
||||
local line2 = ''
|
||||
local line1_width = 0
|
||||
local line2_width = 0
|
||||
local font = 'JetBrainsMono Nerd Font'
|
||||
local font_size = dpi(16)
|
||||
local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD }
|
||||
|
||||
for word in str:gmatch('%S+') do
|
||||
local word_width = cairo_text_extents(font, font_size, word, font_args).width
|
||||
if line1_width + word_width < max_width then
|
||||
line1 = line1 .. word .. ' '
|
||||
line1_width = line1_width + word_width
|
||||
else
|
||||
line2 = line2 .. word .. ' '
|
||||
line2_width = line2_width + word_width
|
||||
end
|
||||
end
|
||||
|
||||
return line1, line2
|
||||
end
|
||||
|
||||
---This function takes any text and uses cairo to draw an outline and a shadow
|
||||
---It also wraps the text correctly if max_width would be violated. It only uses two lines for wraping
|
||||
---the rest is cut off.
|
||||
---@param text string Text to be changed
|
||||
---@param max_width number max width the text won't go over
|
||||
---@return cairo.Surface cairo_surface manupulated text as a cairo surface
|
||||
---@return table `width`,`height` The surface dimensions
|
||||
local function outlined_text(text, max_width)
|
||||
local font = 'JetBrainsMono Nerd Font'
|
||||
local font_size = dpi(16)
|
||||
local spacing = dpi(5)
|
||||
local margin = dpi(5)
|
||||
max_width = max_width - (margin * 2)
|
||||
local shadow_offset_x, shadow_offset_y = 1, 1
|
||||
local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD }
|
||||
|
||||
-- Get the dimensions from the text
|
||||
local extents = cairo_text_extents(font, font_size, text, font_args)
|
||||
|
||||
-- if its bigger it needs special treatment
|
||||
if extents.width > max_width then
|
||||
|
||||
local line1, line2 = split_string(text, max_width)
|
||||
|
||||
-- Get the dimensions for both lines
|
||||
local extents1 = cairo_text_extents(font, font_size, line1, font_args)
|
||||
local extents2 = cairo_text_extents(font, font_size, line2, font_args)
|
||||
|
||||
-- The surface width will be the biggest of the two lines
|
||||
local s_width = extents1.width
|
||||
if extents1.width < extents2.width then
|
||||
s_width = extents2.width
|
||||
end
|
||||
|
||||
-- Create a new surface based on the widest line, and both line's height + the spacing between them and the shadow offset
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, s_width + shadow_offset_x, extents1.height + extents2.height + spacing + (shadow_offset_y * 3))
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Create the font with best antialias
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
cr:set_antialias(cairo.Antialias.BEST)
|
||||
|
||||
-- To center both lines get the surface center then substract half the line width
|
||||
local text_x = s_width / 2 - ((extents1.width) / 2)
|
||||
local text_x2 = s_width / 2 - ((extents2.width) / 2)
|
||||
|
||||
-- This makes the first text to be blow the main text
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the text shadow
|
||||
cr:move_to(text_x + shadow_offset_x, -extents1.y_bearing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(line1)
|
||||
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the second shadow
|
||||
cr:move_to(text_x2 + shadow_offset_x, extents1.height + extents2.height + spacing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(line2)
|
||||
|
||||
-- Draw the first and second line
|
||||
cr:move_to(text_x, -extents1.y_bearing)
|
||||
cr:set_source_rgb(1, 1, 1)
|
||||
cr:text_path(line1)
|
||||
cr:move_to(text_x2, extents1.height + extents2.height + spacing)
|
||||
cr:text_path(line2)
|
||||
|
||||
-- Color it and set the stroke
|
||||
cr:fill_preserve()
|
||||
cr:set_source_rgb(0, 0, 0)
|
||||
cr:set_line_width(0.1)
|
||||
cr:stroke()
|
||||
|
||||
return surface, { width = extents.width, height = extents1.height + extents2.height + spacing }
|
||||
else
|
||||
-- The size is the dimension from above the if
|
||||
local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, extents.width, extents.height + shadow_offset_y)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Set the font, then draw the text and its stroke
|
||||
cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||
cr:set_font_size(font_size)
|
||||
|
||||
-- This makes the first text to be blow the main text
|
||||
cr:set_operator(cairo.Operator.OVER)
|
||||
|
||||
-- Draw the text shadow
|
||||
cr:move_to(-extents.x_bearing + shadow_offset_x, -extents.y_bearing + shadow_offset_y)
|
||||
cr:set_source_rgba(0, 0, 0, 0.5)
|
||||
cr:show_text(text)
|
||||
|
||||
cr:move_to(-extents.x_bearing, -extents.y_bearing)
|
||||
cr:set_source_rgb(1, 1, 1)
|
||||
cr:text_path(text)
|
||||
cr:fill_preserve()
|
||||
cr:set_source_rgb(0, 0, 0)
|
||||
cr:set_line_width(0.1)
|
||||
cr:stroke()
|
||||
return surface, { width = extents.width, height = extents.height }
|
||||
end
|
||||
end
|
||||
|
||||
function element.new(args)
|
||||
args = args or {}
|
||||
|
||||
local text_img, size = outlined_text(args.label, args.width)
|
||||
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
@@ -66,31 +204,34 @@ function element.new(args)
|
||||
image = args.icon,
|
||||
resize = true,
|
||||
clip_shape = gshape.rounded_rect,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
widget = wibox.widget.imagebox
|
||||
valign = 'top',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
forced_width = args.icon_size,
|
||||
forced_height = args.icon_size,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
height = args.icon_size,
|
||||
width = args.icon_size,
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(5),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(5),
|
||||
},
|
||||
{
|
||||
text = args.label,
|
||||
id = "text_role",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
image = text_img,
|
||||
resize = false,
|
||||
valign = 'bottom',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.align.vertical,
|
||||
},
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
},
|
||||
fg = "#ffffff",
|
||||
fg = '#ffffff',
|
||||
bg = gcolor.transparent,
|
||||
border_color = gcolor.transparent,
|
||||
border_width = dpi(2),
|
||||
@@ -102,9 +243,12 @@ function element.new(args)
|
||||
exec = args.exec,
|
||||
icon_size = args.icon_size,
|
||||
icon = args.icon,
|
||||
widget = wibox.container.background
|
||||
label = args.label,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(w, 'No widget returned')
|
||||
|
||||
gtable.crush(w, element, true)
|
||||
|
||||
w:on_hover()
|
||||
|
||||
@@ -2,27 +2,45 @@
|
||||
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local awful = require('awful')
|
||||
|
||||
awful.screen.connect_for_each_screen(function(s)
|
||||
-- Create 9 tags
|
||||
awful.layout.append_default_layouts(User_config.layouts)
|
||||
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, User_config.layouts[1])
|
||||
awful.tag({ '1', '2', '3', '4', '5', '6', '7', '8', '9' }, s, User_config.layouts[1])
|
||||
|
||||
require("src.modules.desktop.desktop") { screen = s }
|
||||
require("src.modules.powermenu.powermenu")(s)
|
||||
require("src.modules.audio.volume_osd") { screen = s }
|
||||
--require("src.modules.audio.volume_controller") { screen = s }
|
||||
require("src.modules.brightness.brightness_osd") { screen = s }
|
||||
require("src.modules.crylia_bar.init")(s)
|
||||
--require("src.modules.crylia_wibox.init")(s)
|
||||
require("src.modules.notification-center.init")(s)
|
||||
require("src.modules.window_switcher.init")(s)
|
||||
require("src.modules.application_launcher.init") { screen = s }
|
||||
--require("src.modules.network_controller.init") { screen = s }
|
||||
require('src.modules.desktop.desktop') { screen = s }
|
||||
require('src.modules.crylia_bar.init')(s)
|
||||
--require('src.modules.crylia_wibox.init')(s)
|
||||
require('src.modules.notification-center.init') { screen = s }
|
||||
--require('src.modules.window_switcher.init')(s)
|
||||
require('src.modules.application_launcher.init') { screen = s }
|
||||
end)
|
||||
|
||||
do
|
||||
require("src.lib.nice") { titlebar_font = User_config.font.bold,
|
||||
titlebar_items = { left = { "icon" }, right = { "minimize", "maximize", "close" } } }
|
||||
end
|
||||
local ip = require('src.modules.inputbox.new') {
|
||||
text = 'inputboxtest',
|
||||
cursor_pos = 4,
|
||||
highlight = {
|
||||
start_pos = 1,
|
||||
end_pos = 4,
|
||||
},
|
||||
text_hint = 'Input Some Text',
|
||||
}
|
||||
|
||||
awful.popup {
|
||||
widget = ip.widget,
|
||||
bg = '#212121',
|
||||
visible = true,
|
||||
screen = 1,
|
||||
placement = awful.placement.centered,
|
||||
}
|
||||
|
||||
--[[ require('src.modules.inputbox.init') {
|
||||
text = 'inputboxtest',
|
||||
cursor_pos = 4,
|
||||
highlight = {
|
||||
start_pos = 5,
|
||||
end_pos = 8,
|
||||
},
|
||||
}
|
||||
]]
|
||||
|
||||
796
awesome/src/modules/inputbox/init.lua
Normal file
@@ -0,0 +1,796 @@
|
||||
---------------------------------------------------------------------------
|
||||
-- This widget can be used to type text and get the text from it.
|
||||
--@DOC_wibox_widget_defaults_inputbox_EXAMPLE@
|
||||
--
|
||||
-- @author Rene Kievits
|
||||
-- @copyright 2022, Rene Kievits
|
||||
-- @module awful.widget.inputbox
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local beautiful = require('beautiful')
|
||||
local gtable = require('gears.table')
|
||||
local base = require('wibox.widget.base')
|
||||
local gstring = require('gears.string')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local akey = require('awful.key')
|
||||
local textbox = require('wibox.widget.textbox')
|
||||
local imagebox = require('wibox.widget.imagebox')
|
||||
local cairo = require('lgi').cairo
|
||||
local apopup = require('awful.popup')
|
||||
local aplacement = require('awful.placement')
|
||||
local gsurface = require('gears.surface')
|
||||
local wibox = require('wibox')
|
||||
local abutton = require('awful.button')
|
||||
|
||||
local capi = {
|
||||
selection = selection,
|
||||
mousegrabber = mousegrabber,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local inputbox = { mt = {} }
|
||||
|
||||
--- Formats the text with a cursor and highlights if set.
|
||||
--[[ local function text_with_cursor(text, cursor_pos, self)
|
||||
local char, spacer, text_start, text_end
|
||||
|
||||
local cursor_fg = beautiful.inputbox_cursor_fg or '#313131'
|
||||
local cursor_bg = beautiful.inputbox_cursor_bg or '#0dccfc'
|
||||
local placeholder_text = self.hint_text or ''
|
||||
local placeholder_fg = beautiful.inputbox_placeholder_fg or '#777777'
|
||||
local highlight_bg = beautiful.inputbox_highlight_bg or '#35ffe4'
|
||||
local highlight_fg = beautiful.inputbox_highlight_fg or '#000000'
|
||||
|
||||
if text == '' then
|
||||
return "<span foreground='" .. placeholder_fg .. "'>" .. placeholder_text .. '</span>'
|
||||
end
|
||||
|
||||
local offset = 0
|
||||
if text:sub(cursor_pos - 1, cursor_pos - 1) == -1 then
|
||||
offset = 1
|
||||
end
|
||||
|
||||
if #text < cursor_pos then
|
||||
char = ' '
|
||||
spacer = ''
|
||||
text_start = gstring.xml_escape(text)
|
||||
text_end = ''
|
||||
else
|
||||
char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset))
|
||||
spacer = ' '
|
||||
text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1))
|
||||
text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1))
|
||||
end
|
||||
|
||||
if self._private.highlight and self._private.highlight.start_pos and self._private.highlight.end_pos then
|
||||
-- split the text into 3 parts based on the highlight and cursor position
|
||||
local text_start_highlight = gstring.xml_escape(text:sub(1, self._private.highlight.start_pos - 1))
|
||||
local text_highlighted = gstring.xml_escape(text:sub(self._private.highlight.start_pos,
|
||||
self._private.highlight.end_pos))
|
||||
local text_end_highlight = gstring.xml_escape(text:sub(self._private.highlight.end_pos + 1))
|
||||
|
||||
return text_start_highlight ..
|
||||
"<span foreground='" .. highlight_fg .. "' background='" .. highlight_bg .. "'>" ..
|
||||
text_highlighted .. '</span>' .. text_end_highlight
|
||||
else
|
||||
return text_start .. "<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
|
||||
char .. '</span>' .. text_end .. spacer
|
||||
end
|
||||
end ]]
|
||||
|
||||
local function text_extents(text, font, font_size, args)
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, args)
|
||||
cr:set_font_size(font_size)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
--[[
|
||||
calculate width/height of the text
|
||||
create new surface with the calculated width/height
|
||||
draw a vertical line on the surface as the cursor
|
||||
the position of the vertical line will be the cursor_pos - text length and the text extend
|
||||
draw the "text" .. "cursor" .. "rest of the text"
|
||||
return the surface
|
||||
|
||||
mouse_coord holds the coordinates where the user clicked
|
||||
if its not empty then draw the cursor where the user clicked,
|
||||
if its on a character then set the cursor to the closest space
|
||||
|
||||
if some text is highlighted then draw the text with the highlights
|
||||
]]
|
||||
--inputbox.text
|
||||
--inputbox.cursor_pos <<-- 1 = before the text, 2 = after the first character, 3 = after the second character, etc
|
||||
--inputbox.highlight <<-- { start_pos, end_pos }
|
||||
--inputbox.mouse_coord <<-- { x, y } (Will be saved after the user clicked, it will only be overwritten when the user clicks again)
|
||||
function inputbox:draw_text_surface(x, override_cursor)
|
||||
-- x can be 0 for the first time its drawn with a default cursor position
|
||||
x = x or 0
|
||||
|
||||
--Colors need to be in rgba 0-1 format, table.unpack is used to unpack the table into function arguments
|
||||
local fg, fg_highlight, bg_highlight, fg_cursor = { 1, 1, 1 }, { 1, 1, 1 }, { 0.1, 1, 1, 0.5 }, { 1, 1, 1 }
|
||||
|
||||
-- Main text_entent mainly to align everything to this one (it knows the highest and lowest point of the text)
|
||||
local text_extent = text_extents(self:get_text(), self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
--The offset if so the user has some space to click on the left and right side of the text
|
||||
local start_offset = 4
|
||||
local end_offset = 4
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, text_extent.width + start_offset + end_offset, text_extent.height)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
--Split the text initially into 2 or 3 parts (most likely split again later)
|
||||
local text = self:get_text()
|
||||
local text_start, text_end, text_highlight
|
||||
if self._private.highlight.start_pos ~= self._private.highlight.end_pos then
|
||||
text_start = text:sub(1, self._private.highlight.start_pos - 1)
|
||||
text_highlight = text:sub(self._private.highlight.start_pos, self._private.highlight.end_pos)
|
||||
text_end = text:sub(self._private.highlight.end_pos + 1)
|
||||
else
|
||||
text_start = text:sub(1, self._private.cursor_pos - 1)
|
||||
text_end = text:sub(self._private.cursor_pos)
|
||||
end
|
||||
|
||||
--Figure out the cursor position based on the mouse coordinates
|
||||
if override_cursor then
|
||||
local cursor_pos = 1
|
||||
for i = 1, #text, 1 do
|
||||
-- Not sure if I need new context's to check the character width but I got inconsistent results without it
|
||||
local ccr = cairo.Context(surface)
|
||||
ccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
ccr:set_font_size(self.font_size)
|
||||
local ext_c = ccr:text_extents(text:sub(1, i))
|
||||
if ext_c.width >= x then
|
||||
local cccr = cairo.Context(surface)
|
||||
cccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
cccr:set_font_size(self.font_size)
|
||||
if math.abs(cccr:text_extents(text:sub(1, i - 1)).width - x) <= math.abs(ext_c.width - x) then
|
||||
cursor_pos = i
|
||||
else
|
||||
cursor_pos = i + 1
|
||||
end
|
||||
break
|
||||
else
|
||||
cursor_pos = #text + 1
|
||||
end
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
end
|
||||
-- Text extents for the start and highlight without any splitting (less calculating, text_end is not needed)
|
||||
local text_start_extents = text_extents(text_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
local text_highlight_extents = text_extents(text_highlight, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.REGULAR)
|
||||
cr:set_font_size(self.font_size)
|
||||
--[[
|
||||
The following code is a bit of a mess because I have to check if the cursor is inside the highlighted text,
|
||||
the text_start or text_end and then split either of them again to draw the cursor between.
|
||||
]]
|
||||
if (self._private.cursor_pos > 1) and text_highlight then
|
||||
-- If the cursor is inside the highlighted text
|
||||
if (self._private.highlight.start_pos <= self._private.cursor_pos) and (self._private.highlight.end_pos >= self._private.cursor_pos) then
|
||||
-- Draw the text_start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- split the text_highlight at the cursor_pos
|
||||
local text_highlight_start = text_highlight:sub(1, self._private.cursor_pos - self._private.highlight.start_pos)
|
||||
local text_highlight_end = text_highlight:sub(self._private.cursor_pos - self._private.highlight.start_pos + 1)
|
||||
-- The text_highlight_start extents are needed for the cursor position and the text_highlight_end position
|
||||
local text_highlight_start_extents = text_extents(text_highlight_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first highlighted part(text_highlight_start)
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second highlighted part(text_highlight_end)
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight_end)
|
||||
|
||||
-- Draw the text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
|
||||
-- Draw the background highlight
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
elseif self._private.cursor_pos < self._private.highlight.start_pos then -- If its inside the text_start
|
||||
-- Split the text_start at the cursor_pos
|
||||
local text_start_start = text_start:sub(1, self._private.cursor_pos - 1)
|
||||
local text_start_end = text_start:sub(self._private.cursor_pos)
|
||||
-- The text_start_start extents is needed for the cursor position and the text_start_end position
|
||||
local text_start_start_extents = text_extents(text_start_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first part of the text_start(text_start_start)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second part of the text_start(text_start_end)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_start_end)
|
||||
|
||||
-- Draw the text_highlight
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
|
||||
-- Draw the text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
|
||||
-- Draw the highlight background
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
elseif self._private.cursor_pos > self._private.highlight.end_pos then -- If its inside the text_end
|
||||
-- Draw the text start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- Draw the text highlight
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
|
||||
--split the text_end at the cursor_pos
|
||||
local text_end_start = text_end:sub(1, self._private.cursor_pos - self._private.highlight.end_pos - 1)
|
||||
local text_end_end = text_end:sub(self._private.cursor_pos - self._private.highlight.end_pos)
|
||||
-- Text end_start extents needed for the cursor position and the text_end_end
|
||||
local text_end_start_extents = text_extents(text_end_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
|
||||
-- Draw the first part of the text_end (text_end_start)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end_start)
|
||||
|
||||
-- Draw the cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- Draw the second part of the text_end (text_end_end)
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end_end)
|
||||
|
||||
-- Draw the highlight background
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
end
|
||||
else -- If the cursor is all the way to the left no split is needed
|
||||
-- text_start
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset, -text_extent.y_bearing)
|
||||
cr:show_text(text_start)
|
||||
|
||||
-- Cursor
|
||||
cr:set_source_rgb(table.unpack(fg_cursor))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, text_extent.y_bearing)
|
||||
cr:line_to(start_offset + text_start_extents.x_advance, text_extent.height)
|
||||
cr:stroke()
|
||||
|
||||
-- text_highlight
|
||||
if text_highlight then
|
||||
cr:set_source_rgb(table.unpack(fg_highlight))
|
||||
cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_highlight)
|
||||
cr:set_source_rgba(table.unpack(bg_highlight))
|
||||
cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height)
|
||||
cr:fill()
|
||||
end
|
||||
|
||||
-- text_end
|
||||
cr:set_source_rgb(table.unpack(fg))
|
||||
cr:move_to(start_offset + text_highlight_extents.x_advance + text_start_extents.x_advance, -text_extent.y_bearing)
|
||||
cr:show_text(text_end)
|
||||
end
|
||||
return surface
|
||||
end
|
||||
|
||||
function inputbox:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function inputbox:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
inputbox.set_widget = base.set_widget_common
|
||||
|
||||
--- Clears the current text
|
||||
function inputbox:clear()
|
||||
self:set_text('')
|
||||
end
|
||||
|
||||
function inputbox:get_text()
|
||||
return self._private.text or ''
|
||||
end
|
||||
|
||||
function inputbox:set_text(text)
|
||||
self._private.text = text
|
||||
--self.markup = text_with_cursor(self:get_text(), #self:get_text(), self)
|
||||
self:emit_signal('property::text', text)
|
||||
end
|
||||
|
||||
--- Stop the keygrabber and mousegrabber
|
||||
function inputbox:stop()
|
||||
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end
|
||||
self:emit_signal('stopped')
|
||||
self.akeygrabber.stop()
|
||||
end
|
||||
|
||||
function inputbox:focus()
|
||||
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then
|
||||
akeygrabber.stop()
|
||||
self:run()
|
||||
end
|
||||
|
||||
self:connect_signal('button::press', function()
|
||||
if capi.mouse.current_widget ~= self then
|
||||
self:emit_signal('keygrabber::stop', '')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Init the inputbox and start the keygrabber
|
||||
function inputbox:run()
|
||||
if not self._private.text then self._private.text = '' end
|
||||
|
||||
-- Init the cursor position, but causes on refocus the cursor to move to the left
|
||||
local cursor_pos = self._private.cursor_pos or #self:get_text() + 1
|
||||
|
||||
-- Init and reset(when refocused) the highlight
|
||||
self._private.highlight = {}
|
||||
|
||||
self.akeygrabber = akeygrabber {
|
||||
autostart = true,
|
||||
start_callback = function()
|
||||
self:emit_signal('started')
|
||||
end,
|
||||
stop_callback = function(_, stop_key)
|
||||
if stop_key == 'Return' then
|
||||
self:emit_signal('submit', self:get_text(), stop_key)
|
||||
else
|
||||
self:emit_signal('stopped', stop_key)
|
||||
end
|
||||
end,
|
||||
stop_key = { 'Escape', 'Return' },
|
||||
keybindings = {
|
||||
--lShift, rShift = #50, #62
|
||||
--lControl, rControl = #37, #105
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
if cursor_pos > 1 then
|
||||
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0
|
||||
if not self._private.highlight.start_pos then
|
||||
self._private.highlight.start_pos = cursor_pos - 1
|
||||
end
|
||||
if not self._private.highlight.end_pos then
|
||||
self._private.highlight.end_pos = cursor_pos
|
||||
end
|
||||
|
||||
if self._private.highlight.start_pos < cursor_pos then
|
||||
self._private.highlight.end_pos = self._private.highlight.end_pos - 1
|
||||
else
|
||||
self._private.highlight.start_pos = self._private.highlight.start_pos
|
||||
end
|
||||
|
||||
cursor_pos = cursor_pos - 1
|
||||
end
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
if #self._private.text >= cursor_pos then
|
||||
if not self._private.highlight.end_pos then
|
||||
self._private.highlight.end_pos = cursor_pos - 1
|
||||
end
|
||||
if not self._private.highlight.start_pos then
|
||||
self._private.highlight.start_pos = cursor_pos
|
||||
end
|
||||
|
||||
if self._private.highlight.end_pos <= cursor_pos then
|
||||
self._private.highlight.end_pos = self._private.highlight.end_pos + 1
|
||||
else
|
||||
self._private.highlight.start_pos = self._private.highlight.start_pos + 1
|
||||
end
|
||||
cursor_pos = cursor_pos + 1
|
||||
if cursor_pos > #self._private.text + 1 then
|
||||
self._private.highlight = {}
|
||||
end
|
||||
end
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self._private.cursor_pos = cursor_pos
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Shift', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'a', -- a
|
||||
on_press = function()
|
||||
-- Mark the entire text
|
||||
self._private.highlight = {
|
||||
start_pos = 1,
|
||||
end_pos = #self._private.text,
|
||||
}
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'a')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'v', -- v
|
||||
on_press = function()
|
||||
local sel = capi.selection()
|
||||
if sel then
|
||||
sel = sel:gsub('\n', '')
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
-- insert the text into the selected part
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. sel .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + #sel + 1
|
||||
else
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
sel .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #sel
|
||||
end
|
||||
end
|
||||
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'v')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'c', -- c
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'x', -- x
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Left', -- left
|
||||
on_press = function()
|
||||
-- Find all spaces
|
||||
local spaces = {}
|
||||
local t, i = self._private.text, 0
|
||||
|
||||
while t:find('%s') do
|
||||
i = t:find('%s')
|
||||
table.insert(spaces, i)
|
||||
t = t:sub(1, i - 1) .. '-' .. t:sub(i + 1)
|
||||
end
|
||||
|
||||
local cp = 1
|
||||
for _, v in ipairs(spaces) do
|
||||
if (v < cursor_pos) then
|
||||
cp = v
|
||||
end
|
||||
end
|
||||
cursor_pos = cp
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Left')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Right', -- right
|
||||
on_press = function()
|
||||
local next_space = self._private.text:sub(cursor_pos):find('%s')
|
||||
if next_space then
|
||||
cursor_pos = cursor_pos + next_space
|
||||
else
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', 'Control', 'Right')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'BackSpace', --BackSpace
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the left
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + 1
|
||||
else
|
||||
if cursor_pos > 1 then
|
||||
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or
|
||||
0
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 2 - offset) ..
|
||||
self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos - 1 - offset
|
||||
end
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'BackSpace')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Delete', --delete
|
||||
on_press = function()
|
||||
-- If text is highlighted delete that, else just delete the character to the right
|
||||
if self._private.highlight and self._private.highlight.start_pos and
|
||||
self._private.highlight.end_pos then
|
||||
local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1)
|
||||
local text_end = self._private.text:sub(self._private.highlight.end_pos + 1)
|
||||
self:set_text(text_start .. text_end)
|
||||
self._private.highlight = {}
|
||||
cursor_pos = #text_start + 1
|
||||
else
|
||||
if cursor_pos <= #self._private.text then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
self._private.text:sub(cursor_pos + 1))
|
||||
end
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', nil, 'Delete')
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Left', --left
|
||||
on_press = function()
|
||||
-- Move cursor ro the left
|
||||
if cursor_pos > 1 then
|
||||
cursor_pos = cursor_pos - 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Right', --right
|
||||
on_press = function()
|
||||
-- Move cursor to the right
|
||||
if cursor_pos <= #self._private.text then
|
||||
cursor_pos = cursor_pos + 1
|
||||
end
|
||||
self._private.highlight = {}
|
||||
end,
|
||||
},
|
||||
--self.keybindings
|
||||
},
|
||||
keypressed_callback = function(_, modifiers, key)
|
||||
if modifiers[1] == 'Shift' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
string.upper(key) .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #key
|
||||
end
|
||||
elseif modifiers[1] == 'Mod2' or '' then
|
||||
if key:wlen() == 1 then
|
||||
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
|
||||
key .. self._private.text:sub(cursor_pos))
|
||||
cursor_pos = cursor_pos + #key
|
||||
end
|
||||
end
|
||||
|
||||
if cursor_pos < 1 then
|
||||
cursor_pos = 1
|
||||
elseif cursor_pos > #self._private.text + 1 then
|
||||
cursor_pos = #self._private.text + 1
|
||||
end
|
||||
self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface()
|
||||
self:emit_signal('inputbox::key_pressed', modifiers, key)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
--[[
|
||||
take the text and cursor position and figure out which character is next
|
||||
if mx is greater than lx then the right character is the next character
|
||||
if mx is less than lx then the left character is the next character
|
||||
|
||||
calculate the delta between mx and lx, if the delta is greater than the next
|
||||
character increase or decrease the cursor position by 1 (depends if the delta is positive or negative)
|
||||
and set the lx = mx
|
||||
|
||||
return 1 if advanced to the right, -1 if advanced to the left, 0 if not advanced; and the new lx
|
||||
]]
|
||||
function inputbox:advanced_by_character(mx, lx)
|
||||
local delta = mx - lx
|
||||
local character
|
||||
if delta < 0 then
|
||||
character = self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1)
|
||||
else
|
||||
character = self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1)
|
||||
end
|
||||
|
||||
--local character = (self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1) and (delta < 0)) or self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1)
|
||||
if character then
|
||||
local cr = cairo.Context(cairo.ImageSurface(cairo.Format.ARGB32, 1, 1))
|
||||
cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL)
|
||||
cr:set_font_size(self.font_size)
|
||||
local extents = cr:text_extents(character)
|
||||
if math.abs(delta) >= extents.x_advance then
|
||||
self._private.cursor_pos = self._private.cursor_pos + (((delta > 0) and 1) or -1)
|
||||
lx = mx
|
||||
return (((delta > 0) and 1) or -1), lx
|
||||
end
|
||||
end
|
||||
return 0, lx
|
||||
end
|
||||
|
||||
--- Creates a new inputbox widget
|
||||
-- @tparam table args Arguments for the inputbox widget
|
||||
-- @tparam string args.text The text to display in the inputbox
|
||||
-- @tparam[opt=beautiful.fg_normal] string args.fg Text foreground color
|
||||
-- @tparam[opt=beautiful.border_focus] string args.border_focus_color Border color when focused
|
||||
-- @tparam[opt=""] string args.placeholder_text placeholder text to be shown when not focused and
|
||||
-- @tparam[opt=beautiful.inputbox_placeholder_fg] string args.placeholder_fg placeholder text foreground color
|
||||
-- @tparam[opt=beautiful.inputbox_cursor_bg] string args.cursor_bg Cursor background color
|
||||
-- @tparam[opt=beautiful.inputbox_cursor_fg] string args.cursor_fg Cursor foreground color
|
||||
-- @tparam[opt=beautiful.inputbox_highlight_bg] string args.highlight_bg Highlight background color
|
||||
-- @tparam[opt=beautiful.inputbox_highlight_fg] string args.highlight_fg Highlight foreground color
|
||||
-- @treturn awful.widget.inputbox The inputbox widget.
|
||||
-- @constructorfct awful.widget.inputbox
|
||||
function inputbox.new(args)
|
||||
args = args or {}
|
||||
|
||||
-- directly pass a possible default text(this is not meant to be a hint)
|
||||
local w = imagebox()
|
||||
|
||||
--gtable.crush(w, args)
|
||||
gtable.crush(w, inputbox, true)
|
||||
w._private = {}
|
||||
|
||||
w._private.text = args.text or ''
|
||||
w.font_size = 24
|
||||
w.font = User_config.font.regular
|
||||
w._private.cursor_pos = args.cursor_pos
|
||||
w._private.highlight = args.highlight
|
||||
|
||||
w.p = apopup {
|
||||
widget = {
|
||||
{
|
||||
image = w:draw_text_surface(),
|
||||
resize = false,
|
||||
valign = 'bottom',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'text_image',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = 20,
|
||||
},
|
||||
bg = '#212121',
|
||||
visible = true,
|
||||
screen = 1,
|
||||
placement = aplacement.centered,
|
||||
}
|
||||
|
||||
w.p.widget:get_children_by_id('text_image')[1]:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
-- Get the mouse coordinates realative to the widget
|
||||
local x, y = mouse.coords().x - p.x - 20, mouse.coords().y - p.y - 20 -- 20 is the margin on either side
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false)
|
||||
w.highlight = { start_pos = w.cursor_pos, end_pos = w.cursor_pos }
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false)
|
||||
if not mousegrabber.isrunning() then
|
||||
local last_x, advanced, cursor_pos, mx = x, nil, w.cursor_pos, nil
|
||||
mousegrabber.run(function(m)
|
||||
mx = m.x - p.x - 20
|
||||
if (math.abs(mx - x) > 5) then
|
||||
-- Returns 1 if the mouse has advanced to the right, -1 if it has advanced to the left
|
||||
advanced, last_x = w:advanced_by_character(mx, last_x)
|
||||
if advanced == 1 then
|
||||
print(cursor_pos, w.highlight.start_pos, w.highlight.end_pos)
|
||||
if cursor_pos <= w.highlight.start_pos then
|
||||
if w.highlight.end_pos < #w._private.text then
|
||||
w.highlight.end_pos = w.highlight.end_pos + 1
|
||||
end
|
||||
else
|
||||
w.highlight.start_pos = w.highlight.start_pos + 1
|
||||
end
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true)
|
||||
print(w.highlight.start_pos, w.highlight.end_pos)
|
||||
elseif advanced == -1 then
|
||||
if cursor_pos >= w.highlight.end_pos then
|
||||
if w.highlight.start_pos > 1 then
|
||||
w.highlight.start_pos = w.highlight.start_pos - 1
|
||||
end
|
||||
else
|
||||
w.highlight.end_pos = w.highlight.end_pos - 1
|
||||
end
|
||||
p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true)
|
||||
print(w.highlight.start_pos, w.highlight.end_pos)
|
||||
end
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end
|
||||
w:run()
|
||||
end),
|
||||
})
|
||||
|
||||
--w.font = args.font or beautiful.font
|
||||
|
||||
--w.keybindings = args.keybindings or {}
|
||||
--w.hint_text = args.hint_text
|
||||
|
||||
--w.markup = args.text or text_with_cursor('', 1, w)
|
||||
return w
|
||||
end
|
||||
|
||||
function inputbox.mt:__call(...)
|
||||
return inputbox.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(inputbox, inputbox.mt)
|
||||
485
awesome/src/modules/inputbox/new.lua
Normal file
@@ -0,0 +1,485 @@
|
||||
local Pango = require('lgi').Pango
|
||||
local PangoCairo = require('lgi').PangoCairo
|
||||
local abutton = require('awful.button')
|
||||
local akey = require('awful.key')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local base = require('wibox.widget.base')
|
||||
local beautiful = require('beautiful')
|
||||
local cairo = require('lgi').cairo
|
||||
local gobject = require('gears.object')
|
||||
local gstring = require('gears.string')
|
||||
local gsurface = require('gears.surface')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local imagebox = require('wibox.widget.imagebox')
|
||||
local setmetatable = setmetatable
|
||||
local textbox = require('wibox.widget.textbox')
|
||||
local wibox = require('wibox')
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
local capi = {
|
||||
selection = selection,
|
||||
mousegrabber = mousegrabber,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local inputbox = {}
|
||||
|
||||
local function get_text_extent(text, font, font_size, args)
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0)
|
||||
local cr = cairo.Context(surface)
|
||||
cr:select_font_face(font, args)
|
||||
cr:set_font_size(font_size)
|
||||
return cr:text_extents(text)
|
||||
end
|
||||
|
||||
function inputbox.draw_text(self)
|
||||
local text = self:get_text()
|
||||
local highlight = self:get_highlight()
|
||||
local fg_color = { 1, 1, 1 }
|
||||
local cursor_color = { 1, 1, 1, 1 }
|
||||
|
||||
if text == '' then
|
||||
fg_color = { 0.2, 0.2, 0.2 }
|
||||
-- Silently change the text, it will be changed back after it is drawn
|
||||
self._private.layout:set_text(self._private.text_hint)
|
||||
end
|
||||
|
||||
local _, pango_extent = self._private.layout:get_extents()
|
||||
|
||||
local surface = cairo.ImageSurface(cairo.Format.ARGB32, (pango_extent.width / Pango.SCALE) + pango_extent.x, (pango_extent.height / Pango.SCALE) + pango_extent.y)
|
||||
local cr = cairo.Context(surface)
|
||||
|
||||
-- Draw highlight
|
||||
if (highlight.start_pos ~= 0) or (highlight.end_pos ~= 0) then
|
||||
cr:set_source_rgb(0, 0, 1)
|
||||
local txt = text:sub(self:get_highlight().start_pos + 1, self:get_highlight().end_pos)
|
||||
cr:rectangle(
|
||||
cr:text_extents(text:sub(0, self:get_highlight().start_pos)).x_advance,
|
||||
pango_extent.y / Pango.SCALE,
|
||||
cr:text_extents(txt).width,
|
||||
pango_extent.height / Pango.SCALE
|
||||
)
|
||||
cr:fill()
|
||||
end
|
||||
|
||||
-- Draw text
|
||||
PangoCairo.update_layout(cr, self._private.layout)
|
||||
cr:set_source_rgba(1, 1, 1, 1)
|
||||
cr:move_to(0, 0)
|
||||
PangoCairo.show_layout(cr, self._private.layout)
|
||||
|
||||
-- Draw cursor
|
||||
cr:set_source_rgba(table.unpack(cursor_color))
|
||||
local cursor = self:get_cursor_pos()
|
||||
cr:rectangle(
|
||||
cursor.x / Pango.SCALE,
|
||||
cursor.y / Pango.SCALE,
|
||||
2,
|
||||
cursor.height / Pango.SCALE)
|
||||
cr:fill()
|
||||
|
||||
self.widget:set_image(surface)
|
||||
return surface
|
||||
end
|
||||
|
||||
function inputbox:start_keygrabber()
|
||||
self.akeygrabber = akeygrabber {
|
||||
autostart = true,
|
||||
stop_key = { 'Escape', 'Return' },
|
||||
start_callback = function()
|
||||
end,
|
||||
stop_callback = function()
|
||||
end,
|
||||
keybindings = {
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'BackSpace',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if hl.end_pos ~= hl.start_pos then
|
||||
self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text))
|
||||
self:set_cursor_pos(hl.start_pos)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(text:sub(1, cursor_pos - 1) .. text:sub(cursor_pos + 1))
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Delete',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if hl.end_pos ~= hl.start_pos then
|
||||
self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text))
|
||||
self:set_cursor_pos(hl.start_pos)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(text:sub(1, cursor_pos) .. text:sub(cursor_pos + 2, #text))
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(self:get_cursor_index() - 1)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(self:get_cursor_index() + 1)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Home',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(0)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'End',
|
||||
on_press = function()
|
||||
self:set_cursor_pos(#self:get_text())
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
if cursor_pos == hl.start_pos then
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
elseif cursor_pos == hl.end_pos then
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
else
|
||||
if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
hl = self:get_highlight()
|
||||
self:set_cursor_pos(cursor_pos - 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Shift' },
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
if cursor_pos == hl.end_pos then
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
elseif cursor_pos == hl.start_pos then
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos }
|
||||
else
|
||||
if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
hl = self:get_highlight()
|
||||
self:set_cursor_pos(cursor_pos + 1)
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() }
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'a',
|
||||
on_press = function()
|
||||
self:set_highlight { start_pos = 0, end_pos = #self:get_text() }
|
||||
self:set_cursor_pos(#self:get_text() - 1)
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'c',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
if hl.start_pos ~= hl.end_pos then
|
||||
local text = self:get_text():sub(hl.start_pos, hl.end_pos)
|
||||
--TODO:self:copy_to_clipboard(text)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'v',
|
||||
on_press = function()
|
||||
local hl = self:get_highlight()
|
||||
local selection = capi.selection()
|
||||
if hl.start_pos ~= hl.end_pos then
|
||||
self:set_text(self:get_text():sub(1, hl.start_pos) .. selection .. self:get_text():sub(hl.end_pos + 1, #self:get_text()))
|
||||
self:set_cursor_pos(hl.start_pos + #selection)
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
else
|
||||
self:set_text(self:get_text():sub(1, self:get_cursor_pos()) .. selection .. self:get_text():sub(self:get_cursor_pos() + 1, #self:get_text()))
|
||||
self:set_cursor_pos(self:get_cursor_pos() + #selection)
|
||||
end
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'x',
|
||||
on_press = function()
|
||||
--TODO
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Right',
|
||||
on_press = function()
|
||||
|
||||
end,
|
||||
},
|
||||
akey {
|
||||
modifiers = { 'Control' },
|
||||
key = 'Left',
|
||||
on_press = function()
|
||||
|
||||
end,
|
||||
},
|
||||
},
|
||||
keypressed_callback = function(_, mod, key)
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_index()
|
||||
if (mod[1] == 'Mod2' or '') and (key:wlen() == 1) then
|
||||
self:set_text(text:sub(1, cursor_pos) .. key .. text:sub(cursor_pos + 1, #text))
|
||||
self:set_cursor_pos(cursor_pos + #key)
|
||||
elseif (mod[1] == 'Shift') and (key:wlen() == 1) then
|
||||
self:set_text(text:sub(1, cursor_pos) .. key:upper() .. text:sub(cursor_pos + 1, #text))
|
||||
self:set_cursor_pos(cursor_pos + #key)
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
--[[ function inputbox:advanced_by_character(mx, last_x)
|
||||
local delta = mx - last_x
|
||||
local character
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
if delta < 0 then
|
||||
character = text:sub(cursor_pos + 1, cursor_pos + 1)
|
||||
else
|
||||
character = text:sub(cursor_pos - 1, cursor_pos - 1)
|
||||
end
|
||||
|
||||
if character then
|
||||
local extents = get_text_extent(character, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL })
|
||||
if math.abs(delta) >= extents.x_advance then
|
||||
self:set_cursor_pos(cursor_pos + (((delta > 0) and 1) or -1))
|
||||
last_x = mx
|
||||
return (((delta > 0) and 1) or -1), last_x
|
||||
end
|
||||
end
|
||||
return 0, last_x
|
||||
end ]]
|
||||
|
||||
function inputbox:start_mousegrabber(x, y)
|
||||
--[[ if not mousegrabber.isrunning() then
|
||||
local last_x, advanced, cursor_pos, mx = x, nil, self:get_cursor_pos(), nil
|
||||
local hl = self:get_highlight()
|
||||
self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos }
|
||||
local text = self:get_text()
|
||||
mousegrabber.run(function(m)
|
||||
mx = m.x
|
||||
if (math.abs(mx - x) > 5) then
|
||||
advanced, last_x = self:advanced_by_character(mx, last_x)
|
||||
if advanced == 1 then
|
||||
if cursor_pos <= hl.start_pos then
|
||||
if hl.end_pos < #text then
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos }
|
||||
end
|
||||
elseif advanced == -1 then
|
||||
if cursor_pos >= hl.end_pos then
|
||||
if hl.start_pos > 1 then
|
||||
self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 }
|
||||
end
|
||||
end
|
||||
end
|
||||
hl = self:get_highlight()
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end ]]
|
||||
if not mousegrabber.isrunning() then
|
||||
local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE)
|
||||
|
||||
if not index then return end
|
||||
|
||||
self:set_cursor_pos(index)
|
||||
-- Remove highlight, but also prepare its position (same pos = no highlight)
|
||||
self:set_highlight { start_pos = index, end_pos = index }
|
||||
|
||||
local text = self:get_text()
|
||||
local cursor_pos = self:get_cursor_pos()
|
||||
local hl = self:get_highlight()
|
||||
|
||||
mousegrabber.run(function(m)
|
||||
index, _ = self._private.layout:xy_to_index(m.x * Pango.SCALE, m.y * Pango.SCALE)
|
||||
|
||||
if not index then return end
|
||||
|
||||
if math.abs(index - cursor_pos) == 1 then
|
||||
if cursor_pos <= hl.start_pos then
|
||||
if hl.end_pos < #text then
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos }
|
||||
end
|
||||
elseif math.abs(index - cursor_pos) == -1 then
|
||||
if cursor_pos >= hl.end_pos then
|
||||
if hl.start_pos > 1 then
|
||||
self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos }
|
||||
end
|
||||
else
|
||||
self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 }
|
||||
end
|
||||
end
|
||||
|
||||
if index ~= cursor_pos then
|
||||
self:set_cursor_pos(index)
|
||||
end
|
||||
|
||||
return m.buttons[1]
|
||||
end, 'xterm')
|
||||
end
|
||||
end
|
||||
|
||||
function inputbox:set_cursor_pos_from_mouse(x, y)
|
||||
-- When setting the cursor position, trailing is not needed as its handled by the setter
|
||||
local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE)
|
||||
if not index then return end
|
||||
|
||||
self:set_highlight { start_pos = 0, end_pos = 0 }
|
||||
self:set_cursor_pos(index)
|
||||
end
|
||||
|
||||
function inputbox:get_text()
|
||||
return self._private.layout:get_text()
|
||||
end
|
||||
|
||||
function inputbox:set_text(text)
|
||||
if self:get_text() == text then return end
|
||||
|
||||
local attributes, parsed = Pango.parse_markup(text, -1, 0)
|
||||
|
||||
if not attributes then return parsed.message or tostring(parsed) end
|
||||
|
||||
self._private.layout:set_text(parsed, string.len(parsed))
|
||||
self._private.layout:set_attributes(attributes)
|
||||
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:get_cursor_pos()
|
||||
return self._private.layout:get_cursor_pos(self._private.cursor_pos.index)
|
||||
end
|
||||
|
||||
function inputbox:get_cursor_index()
|
||||
return self._private.cursor_pos.index
|
||||
end
|
||||
|
||||
function inputbox:set_cursor_pos(cursor_pos)
|
||||
-- moving only moved one character set, to move it multiple times we need to loop as long as the difference to the new cursor isn't 0
|
||||
if not cursor_pos or (cursor_pos < 0) or (cursor_pos >= #self:get_text()) then return end
|
||||
while (cursor_pos - self._private.cursor_pos.index) ~= 0 do
|
||||
self._private.cursor_pos.index, self._private.cursor_pos.trailing = self._private.layout:move_cursor_visually(
|
||||
true, self._private.cursor_pos.index,
|
||||
self._private.cursor_pos.trailing,
|
||||
cursor_pos - self._private.cursor_pos.index
|
||||
)
|
||||
end
|
||||
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:get_highlight()
|
||||
return self._private.highlight
|
||||
end
|
||||
|
||||
function inputbox:set_highlight(highlight)
|
||||
self._private.highlight = highlight
|
||||
self.draw_text(self)
|
||||
end
|
||||
|
||||
function inputbox:focus()
|
||||
|
||||
end
|
||||
|
||||
function inputbox:unfocus()
|
||||
|
||||
end
|
||||
|
||||
function inputbox.new(args)
|
||||
local ret = gobject { enable_properties = true }
|
||||
args.text = args.text .. '\n'
|
||||
gtable.crush(ret, inputbox)
|
||||
|
||||
ret._private = {}
|
||||
ret._private.context = PangoCairo.font_map_get_default():create_context()
|
||||
ret._private.layout = Pango.Layout.new(ret._private.context)
|
||||
|
||||
ret.font_size = 24
|
||||
ret.font = 'JetBrainsMono Nerd Font, ' .. 24
|
||||
ret._private.layout:set_font_description(Pango.FontDescription.from_string('JetBrainsMono Nerd Font 16'))
|
||||
|
||||
ret._private.text_hint = args.text_hint or ''
|
||||
ret._private.cursor_pos = {
|
||||
index = args.cursor_pos or 0,
|
||||
trailing = 0,
|
||||
}
|
||||
ret._private.highlight = args.highlight or {
|
||||
start_pos = 0,
|
||||
end_pos = 0,
|
||||
}
|
||||
|
||||
ret.widget = imagebox(nil, false)
|
||||
|
||||
ret.widget:connect_signal('button::press', function(_, x, y, button)
|
||||
if button == 1 then
|
||||
ret:set_cursor_pos_from_mouse(x, y)
|
||||
--ret:start_mousegrabber(x, y)
|
||||
ret:start_keygrabber()
|
||||
end
|
||||
end)
|
||||
|
||||
ret:set_text(args.text or '')
|
||||
--ret:set_cursor_pos(ret._private.cursor_pos)
|
||||
ret:set_highlight(ret._private.highlight)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
return setmetatable(inputbox, {
|
||||
__call = function(_, ...)
|
||||
return inputbox.new(...)
|
||||
end,
|
||||
})
|
||||
@@ -3,44 +3,45 @@
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears").table
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local gcolor = require("gears").color
|
||||
local lgi = require("lgi")
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local abutton = require('awful.button')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears').table
|
||||
local gfilesystem = require('gears').filesystem
|
||||
local gcolor = require('gears').color
|
||||
local lgi = require('lgi')
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
local NM = lgi.NM
|
||||
|
||||
-- Third party libs
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
|
||||
-- Own libs
|
||||
local ap_form = require("src.modules.network_controller.ap_form")
|
||||
local cm = require("src.modules.context_menu.init")
|
||||
local ap_form = require('src.modules.network_controller.ap_form')
|
||||
local cm = require('src.modules.context_menu.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local access_point = { mt = {} }
|
||||
|
||||
local function flags_to_security(flags, wpa_flags, rsn_flags)
|
||||
local str = ""
|
||||
local str = ''
|
||||
if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then
|
||||
str = str .. " WEP"
|
||||
str = str .. ' WEP'
|
||||
end
|
||||
if wpa_flags ~= 0 then
|
||||
str = str .. " WPA1"
|
||||
str = str .. ' WPA1'
|
||||
end
|
||||
if not rsn_flags ~= 0 then
|
||||
str = str .. " WPA2"
|
||||
str = str .. ' WPA2'
|
||||
end
|
||||
if wpa_flags == 512 or rsn_flags == 512 then
|
||||
str = str .. " 802.1X"
|
||||
str = str .. ' 802.1X'
|
||||
end
|
||||
|
||||
return (str:gsub("^%s", ""))
|
||||
return (str:gsub('^%s', ''))
|
||||
end
|
||||
|
||||
function access_point:get_access_point_connections(ssid)
|
||||
@@ -50,9 +51,9 @@ function access_point:get_access_point_connections(ssid)
|
||||
for _, connection_path in ipairs(connections) do
|
||||
local NetworkManagerSettingsConnection = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Settings.Connection",
|
||||
path = connection_path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
|
||||
path = connection_path,
|
||||
}
|
||||
|
||||
if NetworkManagerSettingsConnection.Filename:find(ssid) then
|
||||
@@ -66,39 +67,39 @@ end
|
||||
function access_point:create_profile(ap, password, auto_connect)
|
||||
local s_wsec = {}
|
||||
local security = flags_to_security(ap.Flags, ap.WpaFlags, ap.RsnFlags)
|
||||
if security ~= "" then
|
||||
if security:match("WPA") then
|
||||
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "wpa-psk")
|
||||
s_wsec["auth-alg"] = lgi.GLib.Variant("s", "open")
|
||||
s_wsec["psk"] = lgi.GLib.Variant("s", password)
|
||||
if security ~= '' then
|
||||
if security:match('WPA') then
|
||||
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk')
|
||||
s_wsec['auth-alg'] = lgi.GLib.Variant('s', 'open')
|
||||
s_wsec['psk'] = lgi.GLib.Variant('s', password)
|
||||
else
|
||||
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "None")
|
||||
s_wsec["wep-key-type"] = lgi.GLib.Variant("s", NM.WepKeyType.PASSPHRASE)
|
||||
s_wsec["wep-key0"] = lgi.GLib.Variant("s", password)
|
||||
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'None')
|
||||
s_wsec['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE)
|
||||
s_wsec['wep-key0'] = lgi.GLib.Variant('s', password)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
["connection"] = {
|
||||
['connection'] = {
|
||||
-- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface),
|
||||
["uuid"] = lgi.GLib.Variant("s", string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
|
||||
['uuid'] = lgi.GLib.Variant('s', string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
|
||||
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
||||
return string.format('%x', v)
|
||||
end)),
|
||||
["id"] = lgi.GLib.Variant("s", NM.utils_ssid_to_utf8(ap.Ssid)),
|
||||
["type"] = lgi.GLib.Variant("s", "802-11-wireless"),
|
||||
["autoconnect"] = lgi.GLib.Variant("b", auto_connect),
|
||||
['id'] = lgi.GLib.Variant('s', NM.utils_ssid_to_utf8(ap.Ssid)),
|
||||
['type'] = lgi.GLib.Variant('s', '802-11-wireless'),
|
||||
['autoconnect'] = lgi.GLib.Variant('b', auto_connect),
|
||||
},
|
||||
["ipv4"] = {
|
||||
["method"] = lgi.GLib.Variant("s", "auto")
|
||||
['ipv4'] = {
|
||||
['method'] = lgi.GLib.Variant('s', 'auto'),
|
||||
},
|
||||
["ipv6"] = {
|
||||
["method"] = lgi.GLib.Variant("s", "auto"),
|
||||
['ipv6'] = {
|
||||
['method'] = lgi.GLib.Variant('s', 'auto'),
|
||||
},
|
||||
["802-11-wireless"] = {
|
||||
["mode"] = lgi.GLib.Variant("s", "infrastructure"),
|
||||
['802-11-wireless'] = {
|
||||
['mode'] = lgi.GLib.Variant('s', 'infrastructure'),
|
||||
},
|
||||
["802-11-wireless-security"] = s_wsec
|
||||
['802-11-wireless-security'] = s_wsec,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -113,26 +114,25 @@ function access_point:connect(ap, password, auto_connect)
|
||||
if #connections == 0 then
|
||||
self.NetworkManager:AddAndActivateConnectionAsync(function(proxy, context, success, fail)
|
||||
if fail ~= nil then
|
||||
print("Error: " .. tostring(fail), tostring(fail.code))
|
||||
self:emit_signal("NetworkManager::failed", tostring(fail), tostring(fail.code))
|
||||
self:emit_signal('NetworkManager::failed', tostring(fail), tostring(fail.code))
|
||||
return
|
||||
end
|
||||
|
||||
self:emit_signal("NetworkManager::connected", success)
|
||||
end, { call_id = "my-id" }, profile, self.NetworkManagerDevice.object_path,
|
||||
self:emit_signal('NetworkManager::connected', success)
|
||||
end, { call_id = 'my-id' }, profile, self.NetworkManagerDevice.object_path,
|
||||
self.NetworkManagerAccessPoint.object_path)
|
||||
--88ALYLNxo9Kk*RwRxMfN
|
||||
else
|
||||
connections[1]:Update(profile)
|
||||
self.NetworkManager:ActivateConnectionAsync(function(proxy, context, success, failure)
|
||||
if failure then
|
||||
self:emit_signal("NM::AccessPointFailed", tostring(failure))
|
||||
self:emit_signal('NM::AccessPointFailed', tostring(failure))
|
||||
return
|
||||
end
|
||||
|
||||
self:emit_signal("NM::AccessPointConnected", NM.utils_ssid_to_utf8(ap.Ssid))
|
||||
self:emit_signal('NM::AccessPointConnected', NM.utils_ssid_to_utf8(ap.Ssid))
|
||||
end,
|
||||
{ call_id = "my-id" }, connections[1].object_path, self.NetworkManagerDevice.object_path,
|
||||
{ call_id = 'my-id' }, connections[1].object_path, self.NetworkManagerDevice.object_path,
|
||||
self.NetworkManagerAccessPoint.object_path)
|
||||
end
|
||||
end
|
||||
@@ -156,9 +156,9 @@ function access_point.new(args)
|
||||
|
||||
local ssid_text = awidget.inputbox {
|
||||
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid) or
|
||||
args.NetworkManagerAccessPoint.hw_address or "Unknown",
|
||||
halign = "left",
|
||||
valign = "center",
|
||||
args.NetworkManagerAccessPoint.hw_address or 'Unknown',
|
||||
halign = 'left',
|
||||
valign = 'center',
|
||||
}
|
||||
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
@@ -168,84 +168,86 @@ function access_point.new(args)
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
icondir .. 'wifi-strength-' .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color),
|
||||
id = "icon",
|
||||
id = 'icon',
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "icon_container",
|
||||
strategy = "max",
|
||||
id = 'icon_container',
|
||||
strategy = 'max',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
ssid_text,
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(300),
|
||||
id = "alias"
|
||||
id = 'alias',
|
||||
},
|
||||
width = dpi(260),
|
||||
height = dpi(40),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'max',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ -- Spacing
|
||||
forced_width = dpi(10),
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "con",
|
||||
id = 'con',
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
id = "place",
|
||||
strategy = "max",
|
||||
id = 'place',
|
||||
strategy = 'max',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "margin0",
|
||||
id = 'margin0',
|
||||
margin = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "device_layout",
|
||||
layout = wibox.layout.align.horizontal
|
||||
id = 'device_layout',
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
id = "device_margin",
|
||||
id = 'device_margin',
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.network_manager.access_point.bg,
|
||||
fg = Theme_config.network_manager.access_point.fg,
|
||||
border_color = Theme_config.network_manager.access_point.border_color,
|
||||
border_width = Theme_config.network_manager.access_point.border_width,
|
||||
id = "background",
|
||||
id = 'background',
|
||||
shape = Theme_config.network_manager.access_point.device_shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(type(ret) == 'table', 'access_point:ret is not a table')
|
||||
|
||||
gtable.crush(ret, access_point, true)
|
||||
|
||||
ret.NetworkManagerAccessPoint = args.NetworkManagerAccessPoint
|
||||
@@ -256,49 +258,49 @@ function access_point.new(args)
|
||||
|
||||
ret.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = ret.NetworkManagerAccessPoint.object_path,
|
||||
}
|
||||
|
||||
-- Update the access point strength
|
||||
ret.NetworkManagerAccessPointProperties:connect_signal(function(_, properties, data)
|
||||
if data.Strength then
|
||||
awesome.emit_signal("NM::AccessPointStrength", data.Strength)
|
||||
awesome.emit_signal('NM::AccessPointStrength', data.Strength)
|
||||
if ret.is_ap_active(ret.NetworkManagerAccessPoint.object_path) then
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color2)
|
||||
else
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color)
|
||||
end
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
|
||||
ret.bg = Theme_config.network_manager.access_point.fg
|
||||
ret.fg = Theme_config.network_manager.access_point.bg
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color2)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
||||
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color2)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color2)
|
||||
else
|
||||
ret.bg = Theme_config.network_manager.access_point.bg
|
||||
ret.fg = Theme_config.network_manager.access_point.fg
|
||||
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
||||
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
||||
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
|
||||
Theme_config.network_manager.access_point.icon_color)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
||||
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color)
|
||||
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
|
||||
icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color)
|
||||
end
|
||||
|
||||
ret.ap_form = ap_form {
|
||||
screen = args.screen,
|
||||
NetworkManagerAccessPoint = args.NetworkManagerAccessPoint,
|
||||
ap = ret
|
||||
ap = ret,
|
||||
}
|
||||
|
||||
ret.cm = cm {
|
||||
@@ -309,40 +311,40 @@ function access_point.new(args)
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
stragety = 'exact',
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
id = 'text_role',
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}, spacing = dpi(10),
|
||||
entries = {
|
||||
{ -- Connect/Disconnect a device
|
||||
name = "ret.device.Connected" and "Disconnect" or "Connect",
|
||||
icon = gcolor.recolor_image("ret.device.Connected" and icondir .. "link-off.svg" or
|
||||
icondir .. "link.svg",
|
||||
name = 'ret.device.Connected' and 'Disconnect' or 'Connect',
|
||||
icon = gcolor.recolor_image('ret.device.Connected' and icondir .. 'link-off.svg' or
|
||||
icondir .. 'link.svg',
|
||||
Theme_config.network_manager.access_point.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_connection(ret.NetworkManagerAccessPoint)
|
||||
end,
|
||||
id = "connected"
|
||||
}
|
||||
}
|
||||
id = 'connected',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ret:buttons(gtable.join(
|
||||
@@ -362,7 +364,7 @@ function access_point.new(args)
|
||||
)
|
||||
))
|
||||
|
||||
Hover_signal(ret)
|
||||
hover.bg_hover { widget = ret }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
local abutton = require("awful.button")
|
||||
local aplacement = require("awful.placement")
|
||||
local apopup = require("awful.popup")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local gcolor = require("gears.color")
|
||||
local gshape = require("gears.shape")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local NM = require("lgi").NM
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local aplacement = require('awful.placement')
|
||||
local apopup = require('awful.popup')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local NM = require('lgi').NM
|
||||
local wibox = require('wibox')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
mousegrabber = mousegrabber
|
||||
mousegrabber = mousegrabber,
|
||||
}
|
||||
|
||||
local ap_form = { mt = {} }
|
||||
@@ -28,7 +30,7 @@ function ap_form.new(args)
|
||||
args = args or {}
|
||||
args.screen = args.screen
|
||||
|
||||
local password = awidget.inputbox { hint_text = "Password..." }
|
||||
local password = awidget.inputbox { hint_text = 'Password...' }
|
||||
|
||||
local ret = apopup {
|
||||
widget = {
|
||||
@@ -40,31 +42,31 @@ function ap_form.new(args)
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid),
|
||||
font = User_config.font.specify .. ",extra bold 16",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
font = User_config.font.specify .. ',extra bold 16',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5)
|
||||
margins = dpi(5),
|
||||
},
|
||||
{ -- Close button
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = gcolor.recolor_image(icondir .. "close.svg", Theme_config.network_manager.form.icon_fg),
|
||||
image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.network_manager.form.icon_fg),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = Theme_config.network_manager.form.close_icon_shape,
|
||||
id = "close_button",
|
||||
bg = Theme_config.network_manager.form.close_bg
|
||||
id = 'close_button',
|
||||
bg = Theme_config.network_manager.form.close_bg,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.network_manager.form.header_bg,
|
||||
@@ -73,9 +75,9 @@ function ap_form.new(args)
|
||||
{ -- Form
|
||||
{ -- Password
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Password",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Password',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.container.margin,
|
||||
@@ -89,25 +91,25 @@ function ap_form.new(args)
|
||||
password,
|
||||
widget = wibox.container.margin,
|
||||
margins = 5,
|
||||
id = "marg"
|
||||
id = 'marg',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = 400,
|
||||
height = 50,
|
||||
id = "const"
|
||||
id = 'const',
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = "#212121",
|
||||
fg = "#F0F0F0",
|
||||
border_color = "#414141",
|
||||
bg = '#212121',
|
||||
fg = '#F0F0F0',
|
||||
border_color = '#414141',
|
||||
border_width = 2,
|
||||
shape = gshape.rounded_rect,
|
||||
forced_width = 300,
|
||||
forced_height = 50,
|
||||
id = "password_container"
|
||||
id = 'password_container',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
{ -- Actions
|
||||
{ -- Auto connect
|
||||
@@ -121,26 +123,26 @@ function ap_form.new(args)
|
||||
check_color = Theme_config.network_manager.form.checkbox_bg,
|
||||
border_color = Theme_config.network_manager.form.checkbox_bg,
|
||||
border_width = 2,
|
||||
id = "checkbox",
|
||||
widget = wibox.widget.checkbox
|
||||
id = 'checkbox',
|
||||
widget = wibox.widget.checkbox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "exact",
|
||||
strategy = 'exact',
|
||||
width = dpi(30),
|
||||
height = dpi(30)
|
||||
height = dpi(30),
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Auto connect",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Auto connect',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
nil,
|
||||
{ -- Connect
|
||||
@@ -148,9 +150,9 @@ function ap_form.new(args)
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
text = "Connect",
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
text = 'Connect',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
@@ -159,18 +161,18 @@ function ap_form.new(args)
|
||||
bg = Theme_config.network_manager.form.button_bg,
|
||||
fg = Theme_config.network_manager.form.button_fg,
|
||||
shape = Theme_config.network_manager.form.button_shape,
|
||||
id = "connect_button",
|
||||
id = 'connect_button',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10)
|
||||
margins = dpi(10),
|
||||
},
|
||||
placement = aplacement.centered,
|
||||
ontop = true,
|
||||
@@ -182,55 +184,55 @@ function ap_form.new(args)
|
||||
shape = Theme_config.network_manager.form.shape,
|
||||
border_color = Theme_config.network_manager.form.border_color,
|
||||
border_width = Theme_config.network_manager.form.border_width,
|
||||
type = "dialog",
|
||||
type = 'dialog',
|
||||
screen = args.screen,
|
||||
}
|
||||
|
||||
local password_container = ret.widget:get_children_by_id("password_container")[1]
|
||||
local password_container = ret.widget:get_children_by_id('password_container')[1]
|
||||
|
||||
gtable.crush(ret, ap_form, true)
|
||||
|
||||
-- Focus the searchbar when its left clicked
|
||||
password_container:buttons(gtable.join {
|
||||
abutton({}, 1, function()
|
||||
password:focus()
|
||||
end)
|
||||
end),
|
||||
})
|
||||
|
||||
--#region Hover signals to change the cursor to a text cursor
|
||||
local old_cursor, old_wibox
|
||||
password_container:connect_signal("mouse::enter", function()
|
||||
password_container:connect_signal('mouse::enter', function()
|
||||
local wid = capi.mouse.current_wibox
|
||||
if wid then
|
||||
old_cursor, old_wibox = wid.cursor, wid
|
||||
wid.cursor = "xterm"
|
||||
wid.cursor = 'xterm'
|
||||
end
|
||||
end)
|
||||
password_container:connect_signal("mouse::leave", function()
|
||||
password_container:connect_signal('mouse::leave', function()
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
gtable.crush(ret, ap_form, true)
|
||||
|
||||
local checkbox = ret.widget:get_children_by_id("checkbox")[1]
|
||||
checkbox:connect_signal("button::press", function()
|
||||
local checkbox = ret.widget:get_children_by_id('checkbox')[1]
|
||||
checkbox:connect_signal('button::press', function()
|
||||
checkbox.checked = not checkbox.checked
|
||||
end)
|
||||
|
||||
local close_button = ret.widget:get_children_by_id("close_button")[1]
|
||||
close_button:connect_signal("button::press", function()
|
||||
local close_button = ret.widget:get_children_by_id('close_button')[1]
|
||||
close_button:connect_signal('button::press', function()
|
||||
ret:popup_toggle()
|
||||
end)
|
||||
Hover_signal(close_button)
|
||||
hover.bg_hover { widget = close_button }
|
||||
|
||||
local connect_button = ret.widget:get_children_by_id("connect_button")[1]
|
||||
connect_button:connect_signal("button::press", function()
|
||||
local connect_button = ret.widget:get_children_by_id('connect_button')[1]
|
||||
connect_button:connect_signal('button::press', function()
|
||||
password:stop()
|
||||
args.ap:connect(args.NetworkManagerAccessPoint, password:get_text(),
|
||||
ret.widget:get_children_by_id("checkbox")[1].checked)
|
||||
ret.widget:get_children_by_id('checkbox')[1].checked)
|
||||
ret:popup_toggle()
|
||||
end)
|
||||
Hover_signal(connect_button)
|
||||
hover.bg_hover { widget = connect_button }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local base = require("wibox.widget.base")
|
||||
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gcolor = require("gears.color")
|
||||
local gfilesystem = require("gears.filesystem")
|
||||
local gshape = require("gears.shape")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local lgi = require("lgi")
|
||||
local abutton = require('awful.button')
|
||||
local base = require('wibox.widget.base')
|
||||
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gtable = require('gears.table')
|
||||
local gtimer = require('gears.timer')
|
||||
local lgi = require('lgi')
|
||||
local NM = lgi.NM
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require('naughty')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Third party libs
|
||||
local rubato = require("src.lib.rubato")
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Local libs
|
||||
local access_point = require("src.modules.network_controller.access_point")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local access_point = require('src.modules.network_controller.access_point')
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local network = { mt = {} }
|
||||
|
||||
@@ -41,7 +42,7 @@ network.NMState = {
|
||||
|
||||
network.DeviceType = {
|
||||
ETHERNET = 1,
|
||||
WIFI = 2
|
||||
WIFI = 2,
|
||||
}
|
||||
|
||||
network.DeviceState = {
|
||||
@@ -57,7 +58,7 @@ network.DeviceState = {
|
||||
SECONDARIES = 90,
|
||||
ACTIVATED = 100,
|
||||
DEACTIVATING = 110,
|
||||
FAILED = 120
|
||||
FAILED = 120,
|
||||
}
|
||||
|
||||
---Get the wifi and or ethernet proxy and connect to their PropertiesChanged signal
|
||||
@@ -73,9 +74,9 @@ function network:get_active_device()
|
||||
--Create a new proxy for every device
|
||||
local NetworkManagerDevice = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device',
|
||||
path = path,
|
||||
}
|
||||
|
||||
--Check if the device is either a wifi or ethernet device, and if its activated
|
||||
@@ -87,92 +88,87 @@ function network:get_active_device()
|
||||
--New wifi proxy to check the bitrate
|
||||
self._private.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device.Wireless",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
|
||||
path = path,
|
||||
}
|
||||
-- Watch PropertiesChanged and update the bitrate
|
||||
local NetworkManagerDeviceWirelessProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = self._private.NetworkManagerDeviceWireless.object_path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = self._private.NetworkManagerDeviceWireless.object_path,
|
||||
}
|
||||
|
||||
NetworkManagerDeviceWirelessProperties:connect_signal(function(_, properties, data)
|
||||
if data.Bitrate then
|
||||
self:emit_signal("NM::Bitrate", data.Bitrate)
|
||||
self:emit_signal('NM::Bitrate', data.Bitrate)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
-- Watch the StateChanged signal, update and notify when a new AP is connected
|
||||
self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state)
|
||||
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.AccessPoint",
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.AccessPoint',
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
|
||||
}
|
||||
|
||||
if new_state == network.DeviceState.ACTIVATED then
|
||||
local ssid = NM.utils_ssid_to_utf8(NetworkManagerAccessPoint.Ssid)
|
||||
self:emit_signal("NM::AccessPointConnected", ssid, NetworkManagerAccessPoint.Strength)
|
||||
self:emit_signal('NM::AccessPointConnected', ssid, NetworkManagerAccessPoint.Strength)
|
||||
end
|
||||
end, "StateChanged")
|
||||
end, 'StateChanged')
|
||||
|
||||
elseif (NetworkManagerDevice.DeviceType == network.DeviceType.ETHERNET) and
|
||||
(NetworkManagerDevice.State == network.DeviceState.ACTIVATED) then
|
||||
-- Create a new ethernet device and set it as the active device
|
||||
self._private.NetworkManagerDevice = NetworkManagerDevice
|
||||
self._private.NetworkManagerDeviceWired = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Device.Wired",
|
||||
path = path
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wired',
|
||||
path = path,
|
||||
}
|
||||
|
||||
local NetworkManagerDeviceWiredProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = self._private.NetworkManagerDeviceWired.object_path
|
||||
}
|
||||
|
||||
-- Watch the PropertiesChanged signal and update the speed and carrier
|
||||
NetworkManagerDeviceWiredProperties:connect_signal(function(_, properties, data)
|
||||
if data.Speed then
|
||||
print(data.Speed)
|
||||
self:emit_signal("NM::Speed", data.Speed)
|
||||
elseif data.Carrier then
|
||||
print(data.Carrier)
|
||||
self:emit_signal("NM::Carrier", data.Carrier)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
|
||||
if self._private.NetworkManagerDevice.State == network.DeviceState.ACTIVATED then
|
||||
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
|
||||
end
|
||||
-- Connect to the StateChanged signal and notify when the wired connection is ready
|
||||
self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state)
|
||||
self._private.NetworkManagerDevice:connect_signal(function(_, new_state)
|
||||
if new_state == network.DeviceState.ACTIVATED then
|
||||
self:emit_signal("NM::EthernetActive")
|
||||
print("Ethernet active")
|
||||
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
|
||||
elseif new_state == network.DeviceState.DISCONNECTED then
|
||||
awesome.emit_signal('NM::EthernetStatus', false)
|
||||
end
|
||||
end, "StateChanged")
|
||||
end, 'StateChanged')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function network:get_active_ap_ssid()
|
||||
local d = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
|
||||
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
|
||||
}
|
||||
|
||||
return NM.utils_ssid_to_utf8(d.Ssid)
|
||||
end
|
||||
|
||||
---Scan for access points and create a widget for each one.
|
||||
function network:scan_access_points()
|
||||
if not self._private.NetworkManagerDeviceWireless then return end
|
||||
local ap_list = self:get_children_by_id("wifi_ap_list")[1]
|
||||
local ap_list = self:get_children_by_id('wifi_ap_list')[1]
|
||||
ap_list:reset()
|
||||
local ap_table = {}
|
||||
self._private.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure)
|
||||
if failure then
|
||||
naughty.notification {
|
||||
app_icon = icondir .. "ethernet.svg",
|
||||
app_name = "Network Manager",
|
||||
title = "Error: Scan failed!",
|
||||
message = "Failed to scan for access points.\n" .. failure,
|
||||
icon = gcolor.recolor_image(icondir .. "ethernet.svg", Theme_config.network.icon_color),
|
||||
app_icon = icondir .. 'ethernet.svg',
|
||||
app_name = 'Network Manager',
|
||||
title = 'Error: Scan failed!',
|
||||
message = 'Failed to scan for access points.\n' .. failure,
|
||||
icon = gcolor.recolor_image(icondir .. 'ethernet.svg', Theme_config.network.icon_color),
|
||||
timeout = 5,
|
||||
}
|
||||
return
|
||||
@@ -183,9 +179,9 @@ function network:scan_access_points()
|
||||
-- Create a new proxy for every ap
|
||||
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.AccessPoint",
|
||||
path = ap
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.AccessPoint',
|
||||
path = ap,
|
||||
}
|
||||
|
||||
-- We are only interested in those with a ssid
|
||||
@@ -216,17 +212,17 @@ function network:scan_access_points()
|
||||
NetworkManagerDevice = self._private.NetworkManagerDevice,
|
||||
NetworkManagerSettings = self._private.NetworkManagerSettings,
|
||||
NetworkManager = self._private.NetworkManager,
|
||||
NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless
|
||||
NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless,
|
||||
})
|
||||
end
|
||||
end, { call_id = "my-id" }, {})
|
||||
end, { call_id = 'my-id' }, {})
|
||||
end
|
||||
|
||||
---Toggles networking on or off
|
||||
function network:toggle_wifi()
|
||||
local enable = not self._private.NetworkManager.WirelessEnabled
|
||||
self._private.NetworkManager:Set("org.freedesktop.NetworkManager", "WirelessEnabled", lgi.GLib.Variant("b", enable))
|
||||
self._private.NetworkManager.WirelessEnabled = { signature = "b", value = enable }
|
||||
self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', enable))
|
||||
self._private.NetworkManager.WirelessEnabled = { signature = 'b', value = enable }
|
||||
end
|
||||
|
||||
function network.new(args)
|
||||
@@ -242,54 +238,54 @@ function network.new(args)
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.network_manager.wifi_icon_color),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon',
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = 'center',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "Wifi Networks",
|
||||
text = 'Wifi Networks',
|
||||
widget = wibox.widget.textbox,
|
||||
id = "ap_name"
|
||||
id = 'ap_name',
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "wifi",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
id = 'wifi',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "wifi_bg",
|
||||
id = 'wifi_bg',
|
||||
bg = Theme_config.network_manager.wifi_bg,
|
||||
fg = Theme_config.network_manager.wifi_fg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
id = "wifi_margin",
|
||||
widget = wibox.container.margin
|
||||
id = 'wifi_margin',
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
id = "wifi_list",
|
||||
id = 'wifi_list',
|
||||
{
|
||||
{
|
||||
step = dpi(50),
|
||||
spacing = dpi(10),
|
||||
layout = require("src.lib.overflow_widget.overflow").vertical,
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
id = "wifi_ap_list"
|
||||
id = 'wifi_ap_list',
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.network_manager.ap_border_color,
|
||||
border_width = Theme_config.network_manager.ap_border_width,
|
||||
@@ -297,35 +293,35 @@ function network.new(args)
|
||||
gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
forced_height = 0
|
||||
forced_height = 0,
|
||||
},
|
||||
{
|
||||
{ -- action buttons
|
||||
{
|
||||
dnd_widget {
|
||||
color = Theme_config.network_manager.power_icon_color,
|
||||
size = dpi(40)
|
||||
size = dpi(40),
|
||||
},
|
||||
id = "dnd",
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
nil,
|
||||
{ -- refresh
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. "refresh.svg",
|
||||
image = gcolor.recolor_image(icondir .. 'refresh.svg',
|
||||
Theme_config.network_manager.refresh_icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
id = 'icon',
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
id = "center",
|
||||
id = 'center',
|
||||
},
|
||||
border_width = dpi(2),
|
||||
border_color = Theme_config.network_manager.border_color,
|
||||
@@ -334,20 +330,20 @@ function network.new(args)
|
||||
end,
|
||||
bg = Theme_config.network_manager.refresh_bg,
|
||||
widget = wibox.container.background,
|
||||
id = "refresh"
|
||||
id = 'refresh',
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
id = "action_buttons"
|
||||
id = 'action_buttons',
|
||||
},
|
||||
id = "layout1",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
id = 'layout1',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(15),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
@@ -355,17 +351,19 @@ function network.new(args)
|
||||
border_color = Theme_config.network_manager.border_color,
|
||||
border_width = Theme_config.network_manager.border_width,
|
||||
bg = Theme_config.network_manager.bg,
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
id = 'background',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
width = dpi(400),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
})
|
||||
|
||||
local dnd = ret:get_children_by_id("dnd")[1]:get_widget()
|
||||
assert(type(ret) == 'table', 'NetworkManager is not running')
|
||||
|
||||
dnd:connect_signal("dnd::toggle", function(enable)
|
||||
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
|
||||
|
||||
dnd:connect_signal('dnd::toggle', function(enable)
|
||||
ret:toggle_wifi()
|
||||
end)
|
||||
|
||||
@@ -375,23 +373,23 @@ function network.new(args)
|
||||
|
||||
ret._private.NetworkManager = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager",
|
||||
path = "/org/freedesktop/NetworkManager",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager',
|
||||
path = '/org/freedesktop/NetworkManager',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerSettings = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.NetworkManager.Settings",
|
||||
path = "/org/freedesktop/NetworkManager/Settings",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.NetworkManager.Settings',
|
||||
path = '/org/freedesktop/NetworkManager/Settings',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerProperties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.freedesktop.NetworkManager",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = "/org/freedesktop/NetworkManager",
|
||||
name = 'org.freedesktop.NetworkManager',
|
||||
interface = 'org.freedesktop.DBus.Properties',
|
||||
path = '/org/freedesktop/NetworkManager',
|
||||
}
|
||||
|
||||
ret._private.NetworkManagerProperties:connect_signal(function(_, properties, data)
|
||||
@@ -404,7 +402,7 @@ function network.new(args)
|
||||
dnd:set_disabled()
|
||||
end
|
||||
|
||||
ret:emit_signal("NetworkManager::status", ret._private.WirelessEnabled)
|
||||
ret:emit_signal('NetworkManager::status', ret._private.WirelessEnabled)
|
||||
|
||||
if data.WirelessEnabled then
|
||||
gtimer {
|
||||
@@ -414,11 +412,11 @@ function network.new(args)
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
ret:scan_access_points()
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
end, 'PropertiesChanged')
|
||||
|
||||
ret:get_active_device()
|
||||
|
||||
@@ -433,9 +431,9 @@ function network.new(args)
|
||||
--#endregion
|
||||
|
||||
--#region Dropdown logic
|
||||
local wifi_margin = ret:get_children_by_id("wifi_margin")[1]
|
||||
local wifi_list = ret:get_children_by_id("wifi_list")[1]
|
||||
local wifi = ret:get_children_by_id("wifi")[1].center
|
||||
local wifi_margin = ret:get_children_by_id('wifi_margin')[1]
|
||||
local wifi_list = ret:get_children_by_id('wifi_list')[1]
|
||||
local wifi = ret:get_children_by_id('wifi')[1].center
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
@@ -443,14 +441,14 @@ function network.new(args)
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
wifi_list.forced_height = v
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
wifi_margin:buttons(gtable.join(
|
||||
abutton({}, 1, nil,
|
||||
function()
|
||||
if wifi_list.forced_height == 0 then
|
||||
if not ret:get_children_by_id("wifi_ap_list")[1].children then
|
||||
if not ret:get_children_by_id('wifi_ap_list')[1].children then
|
||||
return
|
||||
end
|
||||
local size = (5 * 49) + 1
|
||||
@@ -461,30 +459,29 @@ function network.new(args)
|
||||
wifi_margin.wifi_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
|
||||
end
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
|
||||
Theme_config.network_manager.wifi_icon_color))
|
||||
else
|
||||
rubato_timer.target = 0
|
||||
wifi_margin.wifi_bg.shape = function(cr, width, height)
|
||||
gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4))
|
||||
end
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
|
||||
wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
|
||||
Theme_config.network_manager.wifi_icon_color))
|
||||
end
|
||||
end
|
||||
)
|
||||
))
|
||||
hover.bg_hover { widget = wifi_margin.wifi_bg }
|
||||
--#endregion
|
||||
|
||||
local refresh_button = ret:get_children_by_id("refresh")[1]
|
||||
local refresh_button = ret:get_children_by_id('refresh')[1]
|
||||
refresh_button:buttons(gtable.join(
|
||||
abutton({}, 1, nil,
|
||||
function()
|
||||
ret:scan_access_points()
|
||||
end
|
||||
)
|
||||
abutton({}, 1, nil, function()
|
||||
ret:scan_access_points()
|
||||
end)
|
||||
))
|
||||
Hover_signal(refresh_button)
|
||||
hover.bg_hover { widget = refresh_button }
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -3,286 +3,303 @@
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local base = require('wibox.widget.base')
|
||||
local wibox = require('wibox')
|
||||
local apopup = require('awful.popup')
|
||||
local aplacement = require('awful.placement')
|
||||
local gshape = require('gears.shape')
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
-- Own Libs
|
||||
local dnd_widget = require('awful.widget.toggle_widget')
|
||||
local notification_list = require('src.modules.notification-center.widgets.notification_list')()
|
||||
local weather_widget = require('src.modules.notification-center.widgets.weather')()
|
||||
local profile_widget = require('src.modules.notification-center.widgets.profile')()
|
||||
local status_bars = require('src.modules.notification-center.widgets.status_bars')()
|
||||
local music_widget = require('src.modules.notification-center.widgets.song_info')()
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
return function(s)
|
||||
local capi = {
|
||||
client = client,
|
||||
}
|
||||
|
||||
local dnd = dnd_widget({
|
||||
text = "Do not disturb",
|
||||
color = Theme_config.notification_center.dnd_color,
|
||||
fg = Theme_config.notification_center.dnd_fg,
|
||||
size = dpi(40)
|
||||
})
|
||||
local instance = nil
|
||||
|
||||
dnd:get_widget():connect_signal("dnd::toggle", function(enabled)
|
||||
User_config.dnd = enabled
|
||||
end)
|
||||
local info_center = {}
|
||||
|
||||
--#region Activation area
|
||||
function info_center:toggle()
|
||||
if self.container.visible then
|
||||
self.container.visible = false
|
||||
else
|
||||
self.container.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
local activation_area = awful.popup {
|
||||
bg = '#00000000',
|
||||
widget = wibox.container.background,
|
||||
ontop = true,
|
||||
screen = s,
|
||||
type = 'dock',
|
||||
placement = function(c)
|
||||
awful.placement.top(c)
|
||||
end,
|
||||
}
|
||||
function info_center.new(args)
|
||||
args = args or {}
|
||||
|
||||
activation_area:setup({
|
||||
widget = wibox.container.background,
|
||||
forced_height = dpi(1),
|
||||
forced_width = dpi(300),
|
||||
bg = '#00000000',
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
})
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"notification_center_activation::toggle",
|
||||
function(screen, hide)
|
||||
if screen == s then
|
||||
activation_area.visible = hide
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--#endregion
|
||||
|
||||
--#region Widgets
|
||||
local nl = require("src.modules.notification-center.notification_list").notification_list
|
||||
local music_widget = require("src.modules.notification-center.song_info")()
|
||||
local time_date = require("src.modules.notification-center.time_date")()
|
||||
local weather_widget = require("src.modules.notification-center.weather")()
|
||||
local profile_widget = require("src.modules.notification-center.profile")()
|
||||
local status_bars_widget = require("src.modules.notification-center.status_bars")()
|
||||
--#endregion
|
||||
|
||||
--#region Notification buttons
|
||||
local clear_all_widget = wibox.widget { -- Clear all button
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
text = "Clear",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "clearall"
|
||||
{
|
||||
{
|
||||
{ -- Time
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
format = "<span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Bold 46'><b>%H:%M</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
{ -- Date and Day
|
||||
{ -- Date
|
||||
halign = 'left',
|
||||
valign = 'bottom',
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Regular 18'><b>%d</b></span><span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Regular 18'><b> %b %Y</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
{ -- Day
|
||||
halign = 'left',
|
||||
valign = 'top',
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Bold 20'><b>%A</b></span>",
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
bg = Theme_config.notification_center.spacing_line.color,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(2),
|
||||
strategy = 'exact',
|
||||
},
|
||||
left = dpi(60),
|
||||
right = dpi(60),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "background4",
|
||||
fg = Theme_config.notification_center.clear_all_button.fg,
|
||||
bg = Theme_config.notification_center.clear_all_button.bg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 12)
|
||||
end,
|
||||
forced_width = dpi(80),
|
||||
forced_height = dpi(40),
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin3",
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = "bottom",
|
||||
halign = "right",
|
||||
}
|
||||
|
||||
local no_notification_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = true,
|
||||
forced_height = dpi(200),
|
||||
forced_width = dpi(200),
|
||||
image = icondir .. "megamind.svg",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
},
|
||||
{
|
||||
id = "txt",
|
||||
markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "lay",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
}
|
||||
--#endregion
|
||||
|
||||
--#region Notification center
|
||||
local notification_center = awful.popup {
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.notification_center.bg,
|
||||
border_color = Theme_config.notification_center.border_color,
|
||||
border_width = Theme_config.notification_center.border_width,
|
||||
placement = function(c)
|
||||
awful.placement.top(c, { margins = dpi(10) })
|
||||
end,
|
||||
ontop = true,
|
||||
screen = s,
|
||||
visible = false,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
}
|
||||
|
||||
local function notification_center_setup()
|
||||
notification_center:setup({
|
||||
widget = notification_center,
|
||||
-- Custom widgets
|
||||
{
|
||||
time_date,
|
||||
require("src.modules.notification-center.spacingline_widget")(),
|
||||
{
|
||||
{
|
||||
weather_widget,
|
||||
{
|
||||
profile_widget,
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
status_bars_widget,
|
||||
status_bars,
|
||||
music_widget,
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
-- Notification list
|
||||
{
|
||||
{
|
||||
{
|
||||
nl,
|
||||
notification_list,
|
||||
height = dpi(680),
|
||||
strategy = "max",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
{
|
||||
no_notification_widget,
|
||||
strategy = "max",
|
||||
height = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'max',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
dnd,
|
||||
{
|
||||
{
|
||||
{
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
image = icondir .. 'megamind.svg',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'no_notification_icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(200),
|
||||
width = dpi(200),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>",
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'no_notification_text',
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
strategy = 'max',
|
||||
height = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
dnd_widget {
|
||||
text = 'Do not disturb',
|
||||
color = Theme_config.notification_center.dnd_color,
|
||||
fg = Theme_config.notification_center.dnd_fg,
|
||||
size = dpi(40),
|
||||
},
|
||||
id = 'dnd',
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
},
|
||||
nil,
|
||||
clear_all_widget,
|
||||
layout = wibox.layout.align.horizontal
|
||||
{ -- Clear all button
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
text = 'Clear',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'clear',
|
||||
},
|
||||
fg = Theme_config.notification_center.clear_all_button.fg,
|
||||
bg = Theme_config.notification_center.clear_all_button.bg,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, 12)
|
||||
end,
|
||||
id = 'clear_all_bg',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(80),
|
||||
height = dpi(40),
|
||||
strategy = 'exact',
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
valign = 'bottom', --? Needed?
|
||||
halign = 'right', --? Needed?
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
id = "layout5",
|
||||
layout = wibox.layout.align.vertical
|
||||
layout = wibox.layout.align.vertical,
|
||||
},
|
||||
id = "margin6",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "yes",
|
||||
spacing_widget = {
|
||||
{
|
||||
bg = Theme_config.notification_center.spacing_color,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
top = dpi(40),
|
||||
bottom = dpi(40),
|
||||
widget = wibox.container.margin
|
||||
thickness = dpi(2),
|
||||
color = Theme_config.notification_center.spacing_color,
|
||||
span_ratio = 0.9,
|
||||
widget = wibox.widget.separator,
|
||||
},
|
||||
spacing = dpi(1),
|
||||
forced_height = dpi(800),
|
||||
forced_width = dpi(1000),
|
||||
layout = wibox.layout.flex.horizontal
|
||||
})
|
||||
end
|
||||
spacing = dpi(2),
|
||||
layout = wibox.layout.flex.horizontal,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(800),
|
||||
width = dpi(1000),
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
--#endregion
|
||||
hover.bg_hover { widget = w:get_children_by_id('clear_all_bg')[1] }
|
||||
|
||||
--#region Signals
|
||||
-- Toggle notification_center visibility when mouse is over activation_area
|
||||
activation_area:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
notification_center.visible = true
|
||||
notification_center_setup()
|
||||
end
|
||||
)
|
||||
assert(type(w) == 'table', 'Widget creation failed')
|
||||
|
||||
-- Update the notification center popup and check if there are no notifications
|
||||
capi.awesome.connect_signal(
|
||||
"notification_center:update::needed",
|
||||
function()
|
||||
if #nl == 0 then
|
||||
math.randomseed(os.time())
|
||||
local prob = math.random(1, 10)
|
||||
notification_list:connect_signal('new_children', function()
|
||||
if #notification_list.children == 0 then
|
||||
math.randomseed(os.time())
|
||||
local prob = math.random(1, 10)
|
||||
|
||||
if (prob == 5) or (prob == 6) then
|
||||
no_notification_widget.lay.icon.image = icondir .. "megamind.svg"
|
||||
no_notification_widget.lay.txt.markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>"
|
||||
else
|
||||
no_notification_widget.lay.icon.image = icondir .. "bell-outline.svg"
|
||||
no_notification_widget.lay.txt.markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notification</span>"
|
||||
end
|
||||
no_notification_widget.visible = true
|
||||
if (prob == 5) or (prob == 6) then
|
||||
w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'megamind.svg'
|
||||
w:get_children_by_id('no_notification_text')[1].markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notifications?</span>"
|
||||
else
|
||||
no_notification_widget.visible = false
|
||||
w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'bell-outline.svg'
|
||||
w:get_children_by_id('no_notification_text')[1].markup = "<span color='#414141' font='JetBrainsMono Nerd Font, ExtraBold 20'>No Notification</span>"
|
||||
end
|
||||
notification_center_setup()
|
||||
w:get_children_by_id('no_notification_icon')[1].visible = true
|
||||
w:get_children_by_id('no_notification_text')[1].visible = true
|
||||
else
|
||||
w:get_children_by_id('no_notification_icon')[1].visible = false
|
||||
w:get_children_by_id('no_notification_text')[1].visible = false
|
||||
end
|
||||
)
|
||||
|
||||
local function mouse_leave()
|
||||
notification_center.visible = false
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal("notification_center::block_mouse_events", function()
|
||||
notification_center:disconnect_signal("mouse::leave", mouse_leave)
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("notification_center::unblock_mouse_events", function()
|
||||
notification_center:connect_signal("mouse::leave", mouse_leave)
|
||||
w:get_children_by_id('clear')[1]:connect_signal('button::press', function()
|
||||
notification_list.children = {}
|
||||
notification_list:emit_signal('new_children')
|
||||
end)
|
||||
|
||||
-- Hide notification_center when mouse leaves it
|
||||
notification_center:connect_signal(
|
||||
"mouse::leave",
|
||||
mouse_leave
|
||||
)
|
||||
w:get_children_by_id('dnd')[1]:get_widget():connect_signal('dnd::toggle', function(enabled)
|
||||
User_config.dnd = enabled
|
||||
end)
|
||||
|
||||
-- Clear all notifications on button press
|
||||
clear_all_widget:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
local size = #nl
|
||||
for i = 0, size do
|
||||
nl[i] = nil
|
||||
end
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
w.container = apopup {
|
||||
widget = w,
|
||||
bg = Theme_config.notification_center.bg,
|
||||
border_color = Theme_config.notification_center.border_color,
|
||||
border_width = Theme_config.notification_center.border_width,
|
||||
placement = function(c)
|
||||
aplacement.top(c, { margins = dpi(10) })
|
||||
end,
|
||||
ontop = true,
|
||||
screen = args.screen,
|
||||
visible = false,
|
||||
}
|
||||
|
||||
local activation_area = apopup {
|
||||
bg = gcolor.transparent,
|
||||
widget = {
|
||||
forced_height = dpi(1),
|
||||
forced_width = dpi(300),
|
||||
bg = gcolor.transparent,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
ontop = true,
|
||||
screen = args.screen,
|
||||
type = 'dock',
|
||||
placement = function(c)
|
||||
aplacement.top(c)
|
||||
end,
|
||||
}
|
||||
|
||||
capi.client.connect_signal('property::fullscreen', function(c)
|
||||
if c.fullscreen then
|
||||
activation_area.visible = false
|
||||
else
|
||||
activation_area.visible = true
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
Hover_signal(clear_all_widget.margin3.background4)
|
||||
--#endregion
|
||||
activation_area:connect_signal('mouse::enter', function()
|
||||
w.container.visible = true
|
||||
end)
|
||||
|
||||
w.container:connect_signal('mouse::leave', function()
|
||||
w.container.visible = false
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable(info_center, {
|
||||
__call = function(self, ...)
|
||||
self.new(...)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return instance
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
-------------------------------------
|
||||
-- This is the notification-center --
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
|
||||
local nl = {}
|
||||
|
||||
nl.notification_list = { layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0,
|
||||
step = dpi(100), spacing = dpi(20) }
|
||||
|
||||
-- @param {table} notification
|
||||
-- @return {widget} notifications_list
|
||||
function nl.create_notification(n)
|
||||
|
||||
n.time = os.time()
|
||||
|
||||
local time_ago_text = "- ago"
|
||||
|
||||
local timer_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
text = time_ago_text,
|
||||
widget = wibox.widget.textbox,
|
||||
id = "txt"
|
||||
},
|
||||
id = "background",
|
||||
fg = Theme_config.notification_center.notification_list.timer_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
local time_ago = math.floor(os.time() - n.time)
|
||||
local timer_text = timer_widget.background.txt
|
||||
if time_ago < 5 then
|
||||
timer_text:set_text("now")
|
||||
elseif time_ago < 60 then
|
||||
timer_text:set_text(time_ago .. "s ago")
|
||||
elseif time_ago < 3600 then
|
||||
timer_text:set_text(math.floor(time_ago / 60) .. "m ago")
|
||||
elseif time_ago < 86400 then
|
||||
timer_text:set_text(math.floor(time_ago / 3600) .. "h ago")
|
||||
else
|
||||
timer_text:set_text(math.floor(time_ago / 86400) .. "d ago")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local close_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
font = User_config.font.specify .. ", 10",
|
||||
text = "✕",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
start_angle = 4.71239,
|
||||
thickness = dpi(2),
|
||||
min_value = 0,
|
||||
max_value = 360,
|
||||
value = 360,
|
||||
widget = wibox.container.arcchart,
|
||||
id = "arc_chart"
|
||||
},
|
||||
id = "background",
|
||||
fg = Theme_config.notification_center.notification_list.close_color,
|
||||
bg = Theme_config.notification_center.notification_list.close_bg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
strategy = "exact",
|
||||
width = dpi(20),
|
||||
height = dpi(20),
|
||||
widget = wibox.container.constraint,
|
||||
id = "const"
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
local timer_close_widget = timer_widget
|
||||
|
||||
local notification = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = gears.color.recolor_image(icondir .. "notification-outline.svg",
|
||||
Theme_config.notification_center.notification_list.icon),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
markup = n.app_name or 'System Notification',
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
fg = Theme_config.notification_center.notification_list.title_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
nil,
|
||||
{
|
||||
timer_widget,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "arc_app_layout_2"
|
||||
},
|
||||
id = "arc_app_layout",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "arc_app_bg",
|
||||
border_color = Theme_config.notification_center.notification_list.title_border_color,
|
||||
border_width = Theme_config.notification_center.notification_list.title_border_width,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = n.icon,
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, 10)
|
||||
end
|
||||
},
|
||||
width = naughty.config.defaults.icon_size,
|
||||
height = naughty.config.defaults.icon_size,
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "top",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "margin01",
|
||||
left = dpi(20),
|
||||
bottom = dpi(15),
|
||||
top = dpi(15),
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = n.title,
|
||||
widget = wibox.widget.textbox,
|
||||
align = "left"
|
||||
},
|
||||
{
|
||||
markup = n.message,
|
||||
widget = wibox.widget.textbox,
|
||||
align = "left"
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
left = dpi(10),
|
||||
bottom = dpi(10),
|
||||
top = dpi(10),
|
||||
right = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "widget_layout",
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "min_size",
|
||||
strategy = "min",
|
||||
width = dpi(100),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "max_size",
|
||||
strategy = "max",
|
||||
width = Theme.notification_max_width or dpi(500),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
pk = #nl.notification_list + 1,
|
||||
bg = Theme_config.notification_center.notification_list.notification_bg,
|
||||
border_color = Theme_config.notification_center.notification_list.notification_border_color,
|
||||
border_width = Theme_config.notification_center.notification_list.notification_border_width,
|
||||
shape = Theme_config.notification_center.notification_list.notification_shape,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
close_widget:connect_signal(
|
||||
"button::press",
|
||||
function(_, _, _, button)
|
||||
if button == 1 then
|
||||
for i, b in pairs(nl.notification_list) do
|
||||
if b.pk == notification.pk then
|
||||
table.remove(nl.notification_list, math.tointeger(i))
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Hover_signal(close_widget.const.background)
|
||||
|
||||
notification:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
notification:get_children_by_id("arc_app_layout_2")[1]:set(1, close_widget)
|
||||
end
|
||||
)
|
||||
|
||||
notification:connect_signal(
|
||||
"mouse::leave",
|
||||
function()
|
||||
notification:get_children_by_id("arc_app_layout_2")[1]:set(1, timer_close_widget)
|
||||
end
|
||||
)
|
||||
|
||||
table.insert(nl.notification_list, 1, notification)
|
||||
end
|
||||
|
||||
naughty.connect_signal(
|
||||
"request::display",
|
||||
function(n)
|
||||
nl.create_notification(n)
|
||||
capi.awesome.emit_signal("notification_center:update::needed")
|
||||
end
|
||||
)
|
||||
|
||||
return nl
|
||||
@@ -1,208 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the profile widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/profile/"
|
||||
|
||||
return function()
|
||||
|
||||
local profile_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = gears.surface.load_uncached(gears.filesystem.get_configuration_dir() ..
|
||||
"src/assets/userpfp/crylia.png"),
|
||||
id = "icon",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "icon_margin",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Username
|
||||
id = "username_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "user.svg",
|
||||
Theme_config.notification_center.profile.username_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Username
|
||||
id = "username",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "os_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "laptop.svg",
|
||||
Theme_config.notification_center.profile.os_prefix_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- OS
|
||||
id = "os",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "kernel_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "penguin.svg",
|
||||
Theme_config.notification_center.profile.kernel_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Kernel
|
||||
id = "kernel",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "uptime_prefix",
|
||||
image = gears.color.recolor_image(icondir .. "clock.svg",
|
||||
Theme_config.notification_center.profile.uptime_icon_color),
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{ -- Uptime
|
||||
id = "uptime",
|
||||
valign = "center",
|
||||
align = "left",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "uptime_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
spacing = dpi(5),
|
||||
id = "info_layout",
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
id = "text_margin",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "text_container",
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "text_container_wrapper",
|
||||
widget = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "wrapper",
|
||||
fg = Theme_config.notification_center.profile.fg,
|
||||
border_color = Theme_config.notification_center.profile.border_color,
|
||||
border_width = Theme_config.notification_center.profile.border_width,
|
||||
shape = Theme_config.notification_center.profile.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "const",
|
||||
strategy = "exact",
|
||||
width = dpi(250),
|
||||
height = dpi(350),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(10),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local function get_os_name_pretty()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"cat /etc/os-release | grep -w NAME",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("os")[1].text = stdout:match("\"(.+)\"")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- function to get and set the kernel version
|
||||
local function get_kernel_version()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"uname -r",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("kernel")[1].text = stdout:match("(%d+%.%d+%.%d+)")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--function to get the username and hostname
|
||||
local function get_user_hostname()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"echo $USER@$(hostname)",
|
||||
function(stdout)
|
||||
profile_widget:get_children_by_id("username")[1].text = stdout:gsub("\n", "") or ""
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- function to fetch uptime async
|
||||
local function get_uptime()
|
||||
awful.spawn.easy_async_with_shell("uptime -p", function(stdout)
|
||||
|
||||
local hours = stdout:match("(%d+) hours") or 0
|
||||
local minutes = stdout:match("(%d+) minutes") or 0
|
||||
|
||||
profile_widget:get_children_by_id("uptime")[1].text = hours .. "h, " .. minutes .. "m"
|
||||
end)
|
||||
end
|
||||
|
||||
get_os_name_pretty()
|
||||
get_kernel_version()
|
||||
get_user_hostname()
|
||||
|
||||
gears.timer {
|
||||
timeout = 60,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = get_uptime
|
||||
}
|
||||
|
||||
return profile_widget
|
||||
|
||||
end
|
||||
@@ -1,501 +0,0 @@
|
||||
---------------------------
|
||||
-- This is the song-info --
|
||||
---------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/"
|
||||
|
||||
return function(s)
|
||||
|
||||
--#region Music control button widgets
|
||||
|
||||
local function button_hover_effect(widget, svg, color, color2)
|
||||
local mouse_enter = function()
|
||||
widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color2))
|
||||
local w = capi.mouse.current_wibox
|
||||
if w then
|
||||
w.cursor = "hand1"
|
||||
end
|
||||
end
|
||||
|
||||
local mouse_leave = function()
|
||||
widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color))
|
||||
capi.mouse.cursor = "left_ptr"
|
||||
local w = capi.mouse.current_wibox
|
||||
if w then
|
||||
w.cursor = "left_ptr"
|
||||
end
|
||||
end
|
||||
|
||||
widget:disconnect_signal("mouse::enter", mouse_enter)
|
||||
widget:connect_signal("mouse::enter", mouse_enter)
|
||||
widget:disconnect_signal("mouse::leave", mouse_leave)
|
||||
widget:connect_signal("mouse::leave", mouse_leave)
|
||||
end
|
||||
|
||||
local shuffle_button = wibox.widget {
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
}
|
||||
|
||||
local function suffle_handler()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl shuffle",
|
||||
function(stdout)
|
||||
if stdout:match("On") then
|
||||
awful.spawn.with_shell("playerctl shuffle off")
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled)
|
||||
else
|
||||
awful.spawn.with_shell("playerctl shuffle on")
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_enabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function update_shuffle()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl shuffle",
|
||||
function(stdout)
|
||||
if stdout:match("On") then
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_enabled)
|
||||
else
|
||||
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
|
||||
Theme_config.notification_center.song_info.shuffle_disabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_shuffle()
|
||||
|
||||
local repeat_button = wibox.widget {
|
||||
resize = false,
|
||||
image = gears.color.recolor_image(icondir .. "repeat.svg", Theme_config.notification_center.song_info.repeat_disabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "imagebox"
|
||||
}
|
||||
|
||||
-- On first time load set the correct loop
|
||||
local function update_loop()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl loop",
|
||||
function(stdout)
|
||||
local loop_mode = stdout:gsub("\n", "")
|
||||
if loop_mode == "Track" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_single)
|
||||
elseif loop_mode == "None" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_disabled)
|
||||
elseif loop_mode == "Playlist" then
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_loop()
|
||||
-- Activate shuffle when button is clicked
|
||||
shuffle_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, suffle_handler)))
|
||||
|
||||
local prev_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate previous song when button is clicked
|
||||
prev_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl previous && sleep 1",
|
||||
function()
|
||||
update_loop()
|
||||
end
|
||||
)
|
||||
end)
|
||||
))
|
||||
|
||||
local pause_play_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "play-pause.svg",
|
||||
Theme_config.notification_center.song_info.play_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate play/pause when button is clicked
|
||||
pause_play_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.with_shell("playerctl play-pause")
|
||||
end)
|
||||
))
|
||||
|
||||
local next_button = wibox.widget {
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "skip-next.svg", Theme_config.notification_center.song_info.next_enabled),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Activate next song when button is clicked
|
||||
next_button:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl next && sleep 1",
|
||||
function()
|
||||
update_loop()
|
||||
end
|
||||
)
|
||||
end)
|
||||
))
|
||||
|
||||
--- This function updates the repeat button svg and changes the mode on click
|
||||
local function loop_handler()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl loop",
|
||||
function(stdout)
|
||||
local loop_mode = stdout:gsub("\n", "")
|
||||
if loop_mode == "None" then
|
||||
awful.spawn.with_shell("playerctl loop playlist")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
elseif loop_mode == "Playlist" then
|
||||
awful.spawn.with_shell("playerctl loop track")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_single)
|
||||
elseif loop_mode == "Track" then
|
||||
awful.spawn.with_shell("playerctl loop none")
|
||||
repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"),
|
||||
Theme_config.notification_center.song_info.repeat_disabled)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
repeat_button:buttons(gears.table.join(awful.button({}, 1, loop_handler)))
|
||||
|
||||
button_hover_effect(prev_button, "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled,
|
||||
Theme_config.notification_center.song_info.prev_hover)
|
||||
button_hover_effect(pause_play_button, "play-pause.svg", Theme_config.notification_center.song_info.play_enabled,
|
||||
Theme_config.notification_center.song_info.play_hover)
|
||||
button_hover_effect(next_button, "skip-next.svg", Theme_config.notification_center.song_info.next_enabled,
|
||||
Theme_config.notification_center.song_info.next_hover)
|
||||
|
||||
--#endregion
|
||||
|
||||
-- Main music widget
|
||||
local music_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Album art
|
||||
{
|
||||
image = icondir .. "default_image.svg",
|
||||
resize = true,
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "imagebox"
|
||||
},
|
||||
width = dpi(80),
|
||||
height = dpi(80),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint,
|
||||
id = "const"
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Title
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox4"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.title_fg,
|
||||
id = "textbox5",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "textbox_const",
|
||||
strategy = "max",
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = "textbox_container4",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Artist
|
||||
halign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox3"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.artist_fg,
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
strategy = "max",
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
id = "artist_container",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ --Buttons
|
||||
{
|
||||
{
|
||||
shuffle_button,
|
||||
prev_button,
|
||||
pause_play_button,
|
||||
next_button,
|
||||
repeat_button,
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "layout5"
|
||||
},
|
||||
halign = "center",
|
||||
widget = wibox.container.place,
|
||||
id = "place2"
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
id = "margin6"
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
id = "layout4"
|
||||
},
|
||||
fill_space = true,
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "layout3"
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
id = "margin5"
|
||||
},
|
||||
{ --Song Duration
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = "0:00",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "textbox2"
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
id = "background3"
|
||||
},
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
id = "margin4"
|
||||
},
|
||||
{ -- Progressbar
|
||||
{
|
||||
color = Theme_config.notification_center.song_info.progress_color,
|
||||
background_color = Theme_config.notification_center.song_info.progress_background_color,
|
||||
max_value = 100,
|
||||
value = 50,
|
||||
forced_height = dpi(5),
|
||||
shape = function(cr, width)
|
||||
gears.shape.rounded_bar(cr, width, dpi(5))
|
||||
end,
|
||||
widget = wibox.widget.progressbar,
|
||||
id = "progressbar1"
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place,
|
||||
id = "place1"
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
text = "00:00",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "text1"
|
||||
},
|
||||
id = "background2",
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin3",
|
||||
left = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = "layout2",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "layout1",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
id = "margin2",
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10)
|
||||
},
|
||||
id = "background1",
|
||||
border_color = Theme_config.notification_center.song_info.border_color,
|
||||
border_width = Theme_config.notification_center.song_info.border_width,
|
||||
shape = Theme_config.notification_center.song_info.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin1",
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(20)
|
||||
}
|
||||
|
||||
-- Used to check if the music changed and if everthing should be updated
|
||||
local trackid = ""
|
||||
local artist = ""
|
||||
local title = ""
|
||||
|
||||
-- Function to get spotify title, artist, album, album_art, length and track_id
|
||||
local function get_spotify_metadata(skip_check)
|
||||
skip_check = skip_check or false
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata",
|
||||
function(stdout)
|
||||
-- Only fetch info if the track changed or if the title/artist is empty
|
||||
if skip_check or (not stdout:match(trackid)) or (not stdout:match(artist)) or (not stdout:match(title)) then
|
||||
-- Get the song title
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata xesam:title",
|
||||
function(stdout2)
|
||||
local tit = stdout2:gsub("\n", "")
|
||||
title = tit
|
||||
music_widget:get_children_by_id("textbox4")[1].text = tit
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the song artist
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata xesam:artist",
|
||||
function(stdout2)
|
||||
local art = stdout2:gsub("\n", "")
|
||||
artist = art
|
||||
music_widget:get_children_by_id("textbox3")[1].text = art
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the song album image
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:artUrl",
|
||||
function(album_art)
|
||||
local url = album_art:gsub("\n", "")
|
||||
awful.spawn.easy_async_with_shell(
|
||||
-- TODO: curl does not stdout and is returns before it finished. This causes the image to sometimes not show correctly.
|
||||
-- !Find a better solution than sleep 0.1
|
||||
-- Maybe cache the image? Not sure if that would be a waste of space or not.
|
||||
"curl -s " .. url .. " -o /tmp/album_art.jpg && echo /tmp/album_art.jpg && sleep 0.5",
|
||||
function()
|
||||
music_widget:get_children_by_id("imagebox")[1].image = gears.surface.load_uncached("/tmp/album_art.jpg")
|
||||
or icondir .. "default_image.svg"
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
-- Get the length of the song
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:length",
|
||||
function(stdout2)
|
||||
local length = stdout2:gsub("\n", "")
|
||||
if length ~= "" then
|
||||
local length_formated = string.format("%02d:%02d", math.floor((tonumber(length) or 1) / 60000000) or 0,
|
||||
(math.floor((tonumber(length) or 1) / 1000000) % 60) or 0)
|
||||
music_widget:get_children_by_id("progressbar1")[1].max_value = tonumber(math.floor(tonumber(length) /
|
||||
1000000))
|
||||
music_widget:get_children_by_id("text1")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
|
||||
, Theme_config.notification_center.song_info.duration_fg, length_formated)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl metadata mpris:trackid",
|
||||
function(stdout2)
|
||||
trackid = stdout2:gsub("\n", "")
|
||||
end
|
||||
)
|
||||
-- Update track id
|
||||
trackid, artist, title = stdout, music_widget:get_children_by_id("textbox3")[1].text,
|
||||
music_widget:get_children_by_id("textbox4")[1].text
|
||||
end
|
||||
)
|
||||
-- Always update the current song progression
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"playerctl position",
|
||||
function(stdout)
|
||||
local time = stdout:gsub("\n", "")
|
||||
if time ~= "" then
|
||||
local time_formated = string.format("%02d:%02d", math.floor((tonumber(time) or 1) / 60),
|
||||
math.floor(tonumber(time) or 1) % 60)
|
||||
music_widget:get_children_by_id("textbox2")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
|
||||
, Theme_config.notification_center.song_info.duration_fg, time_formated)
|
||||
music_widget:get_children_by_id("progressbar1")[1].value = tonumber(time)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Call every second, if performance is bad, set the timer to a higher value
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
--!Rewrite entire playerctl module for better performance
|
||||
--get_spotify_metadata()
|
||||
end
|
||||
}
|
||||
|
||||
-- get_spotify_metadata() on awesome reload
|
||||
capi.awesome.connect_signal("startup", function()
|
||||
get_spotify_metadata(true)
|
||||
end)
|
||||
|
||||
return music_widget
|
||||
end
|
||||
@@ -1,22 +0,0 @@
|
||||
------------------------------------------------
|
||||
-- This is the spacing widget under the clock --
|
||||
------------------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
|
||||
return function()
|
||||
|
||||
return wibox.widget {
|
||||
{
|
||||
forced_height = dpi(2),
|
||||
bg = Theme_config.notification_center.spacing_line.color,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
left = dpi(80),
|
||||
right = dpi(80),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
end
|
||||
@@ -1,840 +0,0 @@
|
||||
------------------------------------
|
||||
-- This is the status_bars widget --
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local rubato = require("src.lib.rubato")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/"
|
||||
|
||||
--- Signal bars widget for the notification-center
|
||||
---@diagnostic disable-next-line: undefined-doc-name
|
||||
---@return wibox.widget
|
||||
return function()
|
||||
|
||||
---Creates a layout with bar widgets based on the given table
|
||||
---@param widget_table table
|
||||
---@return table
|
||||
local function create_bar_layout(widget_table)
|
||||
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
|
||||
|
||||
for _, widget in pairs(widget_table) do
|
||||
local w
|
||||
if widget == "cpu_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/cpu.svg",
|
||||
Theme_config.notification_center.status_bar.cpu_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon1",
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "cpu_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"update::cpu_usage",
|
||||
function(cpu_usage)
|
||||
tooltip.text = "CPU Usage: " .. cpu_usage .. "%"
|
||||
rubato_timer.target = cpu_usage
|
||||
end
|
||||
)
|
||||
elseif widget == "cpu_temp" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_temp_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg",
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "cpu_temp_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::cpu_temp",
|
||||
function(cpu_temp)
|
||||
local temp_icon
|
||||
if cpu_temp < 50 then
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
elseif cpu_temp >= 50 and cpu_temp < 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer.svg"
|
||||
elseif cpu_temp >= 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer-high.svg"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color)
|
||||
tooltip.text = "CPU Temp: " .. cpu_temp .. "°C"
|
||||
rubato_timer.target = cpu_temp
|
||||
end
|
||||
)
|
||||
elseif widget == "ram_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.ram_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/ram.svg",
|
||||
Theme_config.notification_center.status_bar.ram_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "ram_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::ram_widget",
|
||||
function(MemTotal, _, MemAvailable)
|
||||
if not MemTotal or not MemAvailable then
|
||||
return
|
||||
end
|
||||
local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
|
||||
tooltip.text = "RAM Usage: " .. ram_usage .. "%"
|
||||
rubato_timer.target = ram_usage
|
||||
end
|
||||
)
|
||||
elseif widget == "gpu_usage" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.gpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
image = gears.color.recolor_image(icondir .. "cpu/gpu.svg",
|
||||
Theme_config.notification_center.status_bar.gpu_usage_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "gpu_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_usage",
|
||||
function(gpu_usage)
|
||||
if not gpu_usage then return end
|
||||
tooltip.text = "GPU Usage: " .. gpu_usage .. "%"
|
||||
rubato_timer.target = tonumber(gpu_usage)
|
||||
end
|
||||
)
|
||||
elseif widget == "gpu_temp" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.gpu_temp_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg",
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "gpu_temp_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_temp",
|
||||
function(gpu_temp)
|
||||
local temp_icon
|
||||
local temp_num = tonumber(gpu_temp) or "NaN"
|
||||
|
||||
if temp_num then
|
||||
|
||||
if temp_num < 50 then
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer.svg"
|
||||
elseif temp_num >= 80 then
|
||||
temp_icon = icondir .. "cpu/thermometer-high.svg"
|
||||
end
|
||||
else
|
||||
temp_num = "NaN"
|
||||
temp_icon = icondir .. "cpu/thermometer-low.svg"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color)
|
||||
tooltip.text = "GPU Temp: " .. temp_num .. "°C"
|
||||
rubato_timer.target = temp_num
|
||||
end
|
||||
)
|
||||
elseif widget == "volume" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.volume_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "audio/volume-high.svg",
|
||||
Theme_config.notification_center.status_bar.volume_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "volume_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"audio::get",
|
||||
function(muted, volume)
|
||||
local icon = icondir .. "audio/volume"
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted then
|
||||
icon = icon .. "-mute"
|
||||
else
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.volume_color)
|
||||
tooltip.text = "Volume: " .. volume .. "%"
|
||||
rubato_timer.target = volume
|
||||
end
|
||||
)
|
||||
elseif widget == "microphone" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.microphone_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "audio/microphone.svg",
|
||||
Theme_config.notification_center.status_bar.microphone_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "microphone_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"microphone::get",
|
||||
function(muted, volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. "audio/microphone"
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted or (volume < 1) then
|
||||
icon = icon .. "-off"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.microphone_color)
|
||||
tooltip.text = "Microphone: " .. volume .. "%"
|
||||
rubato_timer.target = volume
|
||||
end
|
||||
)
|
||||
elseif widget == "backlight" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.backlight_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "brightness/brightness-high.svg",
|
||||
Theme_config.notification_center.status_bar.backlight_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "brightness_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"brightness::get",
|
||||
function(brightness)
|
||||
local icon = icondir .. "brightness"
|
||||
if brightness >= 0 and brightness < 34 then
|
||||
icon = icon .. "-low"
|
||||
elseif brightness >= 34 and brightness < 67 then
|
||||
icon = icon .. "-medium"
|
||||
elseif brightness >= 67 then
|
||||
icon = icon .. "-high"
|
||||
end
|
||||
w:get_children_by_id("icon1")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
|
||||
Theme_config.notification_center.status_bar.backlight_color))
|
||||
tooltip.text = "Backlight: " .. brightness .. "%"
|
||||
rubato_timer.target = brightness
|
||||
end
|
||||
)
|
||||
elseif widget == "battery" then
|
||||
w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.battery_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = "progressbar1",
|
||||
widget = wibox.widget.progressbar
|
||||
},
|
||||
id = "background1",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background2",
|
||||
forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
forced_width = dpi(24),
|
||||
direction = "east",
|
||||
widget = wibox.container.rotate
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = "icon1",
|
||||
image = gears.color.recolor_image(icondir .. "battery/battery.svg",
|
||||
Theme_config.notification_center.status_bar.battery_color),
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
id = "background3",
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
id = "battery_layout",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
local bar = w:get_children_by_id("progressbar1")[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
}
|
||||
w:connect_signal("mouse::enter", function()
|
||||
capi.awesome.emit_signal("notification_center::block_mouse_events")
|
||||
end)
|
||||
|
||||
w:connect_signal("mouse::leave", function()
|
||||
capi.awesome.emit_signal("notification_center::unblock_mouse_events")
|
||||
end)
|
||||
capi.awesome.connect_signal(
|
||||
"update::battery_widget",
|
||||
function(battery, battery_icon)
|
||||
w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(battery_icon,
|
||||
Theme_config.notification_center.status_bar.battery_color)
|
||||
tooltip.text = "Battery: " .. battery .. "%"
|
||||
rubato_timer.target = battery
|
||||
end
|
||||
)
|
||||
end
|
||||
table.insert(bar_layout, w)
|
||||
end
|
||||
|
||||
return bar_layout
|
||||
end
|
||||
|
||||
local signal_bars = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
create_bar_layout(User_config.status_bar_widgets),
|
||||
width = dpi(480),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
magins = dpi(10),
|
||||
layout = wibox.container.margin
|
||||
},
|
||||
forced_height = dpi(120),
|
||||
forced_width = dpi(500),
|
||||
border_color = Theme_config.notification_center.status_bar.border_color,
|
||||
border_width = Theme_config.notification_center.status_bar.border_width,
|
||||
shape = Theme_config.notification_center.status_bar.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
top = dpi(10),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
return signal_bars
|
||||
|
||||
end
|
||||
@@ -1,65 +0,0 @@
|
||||
----------------------------------
|
||||
-- This is the time_date widget --
|
||||
----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local wibox = require("wibox")
|
||||
|
||||
return function()
|
||||
|
||||
local time_date = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Time
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
format = "<span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Bold 46'><b>%H:%M</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{ -- Date and Day
|
||||
{ -- Date
|
||||
{
|
||||
id = "label",
|
||||
align = "left",
|
||||
valign = "bottom",
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Regular 18'><b>%d</b></span><span foreground='#18FFFF' font='JetBrainsMono Nerd Font, Regular 18'><b> %b %Y</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{ -- Day
|
||||
{
|
||||
id = "label",
|
||||
align = "left",
|
||||
valign = "top",
|
||||
format = "<span foreground='#69F0AE' font='JetBrainsMono Nerd Font, Bold 20'><b>%A</b></span>",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
spacing = dpi(20),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin",
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
return time_date
|
||||
|
||||
end
|
||||
@@ -1,224 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the weather widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local json_lua = require("src.lib.json-lua.json-lua")
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/weather/"
|
||||
|
||||
return function()
|
||||
|
||||
local api_secrets = {
|
||||
key = User_config.weather_secrets.key,
|
||||
city_id = User_config.weather_secrets.city_id,
|
||||
unit = User_config.weather_secrets.unit
|
||||
}
|
||||
|
||||
local weather_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = "center",
|
||||
align = "center",
|
||||
resize = true,
|
||||
forced_width = dpi(64),
|
||||
forced_height = dpi(64),
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
},
|
||||
id = "place2",
|
||||
valing = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{ -- Temperature
|
||||
text = "0°C",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
font = "JetBrains Mono Bold 24",
|
||||
id = "temp"
|
||||
},
|
||||
{ -- City, Country
|
||||
text = "City, Country",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "city_country",
|
||||
},
|
||||
{
|
||||
{ -- Description
|
||||
text = "Description",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "description"
|
||||
},
|
||||
fg = Theme_config.notification_center.weather.description_fg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
{ -- line
|
||||
forced_height = dpi(4),
|
||||
forced_width = dpi(10),
|
||||
bg = Theme_config.notification_center.weather.line_bg,
|
||||
widget = wibox.container.background,
|
||||
id = "line"
|
||||
},
|
||||
{
|
||||
{ -- Speed
|
||||
{
|
||||
image = gears.color.recolor_image(icondir .. "weather-windy.svg",
|
||||
Theme_config.notification_center.weather.speed_icon_color),
|
||||
resize = true,
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{
|
||||
text = "",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "speed"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "layout3",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "place4",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
{
|
||||
{ -- Humidity
|
||||
{
|
||||
forced_width = dpi(24),
|
||||
forced_height = dpi(24),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "humidity.svg",
|
||||
Theme_config.notification_center.weather.humidity_icon_color),
|
||||
id = "humidity_icon"
|
||||
},
|
||||
{
|
||||
text = "",
|
||||
valign = "center",
|
||||
align = "center",
|
||||
widget = wibox.widget.textbox,
|
||||
id = "humidity"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
id = "layoutHum",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "lyt",
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = "center",
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
id = "background",
|
||||
border_color = Theme_config.notification_center.weather.border_color,
|
||||
border_width = Theme_config.notification_center.weather.border_width,
|
||||
shape = Theme_config.notification_center.weather.shape,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
id = "margin",
|
||||
top = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(10),
|
||||
bottom = dpi(10),
|
||||
forced_width = dpi(250),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local function fetch_weather_data()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" ..
|
||||
api_secrets.city_id .. "&units=" .. api_secrets.unit .. "&appid=" .. api_secrets.key .. "'",
|
||||
function(stdout)
|
||||
if not stdout:match('error') then
|
||||
local weather_metadata = json_lua:decode(stdout)
|
||||
if weather_metadata then
|
||||
local temp = weather_metadata.main.temp
|
||||
local humidity = weather_metadata.main.humidity
|
||||
local city = weather_metadata.name
|
||||
local country = weather_metadata.sys.country
|
||||
local weather_icon = weather_metadata.weather[1].icon
|
||||
local description = weather_metadata.weather[1].description
|
||||
local speed = weather_metadata.wind.speed
|
||||
|
||||
local icon_table = {
|
||||
["01d"] = "weather-sunny",
|
||||
["01n"] = "weather-clear-night",
|
||||
["02d"] = "weather-partly-cloudy",
|
||||
["02n"] = "weather-night-partly-cloudy",
|
||||
["03d"] = "weather-cloudy",
|
||||
["03n"] = "weather-clouds-night",
|
||||
["04d"] = "weather-cloudy",
|
||||
["04n"] = "weather-cloudy",
|
||||
["09d"] = "weather-rainy",
|
||||
["09n"] = "weather-rainy",
|
||||
["10d"] = "weather-partly-rainy",
|
||||
["10n"] = "weather-partly-rainy",
|
||||
["11d"] = "weather-pouring",
|
||||
["11n"] = "weather-pouring",
|
||||
["13d"] = "weather-snowy",
|
||||
["13n"] = "weather-snowy",
|
||||
["50d"] = "weather-fog",
|
||||
["50n"] = "weather-fog"
|
||||
}
|
||||
|
||||
weather_widget:get_children_by_id("icon")[1].image = icondir .. icon_table[weather_icon] .. ".svg"
|
||||
weather_widget:get_children_by_id("temp")[1].text = math.floor(temp + 0.5) .. "°C"
|
||||
weather_widget:get_children_by_id("city_country")[1].text = city .. ", " .. country
|
||||
weather_widget:get_children_by_id("description")[1].text = description:sub(1, 1):upper() ..
|
||||
description:sub(2)
|
||||
weather_widget:get_children_by_id("line")[1].bg = Theme_config.notification_center.weather.line_color
|
||||
weather_widget:get_children_by_id("speed")[1].text = speed .. " m/s"
|
||||
weather_widget:get_children_by_id("humidity")[1].text = humidity .. "%"
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
fetch_weather_data()
|
||||
|
||||
gears.timer {
|
||||
timeout = 900,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
fetch_weather_data()
|
||||
end
|
||||
}
|
||||
|
||||
return weather_widget
|
||||
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
-------------------------------------
|
||||
-- This is the notification-center --
|
||||
-------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local naughty = require('naughty')
|
||||
local gtimer = require('gears.timer')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
return setmetatable({}, {
|
||||
__call = function()
|
||||
local ret = wibox.widget {
|
||||
layout = require('src.lib.overflow_widget.overflow').vertical,
|
||||
scrollbar_width = 0,
|
||||
step = dpi(100),
|
||||
spacing = dpi(20),
|
||||
}
|
||||
|
||||
--!No, :get_children_by_id() does not work here for some reason, yes I hate it too
|
||||
--[[ naughty.connect_signal('notification_surface', function(b)
|
||||
local start_time = os.time()
|
||||
local w = wibox.template.make_from_value(b)
|
||||
w = w:get_widget()
|
||||
assert(type(w) == 'table', 'w is not a wibox.widget.base')
|
||||
|
||||
-- Change the clock to a timer how long ago the notification was created
|
||||
w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1] = wibox.widget {
|
||||
text = 'now',
|
||||
font = 'JetBrainsMono Nerd Font, Bold 12',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1] }
|
||||
w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2]:connect_signal('button::press', function()
|
||||
ret:remove_widgets(w)
|
||||
ret:emit_signal('new_children')
|
||||
end)
|
||||
|
||||
gtimer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
local time_ago = math.floor(os.time() - start_time)
|
||||
local timer_text = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1]
|
||||
if time_ago < 5 then
|
||||
timer_text:set_text('now')
|
||||
elseif time_ago < 60 then
|
||||
timer_text:set_text(time_ago .. 's ago')
|
||||
elseif time_ago < 3600 then
|
||||
timer_text:set_text(math.floor(time_ago / 60) .. 'm ago')
|
||||
elseif time_ago < 86400 then
|
||||
timer_text:set_text(math.floor(time_ago / 3600) .. 'h ago')
|
||||
else
|
||||
timer_text:set_text(math.floor(time_ago / 86400) .. 'd ago')
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
ret:add(w)
|
||||
ret:emit_signal('new_children')
|
||||
end) ]]
|
||||
|
||||
return ret
|
||||
end,
|
||||
})
|
||||
174
awesome/src/modules/notification-center/widgets/profile.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
--------------------------------
|
||||
-- This is the profile widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local aspawn = require('awful.spawn')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gshape = require('gears.shape')
|
||||
local gsurface = require('gears.surface')
|
||||
local gtimer = require('gears.timer')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/profile/'
|
||||
|
||||
local instance = nil
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable({}, { __call = function()
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png'),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
clip_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Username
|
||||
image = gcolor.recolor_image(icondir .. 'user.svg',
|
||||
Theme_config.notification_center.profile.username_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Username
|
||||
id = 'username',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'laptop.svg',
|
||||
Theme_config.notification_center.profile.os_prefix_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- OS
|
||||
id = 'os',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'penguin.svg',
|
||||
Theme_config.notification_center.profile.kernel_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Kernel
|
||||
id = 'kernel',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'clock.svg',
|
||||
Theme_config.notification_center.profile.uptime_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
resize = false,
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{ -- Uptime
|
||||
id = 'uptime',
|
||||
valign = 'center',
|
||||
halign = 'left',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.layout.fixed.vertical,
|
||||
},
|
||||
fg = Theme_config.notification_center.profile.fg,
|
||||
border_color = Theme_config.notification_center.profile.border_color,
|
||||
border_width = Theme_config.notification_center.profile.border_width,
|
||||
shape = Theme_config.notification_center.profile.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'exact',
|
||||
width = dpi(250),
|
||||
height = dpi(350),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(10),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
aspawn.easy_async_with_shell('cat /etc/os-release | grep -w NAME', function(stdout)
|
||||
w:get_children_by_id('os')[1].text = stdout:match('\"(.+)\"')
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell('uname -r', function(stdout)
|
||||
w:get_children_by_id('kernel')[1].text = stdout:match('(%d+%.%d+%.%d+)')
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell('echo $USER@$(hostname)', function(stdout)
|
||||
w:get_children_by_id('username')[1].text = stdout:gsub('\n', '') or ''
|
||||
end)
|
||||
|
||||
gtimer {
|
||||
timeout = 60,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
aspawn.easy_async_with_shell('uptime -p', function(stdout)
|
||||
local hours = stdout:match('(%d+) hours') or 0
|
||||
local minutes = stdout:match('(%d+) minutes') or 0
|
||||
w:get_children_by_id('uptime')[1].text = hours .. 'h, ' .. minutes .. 'm'
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
return w
|
||||
end, })
|
||||
end
|
||||
|
||||
return instance
|
||||
241
awesome/src/modules/notification-center/widgets/song_info.lua
Normal file
@@ -0,0 +1,241 @@
|
||||
---------------------------
|
||||
-- This is the song-info --
|
||||
---------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
local gshape = require('gears.shape')
|
||||
local base = require('wibox.widget.base')
|
||||
local abutton = require('awful.button')
|
||||
|
||||
local mh = require('src.tools.helpers.playerctl')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
local music_player = {}
|
||||
|
||||
return setmetatable({}, { __call = function()
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Album art
|
||||
{
|
||||
image = icondir .. 'default_image.svg',
|
||||
resize = true,
|
||||
clip_shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'album_art',
|
||||
},
|
||||
width = dpi(80),
|
||||
height = dpi(80),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Title
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
text = 'Unknown Title',
|
||||
id = 'title',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.title_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'max',
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Artist
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
id = 'artist',
|
||||
text = 'Unknown Artist',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.artist_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
strategy = 'max',
|
||||
width = dpi(400),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{ --Buttons
|
||||
{
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'shuffle.svg',
|
||||
Theme_config.notification_center.song_info.shuffle_disabled),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'shuffle',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'prev',
|
||||
image = gcolor.recolor_image(icondir .. 'skip-prev.svg', Theme_config.notification_center.song_info.prev_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'play_pause',
|
||||
image = gcolor.recolor_image(icondir .. 'play-pause.svg',
|
||||
Theme_config.notification_center.song_info.play_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'next',
|
||||
image = gcolor.recolor_image(icondir .. 'skip-next.svg', Theme_config.notification_center.song_info.next_enabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
resize = false,
|
||||
image = gcolor.recolor_image(icondir .. 'repeat.svg', Theme_config.notification_center.song_info.repeat_disabled),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'repeat',
|
||||
},
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
layout = wibox.layout.flex.vertical,
|
||||
},
|
||||
fill_space = true,
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ --Song Duration
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'position',
|
||||
text = '00:00',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
right = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{ -- Progressbar
|
||||
{
|
||||
color = Theme_config.notification_center.song_info.progress_color,
|
||||
background_color = Theme_config.notification_center.song_info.progress_background_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
id = 'progress',
|
||||
forced_height = dpi(5),
|
||||
shape = function(cr, width)
|
||||
gshape.rounded_bar(cr, width, dpi(5))
|
||||
end,
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'length',
|
||||
text = '00:00',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
fg = Theme_config.notification_center.song_info.duration_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
left = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
},
|
||||
border_color = Theme_config.notification_center.song_info.border_color,
|
||||
border_width = Theme_config.notification_center.song_info.border_width,
|
||||
shape = Theme_config.notification_center.song_info.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
bottom = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
}
|
||||
assert(type(w) == 'table', 'Widget must be a table')
|
||||
|
||||
gtable.crush(w, music_player, true)
|
||||
|
||||
local music_handler = mh(w)
|
||||
|
||||
--#region Buttons
|
||||
w:get_children_by_id('play_pause')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:play_pause()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('next')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:next()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('prev')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:prev()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('repeat')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:set_loop_status()
|
||||
end)
|
||||
))
|
||||
|
||||
w:get_children_by_id('shuffle')[1]:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
music_handler:set_shuffle()
|
||||
end)
|
||||
))
|
||||
--#endregion
|
||||
return w
|
||||
end, })
|
||||
266
awesome/src/modules/notification-center/widgets/status_bars.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
------------------------------------
|
||||
-- This is the status_bars widget --
|
||||
------------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
local base = require('wibox.widget.base')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
-- Own Libs
|
||||
local audio = require('src.tools.helpers.audio')
|
||||
local backlight = require('src.tools.helpers.backlight')
|
||||
--local battery = require('src.tools.helpers.battery')
|
||||
local cpu_usage = require('src.tools.helpers.cpu_usage')
|
||||
local cpu_temp = require('src.tools.helpers.cpu_temp')
|
||||
local ram = require('src.tools.helpers.ram')
|
||||
local gpu_usage = require('src.tools.helpers.gpu_usage')
|
||||
local gpu_temp = require('src.tools.helpers.gpu_temp')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/'
|
||||
|
||||
return setmetatable({}, { __call = function()
|
||||
|
||||
---Creates a layout with bar widgets based on the given table
|
||||
---@param widget_table table
|
||||
---@return table
|
||||
local function create_bar_layout(widget_table)
|
||||
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
|
||||
|
||||
for _, widget in pairs(widget_table) do
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
{ --Bar
|
||||
color = Theme_config.notification_center.status_bar.cpu_usage_color,
|
||||
background_color = Theme_config.notification_center.status_bar.bar_bg_color,
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
forced_height = dpi(8),
|
||||
shape = function(cr)
|
||||
gears.shape.rounded_bar(cr, dpi(58), dpi(8))
|
||||
end,
|
||||
id = 'progress_role',
|
||||
widget = wibox.widget.progressbar,
|
||||
},
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
direction = 'east',
|
||||
widget = wibox.container.rotate,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
|
||||
width = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{ --Icon
|
||||
id = 'image_role',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
height = dpi(24),
|
||||
width = dpi(24),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
}
|
||||
|
||||
assert(type(w) == 'table', 'Widget creation failed')
|
||||
|
||||
local bar = w:get_children_by_id('progress_role')[1]
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 1,
|
||||
pos = bar.value,
|
||||
easing = rubato.linear,
|
||||
subscribed = function(v)
|
||||
bar.value = v
|
||||
end,
|
||||
}
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { w },
|
||||
mode = 'inside',
|
||||
preferred_alignments = 'middle',
|
||||
margins = dpi(10),
|
||||
}
|
||||
|
||||
if widget == 'cpu_usage' then
|
||||
cpu_usage:connect_signal('update::cpu_usage', function(_, v)
|
||||
tooltip.text = 'CPU Usage: ' .. v .. '%'
|
||||
rubato_timer.target = v
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg',
|
||||
Theme_config.notification_center.status_bar.cpu_usage_color)
|
||||
end)
|
||||
elseif widget == 'cpu_temp' then
|
||||
cpu_temp:connect_signal('update::cpu_temp', function(_, v)
|
||||
local temp_icon
|
||||
if v < 50 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
elseif v >= 50 and v < 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer.svg'
|
||||
elseif v >= 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-high.svg'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.cpu_temp_color)
|
||||
tooltip.text = 'CPU Temp: ' .. v .. '°C'
|
||||
rubato_timer.target = v
|
||||
end)
|
||||
elseif widget == 'ram_usage' then
|
||||
ram:connect_signal('update::ram_widget', function(_, MemTotal, _, MemAvailable)
|
||||
if not MemTotal or not MemAvailable then return end
|
||||
local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
|
||||
tooltip.text = 'RAM Usage: ' .. ram_usage .. '%'
|
||||
rubato_timer.target = ram_usage
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/ram.svg',
|
||||
Theme_config.notification_center.status_bar.ram_usage_color)
|
||||
end)
|
||||
elseif widget == 'gpu_usage' then
|
||||
gpu_usage:connect_signal('update::gpu_usage', function(_, v)
|
||||
if not v then return end
|
||||
tooltip.text = 'GPU Usage: ' .. v .. '%'
|
||||
rubato_timer.target = tonumber(v)
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/gpu.svg',
|
||||
Theme_config.notification_center.status_bar.gpu_usage_color)
|
||||
end)
|
||||
elseif widget == 'gpu_temp' then
|
||||
gpu_temp:connect_signal('update::gpu_temp', function(_, v)
|
||||
local temp_icon, temp_num
|
||||
|
||||
if v then
|
||||
temp_num = tonumber(v)
|
||||
if temp_num < 50 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer.svg'
|
||||
elseif temp_num >= 80 then
|
||||
temp_icon = icondir .. 'cpu/thermometer-high.svg'
|
||||
end
|
||||
else
|
||||
temp_num = 'NaN'
|
||||
temp_icon = icondir .. 'cpu/thermometer-low.svg'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
|
||||
Theme_config.notification_center.status_bar.gpu_temp_color)
|
||||
tooltip.text = 'GPU Temp: ' .. temp_num .. '°C'
|
||||
rubato_timer.target = temp_num
|
||||
end)
|
||||
elseif widget == 'volume' then
|
||||
audio:connect_signal('sink::get', function(_, muted, volume)
|
||||
local icon = icondir .. 'audio/volume'
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted then
|
||||
icon = icon .. '-mute'
|
||||
else
|
||||
if volume < 1 then
|
||||
icon = icon .. '-mute'
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.volume_color)
|
||||
tooltip.text = 'Volume: ' .. volume .. '%'
|
||||
rubato_timer.target = volume
|
||||
end)
|
||||
elseif widget == 'microphone' then
|
||||
audio:connect_signal('source::get', function(_, muted, volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
local icon = icondir .. 'audio/microphone'
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if muted or (volume < 1) then
|
||||
icon = icon .. '-off'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.microphone_color)
|
||||
tooltip.text = 'Microphone: ' .. volume .. '%'
|
||||
rubato_timer.target = volume
|
||||
end)
|
||||
elseif widget == 'backlight' then
|
||||
backlight:connect_signal('brightness::get', function(_, v)
|
||||
local icon = icondir .. 'brightness'
|
||||
if v >= 0 and v < 34 then
|
||||
icon = icon .. '-low'
|
||||
elseif v >= 34 and v < 67 then
|
||||
icon = icon .. '-medium'
|
||||
elseif v >= 67 then
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon .. '.svg',
|
||||
Theme_config.notification_center.status_bar.backlight_color))
|
||||
tooltip.text = 'Backlight: ' .. v .. '%'
|
||||
rubato_timer.target = v
|
||||
end)
|
||||
elseif widget == 'battery' then
|
||||
--[[ battery:connect_signal('update::battery_widget', function(battery, battery_icon)
|
||||
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(battery_icon,
|
||||
Theme_config.notification_center.status_bar.battery_color)
|
||||
tooltip.text = 'Battery: ' .. battery .. '%'
|
||||
rubato_timer.target = battery
|
||||
end) ]]
|
||||
end
|
||||
table.insert(bar_layout, w)
|
||||
end
|
||||
|
||||
return bar_layout
|
||||
end
|
||||
|
||||
return wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
create_bar_layout(User_config.status_bar_widgets),
|
||||
width = dpi(480),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
magins = dpi(10),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
border_color = Theme_config.notification_center.status_bar.border_color,
|
||||
border_width = Theme_config.notification_center.status_bar.border_width,
|
||||
shape = Theme_config.notification_center.status_bar.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(120),
|
||||
width = dpi(500),
|
||||
strategy = 'exact',
|
||||
},
|
||||
top = dpi(10),
|
||||
left = dpi(20),
|
||||
right = dpi(20),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
}
|
||||
|
||||
end, })
|
||||
203
awesome/src/modules/notification-center/widgets/weather.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--------------------------------
|
||||
-- This is the weather widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtimer = require('gears.timer')
|
||||
local aspawn = require('awful.spawn')
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
local json_lua = require('src.lib.json-lua.json-lua')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/weather/'
|
||||
|
||||
local instance = nil
|
||||
|
||||
local icon_table = {
|
||||
['01d'] = 'weather-sunny',
|
||||
['01n'] = 'weather-clear-night',
|
||||
['02d'] = 'weather-partly-cloudy',
|
||||
['02n'] = 'weather-night-partly-cloudy',
|
||||
['03d'] = 'weather-cloudy',
|
||||
['03n'] = 'weather-clouds-night',
|
||||
['04d'] = 'weather-cloudy',
|
||||
['04n'] = 'weather-cloudy',
|
||||
['09d'] = 'weather-rainy',
|
||||
['09n'] = 'weather-rainy',
|
||||
['10d'] = 'weather-partly-rainy',
|
||||
['10n'] = 'weather-partly-rainy',
|
||||
['11d'] = 'weather-pouring',
|
||||
['11n'] = 'weather-pouring',
|
||||
['13d'] = 'weather-snowy',
|
||||
['13n'] = 'weather-snowy',
|
||||
['50d'] = 'weather-fog',
|
||||
['50n'] = 'weather-fog',
|
||||
}
|
||||
|
||||
if not instance then
|
||||
instance = setmetatable({}, { __call = function()
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{ -- Icon
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
id = 'icon',
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(64),
|
||||
height = dpi(64),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{ -- Temperature
|
||||
text = 'NaN°C',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
font = 'JetBrains Mono Bold 24',
|
||||
id = 'temp',
|
||||
},
|
||||
{ -- City, Country
|
||||
text = 'City, Country',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'city_country',
|
||||
},
|
||||
{
|
||||
{ -- Description
|
||||
text = 'NaN',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'description',
|
||||
},
|
||||
fg = Theme_config.notification_center.weather.description_fg,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{ -- line
|
||||
{
|
||||
bg = Theme_config.notification_center.weather.line_color,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
height = dpi(2),
|
||||
width = dpi(10),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
{ -- Speed
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. 'weather-windy.svg',
|
||||
Theme_config.notification_center.weather.speed_icon_color),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
text = 'NaN m/s',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'speed',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{
|
||||
{ -- Humidity
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'humidity.svg',
|
||||
Theme_config.notification_center.weather.humidity_icon_color),
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
text = 'NaN%',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
id = 'humidity',
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
border_color = Theme_config.notification_center.weather.border_color,
|
||||
border_width = Theme_config.notification_center.weather.border_width,
|
||||
shape = Theme_config.notification_center.weather.shape,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
top = dpi(20),
|
||||
left = dpi(20),
|
||||
right = dpi(10),
|
||||
bottom = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(250),
|
||||
strategy = 'exact',
|
||||
}
|
||||
|
||||
gtimer {
|
||||
timeout = 900,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
aspawn.easy_async_with_shell("curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" ..
|
||||
User_config.weather_secrets.city_id .. '&units=' .. User_config.weather_secrets.unit .. '&appid=' .. User_config.weather_secrets.key .. "'",
|
||||
function(stdout)
|
||||
if not stdout:match('error') then
|
||||
local weather_metadata = json_lua:decode(stdout)
|
||||
if weather_metadata then
|
||||
w:get_children_by_id('icon')[1].image = icondir .. icon_table[weather_metadata.weather[1].icon] .. '.svg'
|
||||
w:get_children_by_id('temp')[1].text = math.floor(weather_metadata.main.temp + 0.5) .. '°C'
|
||||
w:get_children_by_id('city_country')[1].text = weather_metadata.name .. ', ' .. weather_metadata.sys.country
|
||||
w:get_children_by_id('description')[1].text = weather_metadata.weather[1].description:sub(1, 1):upper() ..
|
||||
weather_metadata.weather[1].description:sub(2)
|
||||
w:get_children_by_id('speed')[1].text = weather_metadata.wind.speed .. ' m/s'
|
||||
w:get_children_by_id('humidity')[1].text = weather_metadata.main.humidity .. '%'
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end,
|
||||
}
|
||||
|
||||
return w
|
||||
|
||||
end, })
|
||||
end
|
||||
|
||||
return instance
|
||||
214
awesome/src/modules/powermenu/init.lua
Normal file
@@ -0,0 +1,214 @@
|
||||
--------------------------------
|
||||
-- This is the network widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require('awful.button')
|
||||
local akey = require('awful.key')
|
||||
local akeygrabber = require('awful.keygrabber')
|
||||
local aspawn = require('awful.spawn')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/powermenu/'
|
||||
|
||||
local instance = nil
|
||||
local powermenu = {}
|
||||
|
||||
local function get_button(type)
|
||||
local icon, name, bg_color, command
|
||||
|
||||
if type == 'shutdown' then
|
||||
icon = icondir .. 'shutdown.svg'
|
||||
name = 'Shutdown'
|
||||
bg_color = Theme_config.powermenu.shutdown_button_bg
|
||||
command = 'shutdown now'
|
||||
elseif type == 'reboot' then
|
||||
icon = icondir .. 'reboot.svg'
|
||||
name = 'Reboot'
|
||||
bg_color = Theme_config.powermenu.reboot_button_bg
|
||||
command = 'reboot'
|
||||
elseif type == 'logout' then
|
||||
icon = icondir .. 'logout.svg'
|
||||
name = 'Logout'
|
||||
bg_color = Theme_config.powermenu.logout_button_bg
|
||||
command = 'awesome-client "awesome.quit()"'
|
||||
elseif type == 'lock' then
|
||||
icon = icondir .. 'lock.svg'
|
||||
name = 'Lock'
|
||||
bg_color = Theme_config.powermenu.lock_button_bg
|
||||
command = 'dm-tool lock'
|
||||
elseif type == 'suspend' then
|
||||
icon = icondir .. 'suspend.svg'
|
||||
name = 'Suspend'
|
||||
bg_color = Theme_config.powermenu.suspend_button_bg
|
||||
command = 'systemctl suspend'
|
||||
end
|
||||
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = icon,
|
||||
resize = true,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
{
|
||||
text = name,
|
||||
font = 'JetBrains Mono Bold 30',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
widget = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
fg = Theme_config.powermenu.button_fg,
|
||||
bg = bg_color,
|
||||
shape = Theme_config.powermenu.button_shape,
|
||||
widget = wibox.container.background,
|
||||
id = 'background',
|
||||
},
|
||||
height = dpi(70),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = widget.background, overlay = 12, press_overlay = 24 }
|
||||
|
||||
widget:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
aspawn(command)
|
||||
end)
|
||||
))
|
||||
|
||||
return widget
|
||||
end
|
||||
|
||||
function powermenu:toggle()
|
||||
self.keygrabber:start()
|
||||
self.visible = not self.visible
|
||||
end
|
||||
|
||||
function powermenu.new()
|
||||
local w = wibox {
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = icondir .. 'defaultpfp.svg',
|
||||
resize = true,
|
||||
clip_shape = Theme_config.powermenu.profile_picture_shape,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(200),
|
||||
height = dpi(200),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
font = 'JetBrains Mono Bold 30',
|
||||
id = 'text_role',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
{
|
||||
{
|
||||
get_button('shutdown'),
|
||||
get_button('reboot'),
|
||||
get_button('logout'),
|
||||
get_button('lock'),
|
||||
get_button('suspend'),
|
||||
spacing = dpi(30),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
screen = capi.screen.primary,
|
||||
type = 'splash',
|
||||
visible = false,
|
||||
ontop = true,
|
||||
bg = Theme_config.powermenu.container_bg,
|
||||
height = capi.screen.primary.geometry.height,
|
||||
width = capi.screen.primary.geometry.width,
|
||||
x = capi.screen.primary.geometry.x,
|
||||
y = capi.screen.primary.geometry.y,
|
||||
}
|
||||
|
||||
gtable.crush(w, powermenu, true)
|
||||
|
||||
w:buttons { gtable.join(
|
||||
abutton({}, 3, function()
|
||||
w:toggle()
|
||||
w.keygrabber:stop()
|
||||
end)
|
||||
), }
|
||||
|
||||
w.keygrabber = akeygrabber {
|
||||
autostart = false,
|
||||
stop_event = 'release',
|
||||
stop_key = 'Escape',
|
||||
keybindings = {
|
||||
akey {
|
||||
modifiers = {},
|
||||
key = 'Escape',
|
||||
on_press = function()
|
||||
w:toggle()
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
|
||||
-- and copy it to the assets folder
|
||||
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userPfp'", function(stdout)
|
||||
if stdout then
|
||||
w:get_children_by_id('icon_role')[1].image = stdout:gsub('\n', '')
|
||||
else
|
||||
w:get_children_by_id('icon_role')[1].image = icondir .. 'defaultpfp.svg'
|
||||
end
|
||||
end)
|
||||
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'", function(stdout)
|
||||
w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '')
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
if instance == nil then
|
||||
instance = powermenu.new()
|
||||
end
|
||||
return instance
|
||||
@@ -1,249 +0,0 @@
|
||||
--------------------------------
|
||||
-- This is the network widget --
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/powermenu/"
|
||||
|
||||
return function(s)
|
||||
|
||||
-- Profile picture imagebox
|
||||
local profile_picture = wibox.widget {
|
||||
image = icondir .. "defaultpfp.svg",
|
||||
resize = true,
|
||||
forced_height = dpi(200),
|
||||
clip_shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(30))
|
||||
end,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
-- Username textbox
|
||||
local profile_name = wibox.widget {
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
text = " ",
|
||||
font = "JetBrains Mono Bold 30",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
|
||||
-- and copy it to the assets folder
|
||||
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
|
||||
local update_profile_picture = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"./.config/awesome/src/scripts/pfp.sh 'userPfp'",
|
||||
function(stdout)
|
||||
if stdout then
|
||||
profile_picture:set_image(stdout:gsub("\n", ""))
|
||||
else
|
||||
profile_picture:set_image(icondir .. "defaultpfp.svg")
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
update_profile_picture()
|
||||
|
||||
-- Get the full username(if set) and the username + hostname
|
||||
local update_user_name = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'",
|
||||
function(stdout)
|
||||
if stdout:gsub("\n", "") == "Rick Astley" then
|
||||
profile_picture:set_image(gears.filesystem.get_configuration_dir() .. "src/assets/userpfp/" .. "rickastley.jpg")
|
||||
end
|
||||
profile_name:set_text(stdout)
|
||||
end
|
||||
)
|
||||
end
|
||||
update_user_name()
|
||||
|
||||
-- Universal Button widget
|
||||
local button = function(name, icon, bg_color, callback)
|
||||
local item = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
-- TODO: using gears.color to recolor a SVG will make it look super low res
|
||||
-- currently I recolor it in the .svg file directly, but later implement
|
||||
-- a better way to recolor a SVG
|
||||
image = icon,
|
||||
resize = true,
|
||||
forced_height = dpi(30),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
{
|
||||
text = name,
|
||||
font = "JetBrains Mono Bold 30",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
widget = wibox.layout.fixed.horizontal
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
fg = Theme_config.powermenu.button_fg,
|
||||
bg = bg_color,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(10))
|
||||
end,
|
||||
widget = wibox.container.background,
|
||||
id = 'background'
|
||||
},
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
item:connect_signal(
|
||||
"button::release",
|
||||
function()
|
||||
callback()
|
||||
end
|
||||
)
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
-- Create the power menu actions
|
||||
local suspend_command = function()
|
||||
awful.spawn("systemctl suspend")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local logout_command = function()
|
||||
capi.awesome.quit()
|
||||
end
|
||||
|
||||
local lock_command = function()
|
||||
awful.spawn("dm-tool lock")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local shutdown_command = function()
|
||||
awful.spawn("shutdown now")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
local reboot_command = function()
|
||||
awful.spawn("reboot")
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
|
||||
-- Create the buttons with their command and name etc
|
||||
local shutdown_button = button("Shutdown", icondir .. "shutdown.svg", Theme_config.powermenu.shutdown_button_bg,
|
||||
shutdown_command)
|
||||
local reboot_button = button("Reboot", icondir .. "reboot.svg", Theme_config.powermenu.reboot_button_bg, reboot_command)
|
||||
local suspend_button = button("Suspend", icondir .. "suspend.svg", Theme_config.powermenu.suspend_button_bg,
|
||||
suspend_command)
|
||||
local logout_button = button("Logout", icondir .. "logout.svg", Theme_config.powermenu.logout_button_bg, logout_command)
|
||||
local lock_button = button("Lock", icondir .. "lock.svg", Theme_config.powermenu.lock_button_bg, lock_command)
|
||||
|
||||
-- Signals to change color on hover
|
||||
Hover_signal(shutdown_button.background)
|
||||
Hover_signal(reboot_button.background)
|
||||
Hover_signal(suspend_button.background)
|
||||
Hover_signal(logout_button.background)
|
||||
Hover_signal(lock_button.background)
|
||||
|
||||
-- The powermenu widget
|
||||
local powermenu = wibox.widget {
|
||||
{
|
||||
{
|
||||
profile_picture,
|
||||
profile_name,
|
||||
spacing = dpi(50),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
shutdown_button,
|
||||
reboot_button,
|
||||
logout_button,
|
||||
lock_button,
|
||||
suspend_button,
|
||||
spacing = dpi(30),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
widget = wibox.container.place
|
||||
}
|
||||
|
||||
-- Container for the widget, covers the entire screen
|
||||
local powermenu_container = wibox {
|
||||
widget = powermenu,
|
||||
screen = s,
|
||||
type = "splash",
|
||||
visible = false,
|
||||
ontop = true,
|
||||
bg = Theme_config.powermenu.container_bg,
|
||||
height = s.geometry.height,
|
||||
width = s.geometry.width,
|
||||
x = s.geometry.x,
|
||||
y = s.geometry.y
|
||||
}
|
||||
|
||||
-- Close on rightclick
|
||||
powermenu_container:buttons(
|
||||
gears.table.join(
|
||||
awful.button(
|
||||
{},
|
||||
3,
|
||||
function()
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
-- Close on Escape
|
||||
local powermenu_keygrabber = awful.keygrabber {
|
||||
autostart = false,
|
||||
stop_event = 'release',
|
||||
keypressed_callback = function(self, mod, key, command)
|
||||
if key == 'Escape' then
|
||||
capi.awesome.emit_signal("module::powermenu:hide")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- Signals
|
||||
capi.awesome.connect_signal(
|
||||
"module::powermenu:show",
|
||||
function()
|
||||
if s == capi.mouse.screen then
|
||||
powermenu_container.visible = true
|
||||
powermenu_keygrabber:start()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"module::powermenu:hide",
|
||||
function()
|
||||
powermenu_keygrabber:stop()
|
||||
powermenu_container.visible = false
|
||||
end
|
||||
)
|
||||
end
|
||||
@@ -3,13 +3,13 @@
|
||||
---------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local color = require("src.lib.color")
|
||||
local rubato = require("src.lib.rubato")
|
||||
local color = require('src.lib.color')
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -21,13 +21,13 @@ return function()
|
||||
local elements = wibox.widget {
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
spacing = dpi(20),
|
||||
id = "switcher"
|
||||
id = 'switcher',
|
||||
}
|
||||
|
||||
local selected = 0
|
||||
|
||||
local function create_elements(fn)
|
||||
fn = fn or ""
|
||||
fn = fn or ''
|
||||
|
||||
elements:reset()
|
||||
|
||||
@@ -53,44 +53,43 @@ return function()
|
||||
{
|
||||
{ -- Icon
|
||||
{
|
||||
id = "icon",
|
||||
id = 'icon',
|
||||
--!ADD FALLBACK ICON!--
|
||||
image = Get_icon(client.class, client.name) or client.icon,
|
||||
--image = gears.surface(client.content),
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox
|
||||
image = gears.surface(client.icon),
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
width = dpi(100),
|
||||
height = dpi(100),
|
||||
id = "icon_const",
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
id = 'icon_const',
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
{
|
||||
text = client.name,
|
||||
id = "label",
|
||||
widget = wibox.widget.textbox
|
||||
id = 'label',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
id = "place",
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.container.place
|
||||
id = 'place',
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "layout1",
|
||||
id = 'layout1',
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
id = "box",
|
||||
id = 'box',
|
||||
width = dpi(150),
|
||||
height = dpi(150),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
id = "margin",
|
||||
id = 'margin',
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
@@ -99,13 +98,13 @@ return function()
|
||||
border_width = Theme_config.window_switcher.border_width,
|
||||
bg = Theme_config.window_switcher.bg,
|
||||
fg = Theme_config.window_switcher.element_fg,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
elements:add(window_element)
|
||||
end
|
||||
|
||||
if fn == "next" then
|
||||
if fn == 'next' then
|
||||
if selected >= #clients_sorted then
|
||||
selected = 1
|
||||
else
|
||||
@@ -153,15 +152,15 @@ return function()
|
||||
end
|
||||
|
||||
local function update_bg()
|
||||
element:set_bg("#" .. color.utils.rgba_to_hex { r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos })
|
||||
element:set_bg('#' .. color.utils.rgba_to_hex { r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos })
|
||||
end
|
||||
|
||||
local function update_fg()
|
||||
element:set_fg("#" .. color.utils.rgba_to_hex { r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos })
|
||||
element:set_fg('#' .. color.utils.rgba_to_hex { r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos })
|
||||
end
|
||||
|
||||
local function update_border()
|
||||
element.border_color = "#" ..
|
||||
element.border_color = '#' ..
|
||||
color.utils.rgba_to_hex { r_timed_border.pos, g_timed_border.pos, b_timed_border.pos }
|
||||
end
|
||||
|
||||
@@ -202,7 +201,7 @@ return function()
|
||||
set_bg(Theme_config.window_switcher.bg)
|
||||
end
|
||||
end
|
||||
elseif fn == "raise" then
|
||||
elseif fn == 'raise' then
|
||||
local c = clients_sorted[selected]
|
||||
if not c:isvisible() and c.first_tag then
|
||||
c.first_tag:view_only()
|
||||
@@ -219,35 +218,35 @@ return function()
|
||||
elements = create_elements()
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::select_next",
|
||||
'window_switcher::select_next',
|
||||
function()
|
||||
elements = create_elements("next")
|
||||
elements = create_elements('next')
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::raise",
|
||||
'window_switcher::raise',
|
||||
function()
|
||||
elements = create_elements("raise")
|
||||
elements = create_elements('raise')
|
||||
end
|
||||
)
|
||||
|
||||
capi.client.connect_signal(
|
||||
"manage",
|
||||
'manage',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
)
|
||||
|
||||
capi.client.connect_signal(
|
||||
"unmanage",
|
||||
'unmanage',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"window_switcher::update",
|
||||
'window_switcher::update',
|
||||
function()
|
||||
elements = create_elements()
|
||||
end
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SINK=$(LC_ALL=C pactl get-default-source)
|
||||
|
||||
case $1 in
|
||||
|
||||
"volume")
|
||||
echo $(LC_ALL=C pactl get-source-volume $SINK | awk '{print $5}')
|
||||
;;
|
||||
|
||||
"mute")
|
||||
echo $(LC_ALL=C pactl get-source-mute $SINK)
|
||||
;;
|
||||
|
||||
"toggle_mute")
|
||||
$(LC_ALL=C pactl set-source-mute $SINK toggle)
|
||||
;;
|
||||
|
||||
"set_volume")
|
||||
$(LC_ALL=C pactl set-source-volume $SINK $2)
|
||||
;;
|
||||
|
||||
"set_source")
|
||||
$(LC_ALL=C pactl set-default-source $2)
|
||||
;;
|
||||
|
||||
esac
|
||||
@@ -23,8 +23,8 @@ case $1 in
|
||||
else
|
||||
if [[ -f "$iconPath" ]];
|
||||
then
|
||||
cp "$iconPath" "$userIconPath$USER.png"
|
||||
printf "$userIconPath$USER.png"
|
||||
cp "$iconPath" $userIconPath"userpfp.png"
|
||||
printf $userIconPath"userpfp.png"
|
||||
exit;
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
case $1 in
|
||||
|
||||
"volume")
|
||||
echo $(LC_ALL=C pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}')
|
||||
;;
|
||||
|
||||
"mute")
|
||||
echo $(LC_ALL=C pactl get-sink-mute @DEFAULT_SINK@)
|
||||
;;
|
||||
|
||||
"set_sink")
|
||||
$(LC_ALL=C pactl set-default-sink $2)
|
||||
;;
|
||||
esac
|
||||
@@ -3,125 +3,116 @@
|
||||
-----------------------------------------------------
|
||||
|
||||
return {
|
||||
['White'] = '#ffffff',
|
||||
['Black'] = '#000000',
|
||||
|
||||
['Grey50'] = '#fafafa',
|
||||
['Grey100'] = '#f5f5f5',
|
||||
['Grey200'] = '#eeeeee',
|
||||
['Grey300'] = '#e0e0e0',
|
||||
['Grey400'] = '#bdbdbd',
|
||||
['Grey500'] = '#9e9e9e',
|
||||
['Grey600'] = '#757575',
|
||||
['Grey700'] = '#616161',
|
||||
['Grey800'] = '#424242',
|
||||
['Grey900'] = '#212121',
|
||||
|
||||
['Red50'] = '#ffebee',
|
||||
['Red100'] = '#ffcdd2',
|
||||
['Red200'] = '#ef9a9a',
|
||||
['Red300'] = '#e57373',
|
||||
['Red400'] = '#ef5350',
|
||||
['Red500'] = '#f44336',
|
||||
['Red600'] = '#e53935',
|
||||
['Red700'] = '#d32f2f',
|
||||
['Red800'] = '#c62828',
|
||||
['Red900'] = '#b71c1c',
|
||||
['RedA100'] = '#ff8a80',
|
||||
['RedA200'] = '#ff5252',
|
||||
['RedA400'] = '#ff1744',
|
||||
['RedA700'] = '#d50000',
|
||||
|
||||
['Pink50'] = '#fce4ec',
|
||||
['Pink100'] = '#f8bbd0',
|
||||
['Pink200'] = '#f48fb1',
|
||||
['Pink300'] = '#f06292',
|
||||
['Pink400'] = '#ec407a',
|
||||
['Pink500'] = '#e91e63',
|
||||
['Pink600'] = '#d81b60',
|
||||
['Pink700'] = '#c2185b',
|
||||
['Pink800'] = '#ad1457',
|
||||
['Pink900'] = '#880e4f',
|
||||
['PinkA100'] = '#ff80ab',
|
||||
['PinkA200'] = '#ff4081',
|
||||
['PinkA400'] = '#f50057',
|
||||
['PinkA700'] = '#c51162',
|
||||
|
||||
['Blue50'] = '#e3f2fd',
|
||||
['Blue100'] = '#bbdefb',
|
||||
['Blue200'] = '#90caf9',
|
||||
['Blue300'] = '#64b5f6',
|
||||
['Blue400'] = '#42a5f5',
|
||||
['Blue500'] = '#2196f3',
|
||||
['Blue600'] = '#1e88e5',
|
||||
['Blue700'] = '#1976d2',
|
||||
['Blue800'] = '#1565c0',
|
||||
['Blue900'] = '#0d47a1',
|
||||
['BlueA100'] = '#82b1ff',
|
||||
['BlueA200'] = '#448aff',
|
||||
['BlueA400'] = '#2979ff',
|
||||
['BlueA700'] = '#2962ff',
|
||||
|
||||
['Yellow50'] = '#fffde7',
|
||||
['Yellow100'] = '#fff9c4',
|
||||
['Yellow200'] = '#fff59d',
|
||||
['Yellow300'] = '#fff176',
|
||||
['Yellow400'] = '#ffee58',
|
||||
['Yellow500'] = '#ffeb3b',
|
||||
['Yellow600'] = '#fdd835',
|
||||
['Yellow700'] = '#fbc02d',
|
||||
['Yellow800'] = '#f9a825',
|
||||
['Yellow900'] = '#f57f17',
|
||||
['YellowA100'] = '#ffff8d',
|
||||
['YellowA200'] = '#ffff00',
|
||||
['YellowA400'] = '#ffea00',
|
||||
['YellowA700'] = '#ffd600',
|
||||
|
||||
['Teal50'] = '#e0f2f1',
|
||||
['Teal100'] = '#b2dfdb',
|
||||
['Teal200'] = '#80cbc4',
|
||||
['Teal300'] = '#4db6ac',
|
||||
['Teal400'] = '#26a69a',
|
||||
['Teal500'] = '#009688',
|
||||
['Teal600'] = '#00897b',
|
||||
['Teal700'] = '#00796b',
|
||||
['Teal800'] = '#00695c',
|
||||
['Teal900'] = '#004d40',
|
||||
['TealA100'] = '#a7ffeb',
|
||||
['TealA200'] = '#64ffda',
|
||||
['TealA400'] = '#1de9b6',
|
||||
['TealA700'] = '#00bfa5',
|
||||
|
||||
['Green50'] = '#e8f5e9',
|
||||
['Green100'] = '#c8e6c9',
|
||||
['Green200'] = '#a5d6a7',
|
||||
['Green300'] = '#81c784',
|
||||
['Green400'] = '#66bb6a',
|
||||
['Green500'] = '#4caf50',
|
||||
['Green600'] = '#43a047',
|
||||
['Green700'] = '#388e3c',
|
||||
['Green800'] = '#2e7d32',
|
||||
['Green900'] = '#1b5e20',
|
||||
['GreenA100'] = '#b9f6ca',
|
||||
['GreenA200'] = '#69f0ae',
|
||||
['GreenA400'] = '#00e676',
|
||||
['GreenA700'] = '#00c853',
|
||||
|
||||
['Orange50'] = '#fff3e0',
|
||||
['Orange100'] = '#ffe0b2',
|
||||
['Orange200'] = '#ffcc80',
|
||||
['Orange300'] = '#ffb74d',
|
||||
['Orange400'] = '#ffa726',
|
||||
['Orange500'] = '#ff9800',
|
||||
['Orange600'] = '#fb8c00',
|
||||
['Orange700'] = '#f57c00',
|
||||
['Orange800'] = '#ef6c00',
|
||||
['Orange900'] = '#e65100',
|
||||
['OrangeA100'] = '#ffd180',
|
||||
['OrangeA200'] = '#ffab40',
|
||||
['OrangeA400'] = '#ff9100',
|
||||
['OrangeA700'] = '#ff6d00',
|
||||
|
||||
['White'] = '#ffffff',
|
||||
['Black'] = '#000000',
|
||||
['Grey50'] = '#fafafa',
|
||||
['Grey100'] = '#f5f5f5',
|
||||
['Grey200'] = '#eeeeee',
|
||||
['Grey300'] = '#e0e0e0',
|
||||
['Grey400'] = '#bdbdbd',
|
||||
['Grey500'] = '#9e9e9e',
|
||||
['Grey600'] = '#757575',
|
||||
['Grey700'] = '#616161',
|
||||
['Grey800'] = '#424242',
|
||||
['Grey900'] = '#212121',
|
||||
['Red50'] = '#ffebee',
|
||||
['Red100'] = '#ffcdd2',
|
||||
['Red200'] = '#ef9a9a',
|
||||
['Red300'] = '#e57373',
|
||||
['Red400'] = '#ef5350',
|
||||
['Red500'] = '#f44336',
|
||||
['Red600'] = '#e53935',
|
||||
['Red700'] = '#d32f2f',
|
||||
['Red800'] = '#c62828',
|
||||
['Red900'] = '#b71c1c',
|
||||
['RedA100'] = '#ff8a80',
|
||||
['RedA200'] = '#ff5252',
|
||||
['RedA400'] = '#ff1744',
|
||||
['RedA700'] = '#d50000',
|
||||
['Pink50'] = '#fce4ec',
|
||||
['Pink100'] = '#f8bbd0',
|
||||
['Pink200'] = '#f48fb1',
|
||||
['Pink300'] = '#f06292',
|
||||
['Pink400'] = '#ec407a',
|
||||
['Pink500'] = '#e91e63',
|
||||
['Pink600'] = '#d81b60',
|
||||
['Pink700'] = '#c2185b',
|
||||
['Pink800'] = '#ad1457',
|
||||
['Pink900'] = '#880e4f',
|
||||
['PinkA100'] = '#ff80ab',
|
||||
['PinkA200'] = '#ff4081',
|
||||
['PinkA400'] = '#f50057',
|
||||
['PinkA700'] = '#c51162',
|
||||
['Blue50'] = '#e3f2fd',
|
||||
['Blue100'] = '#bbdefb',
|
||||
['Blue200'] = '#90caf9',
|
||||
['Blue300'] = '#64b5f6',
|
||||
['Blue400'] = '#42a5f5',
|
||||
['Blue500'] = '#2196f3',
|
||||
['Blue600'] = '#1e88e5',
|
||||
['Blue700'] = '#1976d2',
|
||||
['Blue800'] = '#1565c0',
|
||||
['Blue900'] = '#0d47a1',
|
||||
['BlueA100'] = '#82b1ff',
|
||||
['BlueA200'] = '#448aff',
|
||||
['BlueA400'] = '#2979ff',
|
||||
['BlueA700'] = '#2962ff',
|
||||
['Yellow50'] = '#fffde7',
|
||||
['Yellow100'] = '#fff9c4',
|
||||
['Yellow200'] = '#fff59d',
|
||||
['Yellow300'] = '#fff176',
|
||||
['Yellow400'] = '#ffee58',
|
||||
['Yellow500'] = '#ffeb3b',
|
||||
['Yellow600'] = '#fdd835',
|
||||
['Yellow700'] = '#fbc02d',
|
||||
['Yellow800'] = '#f9a825',
|
||||
['Yellow900'] = '#f57f17',
|
||||
['YellowA100'] = '#ffff8d',
|
||||
['YellowA200'] = '#ffff00',
|
||||
['YellowA400'] = '#ffea00',
|
||||
['YellowA700'] = '#ffd600',
|
||||
['Teal50'] = '#e0f2f1',
|
||||
['Teal100'] = '#b2dfdb',
|
||||
['Teal200'] = '#80cbc4',
|
||||
['Teal300'] = '#4db6ac',
|
||||
['Teal400'] = '#26a69a',
|
||||
['Teal500'] = '#009688',
|
||||
['Teal600'] = '#00897b',
|
||||
['Teal700'] = '#00796b',
|
||||
['Teal800'] = '#00695c',
|
||||
['Teal900'] = '#004d40',
|
||||
['TealA100'] = '#a7ffeb',
|
||||
['TealA200'] = '#64ffda',
|
||||
['TealA400'] = '#1de9b6',
|
||||
['TealA700'] = '#00bfa5',
|
||||
['Green50'] = '#e8f5e9',
|
||||
['Green100'] = '#c8e6c9',
|
||||
['Green200'] = '#a5d6a7',
|
||||
['Green300'] = '#81c784',
|
||||
['Green400'] = '#66bb6a',
|
||||
['Green500'] = '#4caf50',
|
||||
['Green600'] = '#43a047',
|
||||
['Green700'] = '#388e3c',
|
||||
['Green800'] = '#2e7d32',
|
||||
['Green900'] = '#1b5e20',
|
||||
['GreenA100'] = '#b9f6ca',
|
||||
['GreenA200'] = '#69f0ae',
|
||||
['GreenA400'] = '#00e676',
|
||||
['GreenA700'] = '#00c853',
|
||||
['Orange50'] = '#fff3e0',
|
||||
['Orange100'] = '#ffe0b2',
|
||||
['Orange200'] = '#ffcc80',
|
||||
['Orange300'] = '#ffb74d',
|
||||
['Orange400'] = '#ffa726',
|
||||
['Orange500'] = '#ff9800',
|
||||
['Orange600'] = '#fb8c00',
|
||||
['Orange700'] = '#f57c00',
|
||||
['Orange800'] = '#ef6c00',
|
||||
['Orange900'] = '#e65100',
|
||||
['OrangeA100'] = '#ffd180',
|
||||
['OrangeA200'] = '#ffab40',
|
||||
['OrangeA400'] = '#ff9100',
|
||||
['OrangeA700'] = '#ff6d00',
|
||||
['DeepOrange50'] = '#fbe9e7',
|
||||
['DeepOrange100'] = '#ffccbc',
|
||||
['DeepOrange200'] = '#ffab91',
|
||||
@@ -136,76 +127,70 @@ return {
|
||||
['DeepOrangeA200'] = '#ff6e40',
|
||||
['DeepOrangeA400'] = '#ff3d00',
|
||||
['DeepOrangeA700'] = '#dd2c00',
|
||||
|
||||
['Purple50'] = '#F3E5F5',
|
||||
['Purple100'] = '#E1BEE7',
|
||||
['Purple200'] = '#CE93D8',
|
||||
['Purple300'] = '#BA68C8',
|
||||
['Purple400'] = '#AB47BC',
|
||||
['Purple500'] = '#9C27B0',
|
||||
['Purple600'] = '#8E24AA',
|
||||
['Purple700'] = '#7B1FA2',
|
||||
['Purple800'] = '#6A1B9A',
|
||||
['Purple900'] = '#4A148C',
|
||||
['PurpleA100'] = '#EA80FC',
|
||||
['PurpleA200'] = '#E040FB',
|
||||
['PurpleA500'] = '#D500F9',
|
||||
['PurpleA700'] = '#AA00FF',
|
||||
|
||||
['DeepPurple50'] = '#EDE7F6',
|
||||
['DeepPurple100'] = '#D1C4E9',
|
||||
['DeepPurple200'] = '#B39DDB',
|
||||
['DeepPurple300'] = '#9575CD',
|
||||
['DeepPurple400'] = '#7E57C2',
|
||||
['DeepPurple500'] = '#673AB7',
|
||||
['DeepPurple600'] = '#5E35B1',
|
||||
['DeepPurple700'] = '#512DA8',
|
||||
['DeepPurple800'] = '#4527A0',
|
||||
['DeepPurple900'] = '#311B92',
|
||||
['Purple50'] = '#F3E5F5',
|
||||
['Purple100'] = '#E1BEE7',
|
||||
['Purple200'] = '#CE93D8',
|
||||
['Purple300'] = '#BA68C8',
|
||||
['Purple400'] = '#AB47BC',
|
||||
['Purple500'] = '#9C27B0',
|
||||
['Purple600'] = '#8E24AA',
|
||||
['Purple700'] = '#7B1FA2',
|
||||
['Purple800'] = '#6A1B9A',
|
||||
['Purple900'] = '#4A148C',
|
||||
['PurpleA100'] = '#EA80FC',
|
||||
['PurpleA200'] = '#E040FB',
|
||||
['PurpleA500'] = '#D500F9',
|
||||
['PurpleA700'] = '#AA00FF',
|
||||
['DeepPurple50'] = '#EDE7F6',
|
||||
['DeepPurple100'] = '#D1C4E9',
|
||||
['DeepPurple200'] = '#B39DDB',
|
||||
['DeepPurple300'] = '#9575CD',
|
||||
['DeepPurple400'] = '#7E57C2',
|
||||
['DeepPurple500'] = '#673AB7',
|
||||
['DeepPurple600'] = '#5E35B1',
|
||||
['DeepPurple700'] = '#512DA8',
|
||||
['DeepPurple800'] = '#4527A0',
|
||||
['DeepPurple900'] = '#311B92',
|
||||
['DeepPurpleA100'] = '#B388FF',
|
||||
['DeepPurpleA200'] = '#7C4DFF',
|
||||
['DeepPurpleA400'] = '#651FFF',
|
||||
['DeepPurpleA700'] = '#6200EA',
|
||||
|
||||
['LightBlue50'] = '#E1F5FE',
|
||||
['LightBlue100'] = '#B3E5FC',
|
||||
['LightBlue200'] = '#81D4FA',
|
||||
['LightBlue300'] = '#4FC3F7',
|
||||
['LightBlue400'] = '#29B6F6',
|
||||
['LightBlue500'] = '#03A9F4',
|
||||
['LightBlue600'] = '#039BE5',
|
||||
['LightBlue700'] = '#0288D1',
|
||||
['LightBlue800'] = '#0277BD',
|
||||
['LightBlue900'] = '#01579B',
|
||||
['LightBlueA100'] = '#80D8FF',
|
||||
['LightBlueA200'] = '#40C4FF',
|
||||
['LightBlueA400'] = '#00B0FF',
|
||||
['LightBlueA700'] = '#0091EA',
|
||||
|
||||
['Cyan50'] = '#E0F7FA',
|
||||
['Cyan100'] = '#B2EBF2',
|
||||
['Cyan200'] = '#80DEEA',
|
||||
['Cyan300'] = '#4DD0E1',
|
||||
['Cyan400'] = '#26C6DA',
|
||||
['Cyan500'] = '#00BCD4',
|
||||
['Cyan600'] = '#00ACC1',
|
||||
['Cyan700'] = '#0097A7',
|
||||
['Cyan800'] = '#00838F',
|
||||
['Cyan900'] = '#006064',
|
||||
['CyanA100'] = '#84FFFF',
|
||||
['CyanA200'] = '#18FFFF',
|
||||
['CyanA400'] = '#00E5FF',
|
||||
['CyanA700'] = '#00B8D4',
|
||||
|
||||
|
||||
['BlueGrey50'] = '#ECEFF1',
|
||||
['BlueGrey100'] = '#CFD8DC',
|
||||
['BlueGrey200'] = '#B0BEC5',
|
||||
['BlueGrey300'] = '#90A4AE',
|
||||
['BlueGrey400'] = '#78909C',
|
||||
['BlueGrey500'] = '#607D8B',
|
||||
['BlueGrey600'] = '#546E7A',
|
||||
['BlueGrey700'] = '#455A64',
|
||||
['BlueGrey800'] = '#37474F',
|
||||
['BlueGrey900'] = '#263238'
|
||||
['LightBlue50'] = '#E1F5FE',
|
||||
['LightBlue100'] = '#B3E5FC',
|
||||
['LightBlue200'] = '#81D4FA',
|
||||
['LightBlue300'] = '#4FC3F7',
|
||||
['LightBlue400'] = '#29B6F6',
|
||||
['LightBlue500'] = '#03A9F4',
|
||||
['LightBlue600'] = '#039BE5',
|
||||
['LightBlue700'] = '#0288D1',
|
||||
['LightBlue800'] = '#0277BD',
|
||||
['LightBlue900'] = '#01579B',
|
||||
['LightBlueA100'] = '#80D8FF',
|
||||
['LightBlueA200'] = '#40C4FF',
|
||||
['LightBlueA400'] = '#00B0FF',
|
||||
['LightBlueA700'] = '#0091EA',
|
||||
['Cyan50'] = '#E0F7FA',
|
||||
['Cyan100'] = '#B2EBF2',
|
||||
['Cyan200'] = '#80DEEA',
|
||||
['Cyan300'] = '#4DD0E1',
|
||||
['Cyan400'] = '#26C6DA',
|
||||
['Cyan500'] = '#00BCD4',
|
||||
['Cyan600'] = '#00ACC1',
|
||||
['Cyan700'] = '#0097A7',
|
||||
['Cyan800'] = '#00838F',
|
||||
['Cyan900'] = '#006064',
|
||||
['CyanA100'] = '#84FFFF',
|
||||
['CyanA200'] = '#18FFFF',
|
||||
['CyanA400'] = '#00E5FF',
|
||||
['CyanA700'] = '#00B8D4',
|
||||
['BlueGrey50'] = '#ECEFF1',
|
||||
['BlueGrey100'] = '#CFD8DC',
|
||||
['BlueGrey200'] = '#B0BEC5',
|
||||
['BlueGrey300'] = '#90A4AE',
|
||||
['BlueGrey400'] = '#78909C',
|
||||
['BlueGrey500'] = '#607D8B',
|
||||
['BlueGrey600'] = '#546E7A',
|
||||
['BlueGrey700'] = '#455A64',
|
||||
['BlueGrey800'] = '#37474F',
|
||||
['BlueGrey900'] = '#263238',
|
||||
}
|
||||
|
||||
@@ -6,16 +6,20 @@
|
||||
-- ╚██████╗██║ ██║ ██║ ███████╗██║██║ ██║ --
|
||||
-- ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝ --
|
||||
--------------------------------------------------
|
||||
local beautiful = require("beautiful")
|
||||
local gears = require("gears")
|
||||
local beautiful = require('beautiful')
|
||||
local gwallpaper = require('gears.wallpaper')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
screen = screen,
|
||||
}
|
||||
|
||||
Theme_path = gears.filesystem.get_configuration_dir() .. "/src/theme/"
|
||||
Theme_path = gfilesystem.get_configuration_dir() .. '/src/theme/'
|
||||
Theme = {}
|
||||
|
||||
awesome.set_preferred_icon_size(128)
|
||||
|
||||
-- Default font, change it in user_config, not here.
|
||||
Theme.font = User_config.font.bold
|
||||
|
||||
@@ -51,17 +55,17 @@ Theme.hotkeys_label_fg = Theme_config.hotkeys.label_fg
|
||||
|
||||
-- Wallpaper
|
||||
beautiful.wallpaper = User_config.wallpaper
|
||||
capi.screen.connect_signal(
|
||||
'request::wallpaper',
|
||||
function(s)
|
||||
if beautiful.wallpaper then
|
||||
if type(beautiful.wallpaper) == 'string' then
|
||||
gears.wallpaper.maximized(beautiful.wallpaper, s)
|
||||
else
|
||||
beautiful.wallpaper(s)
|
||||
end
|
||||
capi.screen.connect_signal('request::wallpaper', function(s)
|
||||
if beautiful.wallpaper then
|
||||
if type(beautiful.wallpaper) == 'string' then
|
||||
gwallpaper.maximized(beautiful.wallpaper, s)
|
||||
else
|
||||
beautiful.wallpaper(s)
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
beautiful.init(Theme)
|
||||
|
||||
-- Load titlebar
|
||||
require('src.core.titlebar')()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
-------------------------------------------
|
||||
-- Uservariables are stored in this file --
|
||||
-------------------------------------------
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local home = os.getenv("HOME")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local home = os.getenv('HOME')
|
||||
|
||||
-- If you want different default programs, wallpaper path or modkey; edit this file.
|
||||
User_config = {
|
||||
@@ -17,10 +17,13 @@ User_config = {
|
||||
Flatpak application: flatpak run com.example.App
|
||||
]] --
|
||||
autostart = {
|
||||
"picom",
|
||||
"/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1",
|
||||
"setxkbmap -option caps:swapescape",
|
||||
"/home/crylia/.screenlayout/double.sh"
|
||||
'nm-applet',
|
||||
'protonvpn-cli ks --off',
|
||||
'picom',
|
||||
'/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1',
|
||||
'setxkbmap -option caps:swapescape',
|
||||
'/home/crylia/.screenlayout/double.sh',
|
||||
'gnome-keyring-daemon --start --components=secrets',
|
||||
},
|
||||
|
||||
--[[
|
||||
@@ -43,7 +46,7 @@ User_config = {
|
||||
"MEDIA_PLAYER"
|
||||
More information at: https://lazka.github.io/pgi-docs/UPowerGlib-1.0/enums.html#UPowerGlib.DeviceKind.KEYBOARD
|
||||
]] --
|
||||
battery_kind = "LINE_POWER",
|
||||
battery_kind = 'LINE_POWER',
|
||||
|
||||
--[[
|
||||
If your battery is not found you can specify its path here.
|
||||
@@ -61,6 +64,8 @@ User_config = {
|
||||
]]
|
||||
brightness_step = 2,
|
||||
|
||||
clock_mode = 'average',
|
||||
|
||||
--[[
|
||||
DnD or 'Do not Disturb' will prevent notifications from poping up.
|
||||
This is just a default value, you can toggle it in the notification-center, but it won't be saved.
|
||||
@@ -78,12 +83,12 @@ User_config = {
|
||||
This is the program that will be started when clicking on the battery widget
|
||||
If you don't want any just leave it as nil
|
||||
]] --
|
||||
energy_manager = "xfce4-power-manager-settings",
|
||||
energy_manager = 'xfce4-power-manager-settings',
|
||||
|
||||
--[[
|
||||
Your filemanager. Will be opened with <super> + <e>
|
||||
]] --
|
||||
file_manager = "nautilus",
|
||||
file_manager = 'nemo',
|
||||
|
||||
--[[
|
||||
The font that will be used on all widgets/modules etc.
|
||||
@@ -98,19 +103,19 @@ User_config = {
|
||||
}
|
||||
]]
|
||||
font = {
|
||||
regular = "JetBrainsMono Nerd Font, " .. dpi(16),
|
||||
bold = "JetBrainsMono Nerd Font, bold " .. dpi(16),
|
||||
extrabold = "JetBrainsMono Nerd Font, ExtraBold " .. dpi(16),
|
||||
specify = "JetBrainsMono Nerd Font"
|
||||
regular = 'JetBrainsMono Nerd Font, ' .. dpi(16),
|
||||
bold = 'JetBrainsMono Nerd Font, bold ' .. dpi(16),
|
||||
extrabold = 'JetBrainsMono Nerd Font, ExtraBold ' .. dpi(16),
|
||||
specify = 'JetBrainsMono Nerd Font',
|
||||
},
|
||||
|
||||
gtk_settings = "lxappearance",
|
||||
gtk_settings = 'lxappearance',
|
||||
|
||||
--[[
|
||||
The icon theme name must be exactly as the folder is called
|
||||
The folder can be in any $XDG_DATA_DIRS/icons/[icon_theme_name]
|
||||
]] --
|
||||
icon_theme = "Papirus-Dark",
|
||||
icon_theme = 'Papirus-Dark',
|
||||
|
||||
-- List every Keyboard layout you use here comma seperated. (run localectl list-keymaps to list all averiable keymaps)
|
||||
--[[
|
||||
@@ -119,28 +124,15 @@ User_config = {
|
||||
Example:
|
||||
kblayout = { "de", "ru", "us" }
|
||||
]] --
|
||||
kblayout = { "de", "ru" },
|
||||
kblayout = { 'de', 'ru' },
|
||||
|
||||
--[[
|
||||
This is a list of every layout you can use.
|
||||
Remove every that you don't want to use.
|
||||
]] --
|
||||
layouts = {
|
||||
awful.layout.suit.tile,
|
||||
awful.layout.suit.tile.left,
|
||||
awful.layout.suit.tile.bottom,
|
||||
awful.layout.suit.tile.top,
|
||||
awful.layout.suit.floating,
|
||||
awful.layout.suit.fair,
|
||||
awful.layout.suit.fair.horizontal,
|
||||
awful.layout.suit.corner.nw,
|
||||
awful.layout.suit.corner.ne,
|
||||
awful.layout.suit.corner.sw,
|
||||
awful.layout.suit.corner.se,
|
||||
awful.layout.suit.magnifier,
|
||||
awful.layout.suit.max,
|
||||
awful.layout.suit.max.fullscreen,
|
||||
awful.layout.suit.spiral.dwindle,
|
||||
awful.layout.suit.floating,
|
||||
},
|
||||
|
||||
--[[
|
||||
@@ -153,9 +145,9 @@ User_config = {
|
||||
"mod4" <-- for the super/windows key
|
||||
"mod5" <-- for the shift key
|
||||
]] --
|
||||
modkey = "Mod4",
|
||||
modkey = 'Mod4',
|
||||
|
||||
music_player = "flatpak run com.spotify.Client",
|
||||
music_player = 'spotify',
|
||||
|
||||
--[[
|
||||
This is the naming sheme used for the powermenu and maybe some other places in the future.
|
||||
@@ -164,7 +156,7 @@ User_config = {
|
||||
"fullname" <-- Will display "Firstname Surname"
|
||||
"?" <-- Will display "?"
|
||||
]] --
|
||||
namestyle = "userhost",
|
||||
namestyle = 'userhost',
|
||||
|
||||
--[[
|
||||
This is used to identify your network adapters.
|
||||
@@ -174,16 +166,16 @@ User_config = {
|
||||
ethernet = "eno1"
|
||||
]] --
|
||||
network = {
|
||||
wlan = "wlo1",
|
||||
ethernet = "eno1"
|
||||
wlan = 'wlo1',
|
||||
ethernet = 'eno1',
|
||||
},
|
||||
|
||||
screen_settings = "arandr",
|
||||
screen_settings = 'arandr',
|
||||
|
||||
--[[
|
||||
This is the program that will be executed when hitting the print key.
|
||||
]] --
|
||||
screenshot_program = "flameshot gui",
|
||||
screenshot_program = 'flameshot gui',
|
||||
|
||||
--[[
|
||||
These are the status bar widgets which are to be found in the notification-center.
|
||||
@@ -199,13 +191,13 @@ User_config = {
|
||||
"backlight"
|
||||
]] --
|
||||
status_bar_widgets = {
|
||||
"cpu_usage",
|
||||
"cpu_temp",
|
||||
"ram_usage",
|
||||
"microphone",
|
||||
"volume",
|
||||
"gpu_temp",
|
||||
"gpu_usage",
|
||||
'cpu_usage',
|
||||
'cpu_temp',
|
||||
'ram_usage',
|
||||
'microphone',
|
||||
'volume',
|
||||
'gpu_temp',
|
||||
'gpu_usage',
|
||||
},
|
||||
|
||||
--[[
|
||||
@@ -217,9 +209,9 @@ User_config = {
|
||||
--[[
|
||||
This is the default terminal, Alacritty is the default.
|
||||
]] --
|
||||
terminal = "kitty",
|
||||
terminal = 'kitty',
|
||||
|
||||
text_editor = "code",
|
||||
text_editor = 'code',
|
||||
|
||||
--[[
|
||||
Add every client that should get no titlebar.
|
||||
@@ -233,7 +225,7 @@ User_config = {
|
||||
}
|
||||
]] --
|
||||
titlebar_exception = {
|
||||
"protonvpn"
|
||||
'protonvpn',
|
||||
},
|
||||
|
||||
--[[
|
||||
@@ -241,13 +233,19 @@ User_config = {
|
||||
Example:
|
||||
titlebar_position = "top"
|
||||
]] --
|
||||
titlebar_position = "top",
|
||||
titlebar_position = 'left',
|
||||
|
||||
titlebar_items = {
|
||||
left_and_bottom = { 'icon' },
|
||||
--middle = "title",
|
||||
right_and_top = { 'close', 'maximize', 'minimize' },
|
||||
},
|
||||
|
||||
--[[
|
||||
This is the path to your wallpaper.
|
||||
home is $HOME, you can also use an absolute path.
|
||||
]] --
|
||||
wallpaper = home .. "/Bilder/Hintergründe/784194.jpg",
|
||||
wallpaper = home .. '/Bilder/Hintergründe/784194.jpg',
|
||||
|
||||
--[[
|
||||
This is the weather widget.
|
||||
@@ -258,12 +256,12 @@ User_config = {
|
||||
unit = "metric" or "imperial"
|
||||
]]
|
||||
weather_secrets = {
|
||||
key = "e71b00168ca7219563dde4514a425b14",
|
||||
city_id = "2864118",
|
||||
unit = "metric"
|
||||
key = 'e71b00168ca7219563dde4514a425b14',
|
||||
city_id = '2864118',
|
||||
unit = 'metric',
|
||||
},
|
||||
|
||||
web_browser = "firefox",
|
||||
web_browser = 'firefox',
|
||||
|
||||
--[[
|
||||
You can configure your bar's here, if you leave it empty the bar will not be shown.
|
||||
@@ -293,65 +291,64 @@ User_config = {
|
||||
crylia_bar = {
|
||||
[1] = {
|
||||
left_bar = {
|
||||
"Tiling Layout",
|
||||
"Systray",
|
||||
"Taglist"
|
||||
'Tiling Layout',
|
||||
'Systray',
|
||||
'Taglist',
|
||||
},
|
||||
center_bar = {
|
||||
"Tasklist"
|
||||
'Tasklist',
|
||||
},
|
||||
right_bar = {
|
||||
"Cpu Frequency",
|
||||
"Cpu Temperature",
|
||||
"Cpu Usage",
|
||||
"Audio",
|
||||
"Keyboard Layout",
|
||||
"Date",
|
||||
"Clock",
|
||||
"Power Button"
|
||||
}
|
||||
'Bluetooth',
|
||||
'Network',
|
||||
'Cpu Frequency',
|
||||
'Cpu Usage',
|
||||
'Cpu Temperature',
|
||||
'Audio',
|
||||
'Keyboard Layout',
|
||||
'Date',
|
||||
'Clock',
|
||||
'Power Button',
|
||||
},
|
||||
},
|
||||
--[[ [2] = {
|
||||
[2] = {
|
||||
left_bar = {
|
||||
"Tiling Layout",
|
||||
"Systray",
|
||||
"Taglist"
|
||||
'Tiling Layout',
|
||||
'Taglist',
|
||||
},
|
||||
center_bar = {
|
||||
"Tasklist"
|
||||
'Tasklist',
|
||||
},
|
||||
right_bar = {
|
||||
"Gpu Temperature",
|
||||
"Gpu Usage",
|
||||
"Ram",
|
||||
"Audio",
|
||||
"Keyboard Layout",
|
||||
"Date",
|
||||
"Clock",
|
||||
"Power Button"
|
||||
}
|
||||
}]]
|
||||
'Gpu Temperature',
|
||||
'Gpu Usage',
|
||||
'Ram Usage',
|
||||
'Audio',
|
||||
'Date',
|
||||
'Clock',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
crylia_wibox = {
|
||||
[1] = {
|
||||
left_bar = {
|
||||
"Tiling Layout",
|
||||
"Taglist"
|
||||
'Tiling Layout',
|
||||
'Taglist',
|
||||
},
|
||||
center_bar = {
|
||||
"Tasklist"
|
||||
'Tasklist',
|
||||
},
|
||||
right_bar = {
|
||||
"Systray",
|
||||
"Battery",
|
||||
"Bluetooth",
|
||||
"Audio",
|
||||
"Network",
|
||||
"Keyboard Layout",
|
||||
"Date",
|
||||
"Clock",
|
||||
}
|
||||
}
|
||||
}
|
||||
'Systray',
|
||||
'Battery',
|
||||
'Bluetooth',
|
||||
'Audio',
|
||||
'Network',
|
||||
'Keyboard Layout',
|
||||
'Date',
|
||||
'Clock',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
local awful = require("awful")
|
||||
local Gio = require("lgi").Gio
|
||||
local gears = require("gears")
|
||||
local Gio = require('lgi').Gio
|
||||
local aspawn = require('awful.spawn')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
|
||||
return function(table)
|
||||
for _, t in ipairs(table) do
|
||||
awful.spawn(t);
|
||||
aspawn(t);
|
||||
end
|
||||
local path = gears.filesystem.get_xdg_config_home() .. "autostart/"
|
||||
local handler = io.popen("ls " .. path)
|
||||
local path = gfilesystem.get_xdg_config_home() .. 'autostart/'
|
||||
local handler = io.popen('ls ' .. path)
|
||||
if not handler then return end
|
||||
|
||||
for file in handler:lines() do
|
||||
local app = Gio.DesktopAppInfo.new_from_filename(path .. file)
|
||||
if app then
|
||||
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(Gio.DesktopAppInfo.get_string(app,
|
||||
"Exec"), nil, 0))
|
||||
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(Gio.DesktopAppInfo.get_string(app, 'Exec'), nil, 0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
87
awesome/src/tools/config.lua
Normal file
@@ -0,0 +1,87 @@
|
||||
local lgi = require('lgi')
|
||||
local GLib = lgi.GLib
|
||||
local Gio = lgi.Gio
|
||||
local gobject = require('gears.object')
|
||||
local gtable = require('gears.table')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local aspawn = require('awful.spawn')
|
||||
|
||||
local json = require('src.lib.json-lua.json-lua')
|
||||
|
||||
local config = {}
|
||||
|
||||
local instance
|
||||
|
||||
---Takes a file path and puts the content into the callback
|
||||
---@param path string file path, caller has to make sure it exists
|
||||
---@return string|nil file_content
|
||||
config.read = function(path)
|
||||
local handler = io.open(path, 'r')
|
||||
if not handler then error('Invalid path') return end
|
||||
|
||||
local content = handler:read('*all')
|
||||
handler:close()
|
||||
return content
|
||||
end
|
||||
|
||||
---Writes a string to a file
|
||||
---@param path string file path, caller has to make sure it exists
|
||||
---@param content string content to write
|
||||
config.write = function(path, content)
|
||||
local handler = io.open(path, 'w')
|
||||
if not handler then error('Invalid path') return end
|
||||
|
||||
handler:write(content)
|
||||
handler:close()
|
||||
end
|
||||
|
||||
config.read_json = function(path)
|
||||
local handler = io.open(path, 'r')
|
||||
if not handler then error('Invalid path') return end
|
||||
|
||||
local content = handler:read('*all')
|
||||
handler:close()
|
||||
|
||||
local json_content = json:decode(content) or {}
|
||||
assert(type(json_content) == 'table', 'json is not a table')
|
||||
return json_content
|
||||
end
|
||||
|
||||
config.write_json = function(path, content)
|
||||
local json_content = json:encode(content)
|
||||
assert(type(json_content) == 'string', 'json is not a string')
|
||||
|
||||
local handler = io.open(path, 'w')
|
||||
if not handler then error('Invalid path') return end
|
||||
|
||||
handler:write(json_content)
|
||||
handler:close()
|
||||
end
|
||||
|
||||
local function new()
|
||||
local ret = gobject {}
|
||||
|
||||
gtable.crush(ret, config, true)
|
||||
|
||||
-- Create config files if they don't exist
|
||||
for _, file in pairs { 'floating.json', 'dock.json', 'desktop.json', 'applications.json' } do
|
||||
if not gfilesystem.file_readable(gfilesystem.get_configuration_dir() .. 'src/config/' .. file) then
|
||||
aspawn('touch ' .. gfilesystem.get_configuration_dir() .. 'src/config/' .. file)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create config directories if they don't exist
|
||||
for _, dir in pairs { 'files/desktop/icons' } do
|
||||
if not gfilesystem.dir_readable(gfilesystem.get_configuration_dir() .. 'src/config/' .. dir) then
|
||||
gfilesystem.make_directories(gfilesystem.get_configuration_dir() .. 'src/config/' .. dir)
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
|
||||
return instance
|
||||
@@ -1,84 +1,23 @@
|
||||
-- Libraries
|
||||
local lgi = require("lgi")
|
||||
local Gtk = lgi.require("Gtk", "3.0")
|
||||
local Gio = lgi.Gio
|
||||
local gears = require("gears")
|
||||
local GLib = require("lgi").GLib
|
||||
|
||||
-- Get all .desktop files as gobjects
|
||||
local app_info = Gio.AppInfo
|
||||
local app_list = app_info.get_all()
|
||||
local lgi = require('lgi')
|
||||
local Gtk = lgi.require('Gtk', '3.0')
|
||||
|
||||
-- Init a new Gtk theme from the users string
|
||||
local gtk_theme = Gtk.IconTheme.new()
|
||||
Gtk.IconTheme.set_custom_theme(gtk_theme, User_config.icon_theme)
|
||||
local gtk_theme = Gtk.IconTheme.get_default()
|
||||
|
||||
---Gets the icon path from an AppInfo gicon.
|
||||
---@param app Gio.AppInfo
|
||||
---@param app Gio.AppInfo|nil
|
||||
---@param icon_string string|nil
|
||||
---@return string|nil path
|
||||
function Get_gicon_path(app)
|
||||
if not app then return end
|
||||
function Get_gicon_path(app, icon_string)
|
||||
if (not app) and (not icon_string) then return end
|
||||
if icon_string then
|
||||
return gtk_theme:lookup_icon(icon_string, 64, 0):get_filename() or ''
|
||||
end
|
||||
|
||||
local icon_info = gtk_theme:lookup_by_gicon(app, 64, 0)
|
||||
if icon_info then
|
||||
local path = icon_info:get_filename()
|
||||
if path then
|
||||
return path
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
---Takes a class and name string and tries to match it to an icon.
|
||||
---@param class string
|
||||
---@param name string
|
||||
---@return string | nil icon_path
|
||||
function Get_icon(class, name)
|
||||
class = string.lower(class or "")
|
||||
name = string.lower(name or "")
|
||||
for _, app in ipairs(app_list) do
|
||||
local desktop_app_info = Gio.DesktopAppInfo.new(app_info.get_id(app))
|
||||
local icon_string = Gio.DesktopAppInfo.get_string(desktop_app_info, "Icon")
|
||||
if icon_string then
|
||||
icon_string = string.lower(icon_string)
|
||||
if icon_string == class or icon_string == name then
|
||||
return Get_gicon_path(app_info.get_icon(app))
|
||||
elseif icon_string:match(class) then
|
||||
return Get_gicon_path(app_info.get_icon(app))
|
||||
end
|
||||
end
|
||||
return icon_info:get_filename()
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Will return every $XDG_DATA_DIRS
|
||||
---@return table
|
||||
local function get_paths()
|
||||
local dirs = {}
|
||||
|
||||
local dir
|
||||
for _, value in ipairs(GLib.get_system_data_dirs()) do
|
||||
dir = GLib.build_filenamev({ value, "applications" })
|
||||
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
|
||||
end
|
||||
|
||||
dir = GLib.build_filenamev({ GLib.get_user_data_dir(), "applications" })
|
||||
if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end
|
||||
|
||||
return dirs
|
||||
end
|
||||
|
||||
---Returns every .desktop file into a table
|
||||
---@param file string .desktop files
|
||||
---@return string | nil path
|
||||
function Get_desktop_values(file)
|
||||
|
||||
if not file or file == "" then
|
||||
return
|
||||
end
|
||||
|
||||
for _, dir in ipairs(get_paths()) do
|
||||
if gears.filesystem.file_readable(dir .. "/" .. file, "r") then
|
||||
return dir .. "/" .. file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,61 +1,108 @@
|
||||
local aspawn = require("awful.spawn")
|
||||
local aspawn = require('awful.spawn')
|
||||
local gobject = require('gears.object')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local audio = {}
|
||||
|
||||
aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], {
|
||||
stdout = function(line)
|
||||
-- Volume changed
|
||||
if line:match("on sink") or line:match("on source") then
|
||||
capi.awesome.emit_signal("audio::volume_changed")
|
||||
capi.awesome.emit_signal("microphone::volume_changed")
|
||||
end
|
||||
-- Device added/removed
|
||||
if line:match("on server") then
|
||||
capi.awesome.emit_signal("audio::device_changed")
|
||||
capi.awesome.emit_signal("microphone::device_changed")
|
||||
end
|
||||
end,
|
||||
output_done = function()
|
||||
aspawn.with_shell("pkill pactl && pkill grep")
|
||||
end
|
||||
})
|
||||
local instance = nil
|
||||
|
||||
capi.awesome.connect_signal("audio::volume_changed", function()
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/vol.sh mute", function(stdout)
|
||||
if stdout == "" or stdout == nil then
|
||||
return
|
||||
end
|
||||
local muted = false
|
||||
if stdout:match("yes") then
|
||||
muted = true
|
||||
end
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/vol.sh volume", function(stdout2)
|
||||
if stdout == "" or stdout == nil then
|
||||
function audio.set_sink_volume(volume)
|
||||
aspawn('pactl set-sink-volume @DEFAULT_SINK@ ' .. volume .. '%')
|
||||
end
|
||||
|
||||
function audio.set_source_volume(volume)
|
||||
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ ' .. volume .. '%')
|
||||
end
|
||||
|
||||
function audio.sink_volume_up()
|
||||
aspawn('pactl set-sink-volume @DEFAULT_SINK@ +2%')
|
||||
end
|
||||
|
||||
function audio.source_volume_up()
|
||||
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ +2%')
|
||||
end
|
||||
|
||||
function audio.sink_volume_down()
|
||||
aspawn('pactl set-sink-volume @DEFAULT_SINK@ -2%')
|
||||
end
|
||||
|
||||
function audio.source_volume_down()
|
||||
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ -2%')
|
||||
end
|
||||
|
||||
function audio.sink_toggle_mute()
|
||||
aspawn('pactl set-sink-mute @DEFAULT_SINK@ toggle')
|
||||
end
|
||||
|
||||
function audio.source_toggle_mute()
|
||||
aspawn('pactl set-source-mute @DEFAULT_SOURCE@ toggle')
|
||||
end
|
||||
|
||||
local function new()
|
||||
|
||||
local self = gobject {}
|
||||
gtable.crush(self, audio, true)
|
||||
|
||||
aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], {
|
||||
stdout = function(line)
|
||||
-- Volume changed
|
||||
if line:match('on sink') or line:match('on source') then
|
||||
self:emit_signal('sink::volume_changed')
|
||||
self:emit_signal('source::volume_changed')
|
||||
end
|
||||
-- Device added/removed
|
||||
if line:match('on server') then
|
||||
self:emit_signal('sink::device_changed')
|
||||
self:emit_signal('source::device_changed')
|
||||
end
|
||||
end,
|
||||
output_done = function()
|
||||
aspawn.with_shell('pkill pactl && pkill grep')
|
||||
end,
|
||||
})
|
||||
|
||||
self:connect_signal('sink::volume_changed', function()
|
||||
aspawn.easy_async_with_shell([[LC_ALL=C pactl get-sink-mute @DEFAULT_SINK@]], function(stdout)
|
||||
if stdout == '' or stdout == nil then
|
||||
return
|
||||
end
|
||||
capi.awesome.emit_signal("audio::get", muted, stdout2:gsub("%%", ""):gsub("\n", "") or 0)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("microphone::volume_changed", function()
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/mic.sh mute", function(stdout)
|
||||
local muted = false
|
||||
if stdout:match("yes") then
|
||||
muted = true
|
||||
end
|
||||
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/mic.sh volume", function(stdout2)
|
||||
if stdout2 == nil or stdout2 == "awful" then
|
||||
return
|
||||
local muted = false
|
||||
if stdout:match('yes') then
|
||||
muted = true
|
||||
end
|
||||
capi.awesome.emit_signal("microphone::get", muted, stdout2:gsub("%%", ""):gsub("\n", "") or 0)
|
||||
aspawn.easy_async_with_shell([[LC_ALL=C pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}']], function(stdout2)
|
||||
if stdout == '' or stdout == nil then
|
||||
return
|
||||
end
|
||||
self:emit_signal('sink::get', muted, stdout2:gsub('%%', ''):gsub('\n', '') or 0)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
capi.awesome.emit_signal("audio::volume_changed")
|
||||
capi.awesome.emit_signal("microphone::volume_changed")
|
||||
capi.awesome.emit_signal("audio::device_changed")
|
||||
capi.awesome.emit_signal("microphone::device_changed")
|
||||
self:connect_signal('source::volume_changed', function()
|
||||
aspawn.easy_async_with_shell([[LC_ALL=C pactl get-source-mute @DEFAULT_SOURCE@]], function(stdout)
|
||||
local muted = false
|
||||
if stdout:match('yes') then
|
||||
muted = true
|
||||
end
|
||||
aspawn.easy_async_with_shell([[LC_ALL=C pactl get-source-volume @DEFAULT_SOURCE@ | awk '{print $5}']], function(stdout2)
|
||||
if stdout2 == nil or stdout2 == 'awful' then
|
||||
return
|
||||
end
|
||||
self:emit_signal('source::get', muted, stdout2:gsub('%%', ''):gsub('\n', '') or 0)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
self:emit_signal('sink::volume_changed')
|
||||
self:emit_signal('source::volume_changed')
|
||||
self:emit_signal('sink::device_changed')
|
||||
self:emit_signal('source::device_changed')
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
@@ -1,57 +1,41 @@
|
||||
local aspawn = require("awful.spawn")
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local aspawn = require('awful.spawn')
|
||||
local gobject = require('gears.object')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local backlight = {}
|
||||
|
||||
backlight.device = ""
|
||||
local instance = nil
|
||||
|
||||
backlight.max_brightness = 1
|
||||
|
||||
-- Init the backlight device and get the max brightness
|
||||
aspawn.easy_async_with_shell("ls /sys/class/backlight/", function(stdout)
|
||||
backlight.device = stdout:gsub("%s+", "")
|
||||
aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/max_brightness", function(stdout)
|
||||
backlight.max_brightness = tonumber(stdout:gsub("\n", "") or 0)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
function backlight.brightness_get()
|
||||
aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout)
|
||||
capi.awesome.emit_signal("brightness::get", tonumber(stdout))
|
||||
function backlight.brightness_get_async(callback)
|
||||
aspawn.easy_async_with_shell('brightnessctl get', function(stdout)
|
||||
callback(tonumber(stdout:gsub('\n', '')))
|
||||
end)
|
||||
end
|
||||
|
||||
function backlight.brightness_get_percent()
|
||||
aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout)
|
||||
capi.awesome.emit_signal("brightness::get_percent",
|
||||
math.floor((tonumber(stdout) / backlight.max_brightness * 100) + 0.5))
|
||||
function backlight:brightness_increase()
|
||||
aspawn('brightnessctl set +2%')
|
||||
self:emit_signal('brightness_changed')
|
||||
end
|
||||
|
||||
function backlight:brightness_decrease()
|
||||
aspawn('brightnessctl set -2%')
|
||||
self:emit_signal('brightness_changed')
|
||||
end
|
||||
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
|
||||
gtable.crush(self, backlight, true)
|
||||
|
||||
-- Init the backlight device and get the max brightness
|
||||
aspawn.easy_async_with_shell('brightnessctl max', function(stdout)
|
||||
self.max_brightness = tonumber(stdout:gsub('\n', '') or 1)
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function backlight.brightness_set(value)
|
||||
if value < 0 or value > (backlight.max_brightness or 24000) then return end
|
||||
aspawn.with_shell("echo " .. math.floor(value) .. " > /sys/class/backlight/" .. backlight.device .. "/brightness")
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
|
||||
function backlight.brightness_increase()
|
||||
aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout)
|
||||
local new_value = tonumber(stdout:gsub("\n", "") or 0) +
|
||||
(backlight.max_brightness / 100 * User_config.brightness_step)
|
||||
backlight.brightness_set(new_value)
|
||||
capi.awesome.emit_signal("brightness::changed", new_value)
|
||||
end)
|
||||
end
|
||||
|
||||
function backlight.brightness_decrease()
|
||||
aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout)
|
||||
local new_value = tonumber(stdout:gsub("\n", "") or 0) -
|
||||
(backlight.max_brightness / 100 * User_config.brightness_step)
|
||||
backlight.brightness_set(new_value)
|
||||
capi.awesome.emit_signal("brightness::changed", new_value)
|
||||
end)
|
||||
end
|
||||
|
||||
return backlight
|
||||
return instance
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local gobject = require('gears.object')
|
||||
local watch = require('awful.widget.watch')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local instance = nil
|
||||
|
||||
watch(
|
||||
[[ bash -c "cat /proc/cpuinfo | grep "MHz" | awk '{print int($4)}'" ]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
|
||||
watch("bash -c \"cat /proc/cpuinfo | grep 'MHz' | awk '{print int($4)}'\"", 2, function(_, stdout)
|
||||
local cpu_freq = {}
|
||||
|
||||
for value in stdout:gmatch("%d+") do
|
||||
for value in stdout:gmatch('%d+') do
|
||||
table.insert(cpu_freq, value)
|
||||
end
|
||||
|
||||
local average = 0
|
||||
|
||||
if User_config.clock_mode == "average" then
|
||||
if User_config.clock_mode == 'average' then
|
||||
for i = 1, #cpu_freq do
|
||||
average = average + cpu_freq[i]
|
||||
end
|
||||
average = math.floor(average / #cpu_freq)
|
||||
capi.awesome.emit_signal("update::cpu_freq_average", average)
|
||||
average = math.floor((average / #cpu_freq) + 0.5)
|
||||
self:emit_signal('update::cpu_freq_average', average)
|
||||
elseif User_config.clock_mode then
|
||||
capi.awesome.emit_signal("update::cpu_freq_core", cpu_freq[User_config.clock_mode])
|
||||
self:emit_signal('update::cpu_freq_core', cpu_freq[User_config.clock_mode])
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local aspawn = require('awful.spawn')
|
||||
local awatch = require('awful.widget.watch')
|
||||
local gobject = require('gears.object')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local instance = nil
|
||||
|
||||
watch(
|
||||
[[ bash -c "sensors | grep 'Package id 0:' | awk '{print $4}'" ]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
local temp = tonumber(stdout:match("%d+"))
|
||||
if not temp or temp == "" then
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp)",
|
||||
function(stdout2)
|
||||
if (not stdout2) or stdout:match("\n") then return end
|
||||
temp = math.floor((tonumber(stdout2:match("x86_pkg_temp(.%d+)")) / 1000) + 0.5)
|
||||
capi.awesome.emit_signal(
|
||||
"update::cpu_temp",
|
||||
temp
|
||||
)
|
||||
end
|
||||
)
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
|
||||
awatch([[ bash -c "sensors | grep 'Package id 0:' | awk '{print $4}'" ]], 2, function(_, stdout)
|
||||
local temp = tonumber(stdout:match('%d+'))
|
||||
if not temp or temp == '' then
|
||||
aspawn.easy_async_with_shell('paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp)', function(stdout2)
|
||||
if (not stdout2) or stdout:match('\n') then return end
|
||||
temp = math.floor((tonumber(stdout2:match('x86_pkg_temp(.%d+)')) / 1000) + 0.5)
|
||||
self:emit_signal('update::cpu_temp', temp)
|
||||
end)
|
||||
else
|
||||
capi.awesome.emit_signal(
|
||||
"update::cpu_temp",
|
||||
temp
|
||||
)
|
||||
self:emit_signal('update::cpu_temp', temp)
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
@@ -1,32 +1,43 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local aspawn = require('awful.spawn')
|
||||
local gobject = require('gears.object')
|
||||
local gtimer = require('gears.timer')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
local total_prev = 0
|
||||
local idle_prev = 0
|
||||
local instance = nil
|
||||
|
||||
--!Find a better way that doesn't need manual GC since it has a huge performance impact
|
||||
watch(
|
||||
[[ cat "/proc/stat" | grep '^cpu ' ]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
local user, nice, system, idle, iowait, irq, softirq, steal =
|
||||
stdout:match("(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s")
|
||||
local function new()
|
||||
|
||||
local total = user + nice + system + idle + iowait + irq + softirq + steal
|
||||
local self = gobject {}
|
||||
|
||||
local diff_idle = idle - idle_prev
|
||||
local diff_total = total - total_prev
|
||||
local diff_usage = math.floor(((1000 * (diff_total - diff_idle) / diff_total + 5) / 10) + 0.5)
|
||||
local total_prev = 0
|
||||
local idle_prev = 0
|
||||
|
||||
capi.awesome.emit_signal("update::cpu_usage", diff_usage)
|
||||
gtimer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
aspawn.easy_async_with_shell([[ cat "/proc/stat" | grep '^cpu ' ]], function(stdout)
|
||||
local user, nice, system, idle, iowait, irq, softirq, steal =
|
||||
stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s')
|
||||
|
||||
total_prev = total
|
||||
idle_prev = idle
|
||||
local total = user + nice + system + idle + iowait + irq + softirq + steal
|
||||
|
||||
collectgarbage("collect")
|
||||
end
|
||||
)
|
||||
local diff_total = total - total_prev
|
||||
local diff_usage = math.floor(((1000 * (diff_total - (idle - idle_prev)) / diff_total + 5) / 10) + 0.5)
|
||||
|
||||
self:emit_signal('update::cpu_usage', diff_usage)
|
||||
|
||||
total_prev = total
|
||||
idle_prev = idle
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local awatch = require('awful.widget.watch')
|
||||
local gobject = require('gears.object')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local instance = nil
|
||||
|
||||
watch(
|
||||
[[ bash -c "nvidia-smi -q -d TEMPERATURE | grep 'GPU Current Temp' | awk '{print $5}'"]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
if not stdout:gsub("\n", "") then return end
|
||||
capi.awesome.emit_signal("update::gpu_temp", stdout:match("%d+"):gsub("\n", ""))
|
||||
end
|
||||
)
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
awatch([[ bash -c "nvidia-smi -q -d TEMPERATURE | grep 'GPU Current Temp' | awk '{print $5}' | head -n 1"]], 3, function(_, stdout)
|
||||
stdout = stdout:match('%d+')
|
||||
if not stdout then return end
|
||||
self:emit_signal('update::gpu_temp', stdout)
|
||||
end)
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local awatch = require('awful.widget.watch')
|
||||
local gobject = require('gears.object')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local instance
|
||||
|
||||
watch(
|
||||
[[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
stdout = stdout:match("%d+")
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
awatch([[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], 3, function(_, stdout)
|
||||
stdout = stdout:match('%d+')
|
||||
if not stdout then return end
|
||||
capi.awesome.emit_signal("update::gpu_usage", stdout)
|
||||
end
|
||||
)
|
||||
self:emit_signal('update::gpu_usage', stdout)
|
||||
end)
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
48
awesome/src/tools/helpers/kb_helper.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
-- Awesome libs
|
||||
local gobject = require('gears.object')
|
||||
local gtable = require('gears.table')
|
||||
local aspawn = require('awful.spawn')
|
||||
|
||||
local instance = nil
|
||||
local kb_helper = {}
|
||||
|
||||
function kb_helper:cycle_layout()
|
||||
self:get_layout_async(function(layout)
|
||||
local index = gtable.hasitem(self.layout_list, layout)
|
||||
if index then
|
||||
if index == #self.layout_list then
|
||||
self:set_layout(self.layout_list[1])
|
||||
else
|
||||
self:set_layout(self.layout_list[index + 1])
|
||||
end
|
||||
else
|
||||
self:set_layout(self.layout_list[1])
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function kb_helper:set_layout(keymap)
|
||||
aspawn('setxkbmap ' .. keymap)
|
||||
self:emit_signal('KB::layout_changed', keymap)
|
||||
end
|
||||
|
||||
function kb_helper:get_layout_async(callback)
|
||||
aspawn.easy_async_with_shell([[ setxkbmap -query | grep layout | awk '{print $2}' ]], function(stdout)
|
||||
callback(stdout:gsub('\n', ''))
|
||||
end)
|
||||
end
|
||||
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
|
||||
gtable.crush(self, kb_helper, true)
|
||||
|
||||
self.layout_list = User_config.kblayout
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
@@ -1,349 +1,213 @@
|
||||
-- 99.9% Stolen from bling
|
||||
local Playerctl = require('lgi').Playerctl
|
||||
local http_request = require('http.request')
|
||||
local Cairo = require('lgi').cairo
|
||||
local Gdk = require('lgi').Gdk
|
||||
local GdkPixbuf = require('lgi').GdkPixbuf
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtimer = require('gears.timer')
|
||||
local gcolor = require('gears.color')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local gobject = require("gears.object")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local gstring = require("gears.string")
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
Gdk.init {}
|
||||
|
||||
local instance = nil
|
||||
|
||||
local music_player = {}
|
||||
|
||||
--#region Audio control mappings
|
||||
|
||||
function music_player:next() self.player:next() end
|
||||
|
||||
function music_player:prev() self.player:previous() end
|
||||
|
||||
function music_player:play_pause() self.player:play_pause() end
|
||||
|
||||
function music_player:play() self.player:play() end
|
||||
|
||||
function music_player:pause() self.player:pause() end
|
||||
|
||||
--TODO: Needs validation
|
||||
function music_player:get_length()
|
||||
local length = self.player:print_metadata_prop('mpris:length') or 0
|
||||
return tonumber(length) / 1000000
|
||||
end
|
||||
|
||||
function music_player:set_shuffle()
|
||||
self.player:set_shuffle(not self.player.shuffle)
|
||||
end
|
||||
|
||||
-- None, Track, Playlist, loops trough them if not specified
|
||||
function music_player:set_loop_status(state)
|
||||
if state then
|
||||
self.player:set_loop_status(state)
|
||||
return
|
||||
end
|
||||
if self.player.loop_status == 'NONE' then
|
||||
self.player:set_loop_status('PLAYLIST')
|
||||
elseif self.player.loop_status == 'PLAYLIST' then
|
||||
self.player:set_loop_status('TRACK')
|
||||
elseif self.player.loop_status == 'TRACK' then
|
||||
self.player:set_loop_status('NONE')
|
||||
end
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
--#region Metadata getter and setter
|
||||
|
||||
function music_player:get_artist() return self.player:get_artist() end
|
||||
|
||||
function music_player:get_title() return self.player:get_title() end
|
||||
|
||||
function music_player:get_album() return self.player:get_album() end
|
||||
|
||||
function music_player:get_position() return (self.player:get_position() / 1000000) end
|
||||
|
||||
function music_player:set_position() return self.player:set_position() end
|
||||
|
||||
function music_player:get_art(url)
|
||||
url = url or self.player:print_metadata_prop('mpris:artUrl')
|
||||
if url and url:match('^https?://') then
|
||||
local scheme = http_request.new_from_uri(url)
|
||||
if not scheme then return end
|
||||
local headers, stream = assert(scheme:go())
|
||||
if not (stream or headers) then return end
|
||||
local body = assert(stream:get_body_as_string())
|
||||
if headers:get ':status' ~= '200' then
|
||||
error(body)
|
||||
end
|
||||
local loader = GdkPixbuf.PixbufLoader()
|
||||
loader:write(body)
|
||||
loader:close()
|
||||
|
||||
local image = loader:get_pixbuf()
|
||||
|
||||
local surface = Cairo.ImageSurface.create(Cairo.Format.ARGB32, image:get_width(), image:get_height())
|
||||
local cr = Cairo.Context(surface)
|
||||
|
||||
-- Render the image onto the surface
|
||||
Gdk.cairo_set_source_pixbuf(cr, image, 0, 0)
|
||||
cr:paint()
|
||||
|
||||
body = nil
|
||||
loader = nil
|
||||
image = nil
|
||||
collectgarbage()
|
||||
|
||||
return surface
|
||||
elseif url and url:match('^file://') then
|
||||
return url:gsub('%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end):gsub('^file://', '')
|
||||
end
|
||||
return icondir .. 'default_image.svg'
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
local priority_players = {
|
||||
'vlc',
|
||||
'spotify',
|
||||
}
|
||||
|
||||
local playerctl = { mt = {} }
|
||||
playerctl._private = {}
|
||||
function music_player:player_gets_priority(name)
|
||||
-- If for some reason there is no player, manage the new one
|
||||
if not name then return true end
|
||||
|
||||
function playerctl:play_pause(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:play_pause()
|
||||
for _, n in ipairs(priority_players) do
|
||||
if name.name:lower():match(n) then return true end
|
||||
end
|
||||
|
||||
-- If the currently managed player is playing, don't change it
|
||||
if self.player.playback_status == 'PLAYING' then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
function playerctl:next(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:next()
|
||||
end
|
||||
end
|
||||
local function start_manage(self, w, name)
|
||||
|
||||
function playerctl:previous(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:previous()
|
||||
end
|
||||
end
|
||||
if not self:player_gets_priority(name) then return end
|
||||
self.player = Playerctl.Player.new_from_name(name)
|
||||
|
||||
function playerctl:cycle_loop(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
local loop_status = player.loop_status
|
||||
if loop_status == "NONE" then
|
||||
player:set_loop_status("TRACK")
|
||||
elseif loop_status == "TRACK" then
|
||||
player:set_loop_status("PLAYLIST")
|
||||
elseif loop_status == "PLAYLIST" then
|
||||
player:set_loop_status("NONE")
|
||||
end
|
||||
end
|
||||
end
|
||||
self.playermanager:manage_player(self.player)
|
||||
|
||||
function playerctl:cycle_shuffle(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_shuffle(not player.shuffle)
|
||||
end
|
||||
end
|
||||
if not self.player.player_name then return end
|
||||
|
||||
function playerctl:set_position(position, player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_position(position * 1000000)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:get_manager()
|
||||
return self._private.manager
|
||||
end
|
||||
|
||||
function playerctl:get_current_player()
|
||||
return self._private.manager.players[1].name
|
||||
end
|
||||
|
||||
local function emit_metadata_callback(self, title, artist, art_url, album, new, player_name)
|
||||
title = gstring.xml_escape(title)
|
||||
artist = gstring.xml_escape(artist)
|
||||
album = gstring.xml_escape(album)
|
||||
|
||||
if player_name == "spotify" then
|
||||
art_url = art_url:gsub("open.spotify.com", "i.scdn.co")
|
||||
local function on_metadata(_, metadata)
|
||||
if not metadata then return end
|
||||
w:get_children_by_id('title')[1].text = metadata.value['xesam:title'] or 'Unknown Title'
|
||||
w:get_children_by_id('artist')[1].text = metadata.value['xesam:artist'] and metadata.value['xesam:artist'][1] or 'Unknown Artist'
|
||||
local length = (metadata.value['mpris:length'] or 0) / 1000000
|
||||
w:get_children_by_id('length')[1].text = string.format('%02d:%02d', math.floor(length / 60), math.floor(length % 60))
|
||||
w:get_children_by_id('progress')[1].max_value = length
|
||||
w:get_children_by_id('album_art')[1].image = self:get_art(metadata.value['mpris:artUrl'])
|
||||
self.gtimer = gtimer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
local position = self:get_position()
|
||||
w:get_children_by_id('position')[1].text = string.format('%02d:%02d', math.floor(position / 60), math.floor(position % 60))
|
||||
w:get_children_by_id('progress')[1].value = position
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
if not art_url or art_url == "" then
|
||||
else
|
||||
capi.awesome.emit_signal("playerctl::title_artist_album", title, artist, "", player_name)
|
||||
self:emit_signal("metadata", title, artist, "", album, new, player_name)
|
||||
end
|
||||
end
|
||||
self.player.on_metadata = on_metadata
|
||||
on_metadata(nil, self.player.metadata)
|
||||
|
||||
local function metadata_callback(self, player, metadata)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:mover_player_to_front(player)
|
||||
end
|
||||
|
||||
local data = metadata.value
|
||||
local title = data["xesam:title"] or ""
|
||||
local artist = data["xesam:artist"] or ""
|
||||
for i = 2, #data["xesam:artist"] do
|
||||
artist = artist .. ", " .. data["xesam:artist"][i]
|
||||
end
|
||||
local art_url = data["mpris:artUrl"] or ""
|
||||
local album = data["xesam:album"] or ""
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
if (not player == self._private.last_player) or (not title == self._private.manager.last_title) or
|
||||
(not artist == self._private.manager.last_artist) or (not art_url == self._private.manager.last_art_url) then
|
||||
if (title == "") and (artist == "") and (art_url == "") then return end
|
||||
|
||||
if (not self._private.metadata_timer) and self._private.metadata_timer.started then
|
||||
self._private.metadata_timer:stop()
|
||||
end
|
||||
|
||||
self._private.metadata_timer = gtimer {
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
emit_metadata_callback(self, title, artist, art_url, album, true, player.name)
|
||||
end
|
||||
}
|
||||
|
||||
self._private.manager.pos_timer:again()
|
||||
self._private.manager.last_title = title
|
||||
self._private.manager.last_artist = artist
|
||||
self._private.manager.last_art_url = art_url
|
||||
self._private.last_player = player
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function pos_callback(self)
|
||||
local player = self._private.manager.players[1]
|
||||
if player then
|
||||
local pos = player:get_position() / 1000000
|
||||
local dur = (player.metadata.value["mpris:length"] or 0) / 1000000
|
||||
if (not pos == self._private.last_pos) or (not dur == self._private.last_length) then
|
||||
self._private.pos = pos
|
||||
self._private.dur = dur
|
||||
self:emit_signal("position", pos, dur, player.player_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function playback_status_callback(self, player, status)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:mover_player_to_front(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
|
||||
if status == "PLAYING" then
|
||||
self:emit_signal("playerctl::playback_status", true, player.player_name)
|
||||
capi.awesome.emit_signal("playerctl::playback_status", true, player.player_name)
|
||||
local function on_loop_status(_, status)
|
||||
if status == 'TRACK' then
|
||||
w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat-once.svg',
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
elseif status == 'PLAYLIST' then
|
||||
w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat.svg',
|
||||
Theme_config.notification_center.song_info.repeat_all)
|
||||
else
|
||||
self:emit_signal("playerctl::playback_status", false, player.player_name)
|
||||
capi.awesome.emit_signal("playerctl::playback_status", false, player.player_name)
|
||||
w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat.svg',
|
||||
Theme_config.notification_center.song_info.repeat_disabled)
|
||||
end
|
||||
end
|
||||
|
||||
self.player.on_loop_status = on_loop_status
|
||||
on_loop_status(nil, self.player.loop_status)
|
||||
|
||||
local function on_shuffle(_, status)
|
||||
if status then
|
||||
w:get_children_by_id('shuffle')[1].image = gcolor.recolor_image(icondir .. 'shuffle.svg',
|
||||
Theme_config.notification_center.song_info.shuffle_enabled)
|
||||
else
|
||||
w:get_children_by_id('shuffle')[1].image = gcolor.recolor_image(icondir .. 'shuffle.svg',
|
||||
Theme_config.notification_center.song_info.shuffle_disabled)
|
||||
end
|
||||
end
|
||||
|
||||
self.player.on_shuffle = on_shuffle
|
||||
on_shuffle(nil, self.player.shuffle)
|
||||
end
|
||||
|
||||
local function loop_callback(self, player, loop_status)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:mover_player_to_front(player)
|
||||
end
|
||||
if not instance then
|
||||
instance = setmetatable(music_player, { __call = function(_, w)
|
||||
if not w then return end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("loop_status", loop_status, player.player_name)
|
||||
end
|
||||
local ret = {}
|
||||
|
||||
gtable.crush(ret, music_player)
|
||||
|
||||
ret.playermanager = Playerctl.PlayerManager()
|
||||
ret.player = Playerctl.Player()
|
||||
|
||||
if ret.player.player_name then
|
||||
start_manage(ret, w, Playerctl:list_players()[1])
|
||||
end
|
||||
|
||||
ret.playermanager.on_name_appeared = function(_, name)
|
||||
start_manage(ret, w, name)
|
||||
end
|
||||
|
||||
ret.playermanager.on_name_vanished = function()
|
||||
start_manage(ret, w, Playerctl:list_players()[1])
|
||||
end
|
||||
|
||||
return ret
|
||||
end, })
|
||||
end
|
||||
|
||||
local function shuffle_callback(self, player, shuffle)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:mover_player_to_front(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("shuffle", shuffle, player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function exit_callback(self, player)
|
||||
if player == self._private.manager.players[1] then
|
||||
self:emit_signal("playerctl::exit", player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function name_is_selected(self, name)
|
||||
if self.ignore[name.name] then
|
||||
return false
|
||||
end
|
||||
if self.priority > 0 then
|
||||
for _, arg in pairs(self.priority) do
|
||||
if arg == name.name or arg == "%any" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local function init_player(self, name)
|
||||
if name_is_selected(self, name) then
|
||||
local player = self._private.Playerctl.Player.new_from_name(name)
|
||||
self._private.manager:manage_player(player)
|
||||
player.on_metadata = function(p, m)
|
||||
metadata_callback(self, p, m)
|
||||
end
|
||||
player.on_playback_status = function(p, s)
|
||||
playback_status_callback(self, p, s)
|
||||
end
|
||||
player.on_loop_status = function(p, s)
|
||||
loop_callback(self, p, s)
|
||||
end
|
||||
player.on_shuffle = function(p, s)
|
||||
shuffle_callback(self, p, s)
|
||||
end
|
||||
player.on_exit = function(p)
|
||||
exit_callback(self, p)
|
||||
end
|
||||
|
||||
if not self._private.pos_timer.started then
|
||||
self._private.pos_timer:start()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function player_compare(self, a, b)
|
||||
local player_a = self._private.Playerctl.Player(a)
|
||||
local player_b = self._private.Playerctl.Player(b)
|
||||
local i = math.huge
|
||||
local ai = nil
|
||||
local bi = nil
|
||||
|
||||
if player_a == player_b then
|
||||
return 0
|
||||
end
|
||||
|
||||
for index, name in ipairs(self.priority) do
|
||||
if name == "%any" then
|
||||
i = (i == math.huge) and index or i
|
||||
elseif name == player_a.player_name then
|
||||
ai = ai or index
|
||||
elseif name == player_b.player_name then
|
||||
bi = bi or index
|
||||
end
|
||||
end
|
||||
|
||||
if not ai and not bi then
|
||||
return 0
|
||||
elseif not ai then
|
||||
return (bi < i) and 1 or -1
|
||||
elseif not bi then
|
||||
return (ai < i) and -1 or 1
|
||||
elseif ai == bi then
|
||||
return 0
|
||||
else
|
||||
return (ai < bi) and -1 or 1
|
||||
end
|
||||
end
|
||||
|
||||
local function get_current_player(self, player)
|
||||
local title = player:get_title() or "Unknown"
|
||||
local artist = player:get_artist() or "Unknown"
|
||||
local album = player:get_album() or "Unknown"
|
||||
local art_url = player:print_metadata_prop("mpris:artUtl") or ""
|
||||
|
||||
emit_metadata_callback(self, title, artist, art_url, album, false, player.player_name)
|
||||
playback_status_callback(self, player, player.playback_status)
|
||||
loop_callback(self, player, player.loop_status)
|
||||
end
|
||||
|
||||
local function start_manager(self)
|
||||
self._private.manager = self.private.Playerctl.PlayerManager()
|
||||
|
||||
if #self.priority > 0 then
|
||||
self._private.manager:set_sort_func(function(a, b)
|
||||
return player_compare(self, a, b)
|
||||
end)
|
||||
end
|
||||
|
||||
self._private.pos_timer = gtimer {
|
||||
timeout = 1,
|
||||
callback = function()
|
||||
pos_callback(self)
|
||||
end
|
||||
}
|
||||
|
||||
for _, name in ipairs(self._private.manager.player_names) do
|
||||
init_player(self, name)
|
||||
end
|
||||
|
||||
if self._private.manager.players[1] then
|
||||
get_current_player(self, self._private.manager.players[1])
|
||||
end
|
||||
|
||||
local _self = self
|
||||
|
||||
function self._private.manager:on_name_appeared(name)
|
||||
init_player(_self, name)
|
||||
end
|
||||
|
||||
function self._private.manager:on_player_appeared(player)
|
||||
if player == self.players[1] then
|
||||
_self._private.active_player = player
|
||||
end
|
||||
end
|
||||
|
||||
function self._private.manager:on_player_vanished(player)
|
||||
if #self.players == 0 then
|
||||
_self._private.metadata_timer:stop()
|
||||
_self._private.pos_timer:stop()
|
||||
_self:emit_signal("playerctl::noplayers")
|
||||
capi.awesome.emit_signal("playerctl::noplayers")
|
||||
elseif player == _self._private.active_player then
|
||||
_self._private.active_player = self.players[1]
|
||||
get_current_player(_self, _self._private.active_player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl.new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, playerctl, true)
|
||||
|
||||
ret.update_on_activity = true
|
||||
ret.interval = 1
|
||||
|
||||
|
||||
ret._private = {}
|
||||
|
||||
ret._private.Playerctl = require("lgi").Playerctl
|
||||
ret._private.manager = nil
|
||||
|
||||
gtimer.delayed_call(function()
|
||||
start_manager(ret)
|
||||
end)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function playerctl.mt:__call(...)
|
||||
return playerctl.new(...)
|
||||
end
|
||||
|
||||
return setmetatable(playerctl, playerctl.mt)
|
||||
return instance
|
||||
|
||||
35
awesome/src/tools/helpers/pulseaudio.lua
Normal file
@@ -0,0 +1,35 @@
|
||||
package.cpath = package.cpath .. ';./?.so'
|
||||
|
||||
local gobject = require('gears.object')
|
||||
local gtable = require('gears.table')
|
||||
|
||||
local pulseaudio = require('lua_libpulse_glib')
|
||||
|
||||
local p = {}
|
||||
|
||||
function p.new()
|
||||
local ret = gobject {}
|
||||
ret._private = {}
|
||||
|
||||
gtable.crush(ret, p, true)
|
||||
|
||||
local pa = pulseaudio.new()
|
||||
|
||||
local ctx = pa:context('My Test App')
|
||||
|
||||
if not ctx then return end
|
||||
|
||||
ctx:connect(nil, function(state)
|
||||
if state == 4 then
|
||||
print('Connection is ready')
|
||||
|
||||
ctx:get_sinks(function(sinks)
|
||||
print(sinks)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
return setmetatable(p, { __call = function(_, ...) return p.new() end })
|
||||
@@ -1,15 +1,18 @@
|
||||
local awful = require("awful")
|
||||
local watch = awful.widget.watch
|
||||
local awatch = require('awful.widget.watch')
|
||||
local gobject = require('gears.object')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local instance = nil
|
||||
|
||||
watch(
|
||||
[[ bash -c "cat /proc/meminfo| grep Mem | awk '{print $2}'" ]],
|
||||
3,
|
||||
function(_, stdout)
|
||||
local MemTotal, MemFree, MemAvailable = stdout:match("(%d+)\n(%d+)\n(%d+)\n")
|
||||
capi.awesome.emit_signal("update::ram_widget", MemTotal, MemFree, MemAvailable)
|
||||
end
|
||||
)
|
||||
local function new()
|
||||
local self = gobject {}
|
||||
awatch([[ bash -c "cat /proc/meminfo| grep Mem | awk '{print $2}'" ]], 3, function(_, stdout)
|
||||
local MemTotal, MemFree, MemAvailable = stdout:match('(%d+)\n(%d+)\n(%d+)\n')
|
||||
self:emit_signal('update::ram_widget', MemTotal, MemFree, MemAvailable)
|
||||
end)
|
||||
return self
|
||||
end
|
||||
|
||||
if not instance then
|
||||
instance = new()
|
||||
end
|
||||
return instance
|
||||
|
||||
319
awesome/src/tools/hover.lua
Normal file
@@ -0,0 +1,319 @@
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
local rubato = require('src.lib.rubato')
|
||||
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
local function hex_to_rgba(hex)
|
||||
return tonumber(hex:sub(2, 3), 16) / 255,
|
||||
tonumber(hex:sub(4, 5), 16) / 255,
|
||||
tonumber(hex:sub(6, 7), 16) / 255,
|
||||
((tonumber(hex:sub(8, 9), 16) or 255) / 255)
|
||||
end
|
||||
|
||||
local function rgba_to_hex(r, g, b, a)
|
||||
return string.format('%02x%02x%02x%02x', r * 255, g * 255, b * 255, a * 255)
|
||||
end
|
||||
|
||||
local function overlay_color(col, overlay, opacity)
|
||||
if tonumber(col:sub(1, 2), 16) < 128 and tonumber(col:sub(3, 4), 16) < 128 and tonumber(col:sub(5, 6), 16) < 128 then
|
||||
overlay = 'ffffff'
|
||||
else
|
||||
overlay = '000000'
|
||||
end
|
||||
return math.floor((tonumber(overlay:sub(1, 2), 16) * opacity / 100) + tonumber(col:sub(1, 2), 16) * (1 - opacity / 100)),
|
||||
math.floor((tonumber(overlay:sub(3, 4), 16) * opacity / 100) + tonumber(col:sub(3, 4), 16) * (1 - opacity / 100)),
|
||||
math.floor((tonumber(overlay:sub(5, 6), 16) * opacity / 100) + tonumber(col:sub(5, 6), 16) * (1 - opacity / 100)),
|
||||
math.floor((tonumber(overlay:sub(7, 8), 16) or 255 * opacity / 100) + tonumber(col:sub(7, 8), 16) * (1 - opacity / 100))
|
||||
end
|
||||
|
||||
local function bg_hover(args)
|
||||
--[[ args = args or {}
|
||||
local old_cursor, old_wibox
|
||||
|
||||
local _, r, g, b, a = args.widget.bg:get_rgba()
|
||||
|
||||
local animation = {
|
||||
r = rubato.timed {
|
||||
duration = 0.3 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = r * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
g = rubato.timed {
|
||||
duration = 0.3 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = g * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
b = rubato.timed {
|
||||
duration = 0.3 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = b * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
a = rubato.timed {
|
||||
duration = 0.3 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = a * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
}
|
||||
|
||||
local function set_bg()
|
||||
args.widget._private.background = gcolor(string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5)))
|
||||
args.widget:emit_signal('widget::redraw_needed')
|
||||
end
|
||||
|
||||
animation.r:subscribe(set_bg)
|
||||
animation.g:subscribe(set_bg)
|
||||
animation.b:subscribe(set_bg)
|
||||
animation.a:subscribe(set_bg)
|
||||
|
||||
args.widget:connect_signal('mouse::enter', function()
|
||||
if animation.r.running or animation.g.running or animation.b.running or animation.a.running then
|
||||
args.widget._private.background = gcolor(string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5),
|
||||
math.floor(animation.a.target + 0.5)))
|
||||
args.widget:emit_signal('widget::redraw_needed')
|
||||
end
|
||||
_, r, g, b, a = args.widget.bg:get_rgba()
|
||||
animation.r.pos = r * 255
|
||||
animation.g.pos = g * 255
|
||||
animation.b.pos = b * 255
|
||||
animation.a.pos = a * 255
|
||||
|
||||
local w = capi.mouse.current_wibox
|
||||
|
||||
if w then
|
||||
old_cursor, old_wibox = w.cursor, w
|
||||
w.cursor = 'hand1' or args.cursor
|
||||
end
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4)
|
||||
end)
|
||||
|
||||
args.widget:connect_signal('mouse::leave', function()
|
||||
if old_wibox then
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = r * 255, g * 255, b * 255, a * 255
|
||||
end)
|
||||
|
||||
args.widget:connect_signal('button::press', function()
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.press_overlay or 12)
|
||||
end)
|
||||
|
||||
args.widget:connect_signal('button::release', function()
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4)
|
||||
end)
|
||||
|
||||
args.widget:connect_signal('property::bg', function(_, newbg)
|
||||
r, g, b, a = hex_to_rgba(newbg)
|
||||
end) ]]
|
||||
end
|
||||
|
||||
--[[ local function fg_hover(args)
|
||||
args = args or {}
|
||||
local old_cursor, old_wibox
|
||||
|
||||
local _, r, g, b, a = args.widget.fg:get_rgba()
|
||||
|
||||
local animation = {
|
||||
r = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = r * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
g = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = g * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
b = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = b * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
a = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = a * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
}
|
||||
|
||||
local function set_fg()
|
||||
args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5)))
|
||||
end
|
||||
|
||||
animation.r:subscribe(set_fg)
|
||||
animation.g:subscribe(set_fg)
|
||||
animation.b:subscribe(set_fg)
|
||||
animation.a:subscribe(set_fg)
|
||||
|
||||
args.widget:connect_signal('mouse::enter', function()
|
||||
if animation.r.running or animation.g.running or animation.b.running or animation.a.running then
|
||||
args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5), math.floor(animation.a.target + 0.5)))
|
||||
end
|
||||
_, r, g, b, a = args.widget.fg:get_rgba()
|
||||
animation.r.pos = r * 255
|
||||
animation.g.pos = g * 255
|
||||
animation.b.pos = b * 255
|
||||
animation.a.pos = a * 255
|
||||
|
||||
local w = capi.mouse.current_wibox
|
||||
|
||||
if w then
|
||||
old_cursor, old_wibox = w.cursor, w
|
||||
w.cursor = 'hand1' or args.cursor
|
||||
end
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4)
|
||||
end)
|
||||
args.widget:connect_signal('mouse::leave', function()
|
||||
if old_wibox then
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end
|
||||
|
||||
animation.r.target = r * 255
|
||||
animation.g.target = g * 255
|
||||
animation.b.target = b * 255
|
||||
animation.a.target = a * 255
|
||||
end)
|
||||
args.widget:connect_signal('button::press', function()
|
||||
_, r, g, b, a = args.widget.fg:get_rgba()
|
||||
|
||||
args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(r + 0.5), math.floor(g + 0.5), math.floor(b + 0.5), math.floor(a + 0.5)))
|
||||
|
||||
animation.r.pos = r * 255
|
||||
animation.g.pos = g * 255
|
||||
animation.b.pos = b * 255
|
||||
animation.a.pos = a * 255
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 12)
|
||||
end)
|
||||
args.widget:connect_signal('button::release', function()
|
||||
animation.r.target = r * 255
|
||||
animation.g.target = g * 255
|
||||
animation.b.target = b * 255
|
||||
animation.a.target = a * 255
|
||||
end)
|
||||
end ]]
|
||||
|
||||
--[[ local function border_hover(args)
|
||||
args = args or {}
|
||||
local old_cursor, old_wibox
|
||||
|
||||
local r, g, b, a = hex_to_rgba(args.widget.border_color)
|
||||
|
||||
local animation = {
|
||||
r = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = r * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
g = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = g * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
b = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = b * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
a = rubato.timed {
|
||||
duration = 0.2 or args.duration,
|
||||
easing = rubato.easing.linear,
|
||||
pos = a * 255,
|
||||
rate = 24,
|
||||
clamp_position = true,
|
||||
},
|
||||
}
|
||||
|
||||
local function set_border()
|
||||
args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5))
|
||||
end
|
||||
|
||||
animation.r:subscribe(set_border)
|
||||
animation.g:subscribe(set_border)
|
||||
animation.b:subscribe(set_border)
|
||||
animation.a:subscribe(set_border)
|
||||
|
||||
args.widget:connect_signal('mouse::enter', function()
|
||||
if animation.r.running or animation.g.running or animation.b.running or animation.a.running then
|
||||
args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5), math.floor(animation.a.target + 0.5))
|
||||
end
|
||||
r, g, b, a = hex_to_rgba(args.widget.border_color)
|
||||
animation.r.pos = r * 255
|
||||
animation.g.pos = g * 255
|
||||
animation.b.pos = b * 255
|
||||
animation.a.pos = a * 255
|
||||
|
||||
local w = capi.mouse.current_wibox
|
||||
|
||||
if w then
|
||||
old_cursor, old_wibox = w.cursor, w
|
||||
w.cursor = 'hand1' or args.cursor
|
||||
end
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4)
|
||||
end)
|
||||
args.widget:connect_signal('mouse::leave', function()
|
||||
if old_wibox then
|
||||
old_wibox.cursor = old_cursor
|
||||
old_wibox = nil
|
||||
end
|
||||
|
||||
animation.r.target = r * 255
|
||||
animation.g.target = g * 255
|
||||
animation.b.target = b * 255
|
||||
animation.a.target = a * 255
|
||||
end)
|
||||
args.widget:connect_signal('button::press', function()
|
||||
r, g, b, a = hex_to_rgba(args.widget.border_color)
|
||||
|
||||
args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(r + 0.5), math.floor(g + 0.5), math.floor(b + 0.5), math.floor(a + 0.5))
|
||||
|
||||
animation.r.pos = r * 255
|
||||
animation.g.pos = g * 255
|
||||
animation.b.pos = b * 255
|
||||
animation.a.pos = a * 255
|
||||
|
||||
animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 12)
|
||||
end)
|
||||
args.widget:connect_signal('button::release', function()
|
||||
animation.r.target = r * 255
|
||||
animation.g.target = g * 255
|
||||
animation.b.target = b * 255
|
||||
animation.a.target = a * 255
|
||||
end)
|
||||
end ]]
|
||||
|
||||
return {
|
||||
bg_hover = bg_hover,
|
||||
--fg_hover = fg_hover,
|
||||
--border_hover = border_hover,
|
||||
}
|
||||
@@ -2,98 +2,118 @@
|
||||
-- This is the audio widget --
|
||||
------------------------------
|
||||
-- Awesome Libs
|
||||
local abutton = require('awful.button')
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
-- Local libs
|
||||
local audio_controller = require('src.modules.audio.audio_controller')
|
||||
local audio_helper = require('src.tools.helpers.audio')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
require("src.tools.helpers.audio")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local capi = { mouse = mouse }
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
|
||||
|
||||
-- Returns the audio widget
|
||||
return function(s)
|
||||
return setmetatable({}, { __call = function(_, screen)
|
||||
|
||||
local audio_widget = wibox.widget {
|
||||
local ac_popup = apopup {
|
||||
widget = audio_controller,
|
||||
ontop = true,
|
||||
visible = false,
|
||||
screen = screen,
|
||||
border_color = Theme_config.bluetooth_controller.container_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.container_border_width,
|
||||
bg = Theme_config.bluetooth_controller.container_bg,
|
||||
}
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
id = 'icon',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
{
|
||||
id = 'label',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "audio_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
id = 'audio_layout',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "container",
|
||||
id = 'container',
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.audio.bg,
|
||||
fg = Theme_config.audio.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
shape = Theme_config.audio.shape,
|
||||
widget = wibox.container.background,
|
||||
buttons = { gtable.join(
|
||||
abutton({}, 1, function()
|
||||
local geo = capi.mouse.coords()
|
||||
ac_popup.y = dpi(65)
|
||||
ac_popup.x = geo.x - ac_popup.width / 2
|
||||
ac_popup.visible = not ac_popup.visible
|
||||
end)
|
||||
), },
|
||||
}
|
||||
|
||||
capi.awesome.connect_signal("audio::get", function(muted, volume)
|
||||
hover.bg_hover { widget = w }
|
||||
|
||||
local audio_label = w:get_children_by_id('label')[1]
|
||||
local audio_icon = w:get_children_by_id('icon')[1]
|
||||
local audio_spacing = w:get_children_by_id('audio_layout')[1]
|
||||
audio_helper:connect_signal('sink::get', function(_, muted, volume)
|
||||
volume = tonumber(volume)
|
||||
assert(type(volume) == 'number' and type(muted) == 'boolean', 'Invalid arguments')
|
||||
|
||||
if w.volume == volume and w.muted == muted then return end
|
||||
w.volume = volume
|
||||
w.muted = muted
|
||||
|
||||
if muted then
|
||||
audio_widget.container.audio_layout.label.visible = false
|
||||
audio_widget.container.audio_layout.icon_margin.icon_layout.icon:set_image(
|
||||
gears.color.recolor_image(icondir .. "volume-mute" .. ".svg", Theme_config.audio.fg))
|
||||
audio_label.visible = false
|
||||
audio_icon:set_image(gcolor.recolor_image(icondir .. 'volume-mute' .. '.svg', Theme_config.audio.fg))
|
||||
else
|
||||
audio_widget.container:set_right(10)
|
||||
local icon = icondir .. "volume"
|
||||
audio_widget.container.audio_layout.spacing = dpi(5)
|
||||
audio_widget.container.audio_layout.label.visible = true
|
||||
volume = tonumber(volume)
|
||||
if not volume then
|
||||
return
|
||||
end
|
||||
if not volume then return end
|
||||
w.container:set_right(10)
|
||||
audio_spacing.spacing = dpi(5)
|
||||
audio_label.visible = true
|
||||
local icon = icondir .. 'volume'
|
||||
if volume < 1 then
|
||||
icon = icon .. "-mute"
|
||||
audio_widget.container.audio_layout.spacing = dpi(0)
|
||||
audio_widget.container.audio_layout.label.visible = false
|
||||
icon = icon .. '-mute'
|
||||
audio_spacing.spacing = 0
|
||||
audio_label.visible = false
|
||||
elseif volume >= 1 and volume < 34 then
|
||||
icon = icon .. "-low"
|
||||
icon = icon .. '-low'
|
||||
elseif volume >= 34 and volume < 67 then
|
||||
icon = icon .. "-medium"
|
||||
icon = icon .. '-medium'
|
||||
elseif volume >= 67 then
|
||||
icon = icon .. "-high"
|
||||
icon = icon .. '-high'
|
||||
end
|
||||
audio_widget.container.audio_layout.label:set_text(volume .. "%")
|
||||
audio_widget.container.audio_layout.icon_margin.icon_layout.icon:set_image(
|
||||
gears.color.recolor_image(icon .. ".svg", Theme_config.audio.fg))
|
||||
audio_label:set_text(volume .. '%')
|
||||
audio_icon:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.audio.fg))
|
||||
end
|
||||
end)
|
||||
|
||||
-- Signals
|
||||
Hover_signal(audio_widget)
|
||||
|
||||
return audio_widget
|
||||
end
|
||||
return w
|
||||
end, })
|
||||
|
||||
@@ -3,20 +3,23 @@
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local lgi = require("lgi")
|
||||
local naughty = require("naughty")
|
||||
local upower_glib = lgi.require("UPowerGlib")
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local lgi = require('lgi')
|
||||
local naughty = require('naughty')
|
||||
local upower_glib = lgi.require('UPowerGlib')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Local libs
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/battery/"
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/battery/'
|
||||
|
||||
---Returns the battery widget
|
||||
---@return wibox.widget
|
||||
@@ -29,46 +32,46 @@ return function(battery_kind)
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
image = gears.color.recolor_image(icondir .. "battery-unknown.svg", Theme_config.battery.fg),
|
||||
id = 'icon',
|
||||
image = gears.color.recolor_image(icondir .. 'battery-unknown.svg', Theme_config.battery.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = false,
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
id = 'icon_layout',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "icon_margin",
|
||||
id = 'icon_margin',
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
visible = false,
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
id = "label",
|
||||
widget = wibox.widget.textbox
|
||||
id = 'label',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
id = "battery_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
id = 'battery_layout',
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "container",
|
||||
id = 'container',
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.battery.bg,
|
||||
fg = Theme_config.battery.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
-- Color change on mouse over
|
||||
Hover_signal(battery_widget)
|
||||
hover.bg_hover { widget = battery_widget }
|
||||
|
||||
-- Open an energy manager on click
|
||||
battery_widget:connect_signal(
|
||||
@@ -105,9 +108,9 @@ return function(battery_kind)
|
||||
|
||||
local tooltip = awful.tooltip {
|
||||
objects = { battery_widget },
|
||||
mode = "inside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10)
|
||||
mode = 'inside',
|
||||
preferred_alignments = 'middle',
|
||||
margins = dpi(10),
|
||||
}
|
||||
|
||||
---Sets the battery information for the widget
|
||||
@@ -125,50 +128,50 @@ return function(battery_kind)
|
||||
battery_time = device.time_to_full
|
||||
end
|
||||
|
||||
local battery_string = math.floor(battery_time / 3600) .. "h, " .. math.floor((battery_time / 60) % 60) .. "m"
|
||||
local battery_string = math.floor(battery_time / 3600) .. 'h, ' .. math.floor((battery_time / 60) % 60) .. 'm'
|
||||
|
||||
if battery_temp == 0.0 then
|
||||
battery_temp = "NaN"
|
||||
battery_temp = 'NaN'
|
||||
else
|
||||
battery_temp = math.floor(battery_temp + 0.5) .. "°C"
|
||||
battery_temp = math.floor(battery_temp + 0.5) .. '°C'
|
||||
end
|
||||
|
||||
if not battery_percentage then
|
||||
return
|
||||
end
|
||||
|
||||
battery_widget:get_children_by_id("battery_layout")[1].spacing = dpi(5)
|
||||
battery_widget:get_children_by_id("label")[1].visible = true
|
||||
battery_widget:get_children_by_id("label")[1].text = battery_percentage .. '%'
|
||||
battery_widget:get_children_by_id('battery_layout')[1].spacing = dpi(5)
|
||||
battery_widget:get_children_by_id('label')[1].visible = true
|
||||
battery_widget:get_children_by_id('label')[1].text = battery_percentage .. '%'
|
||||
|
||||
tooltip.markup = "<span foreground='#64ffda'>Battery Status:</span> <span foreground='#90caf9'>"
|
||||
.. battery_status .. "</span>\n<span foreground='#64ffda'>Remaining time:</span> <span foreground='#90caf9'>"
|
||||
.. battery_string .. "</span>\n<span foreground='#64ffda'>Temperature:</span> <span foreground='#90caf9'>"
|
||||
.. battery_temp .. "</span>"
|
||||
.. battery_temp .. '</span>'
|
||||
|
||||
local icon = 'battery'
|
||||
|
||||
if battery_status == 'fully-charged' or battery_status == 'charging' and battery_percentage == 100 then
|
||||
icon = icon .. '-' .. 'charging.svg'
|
||||
naughty.notification {
|
||||
title = "Battery notification",
|
||||
message = "Battery is fully charged",
|
||||
title = 'Battery notification',
|
||||
message = 'Battery is fully charged',
|
||||
icon = icondir .. icon,
|
||||
timeout = 5
|
||||
timeout = 5,
|
||||
}
|
||||
battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir
|
||||
battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir
|
||||
.. icon, Theme_config.battery.fg))
|
||||
return
|
||||
elseif battery_percentage > 0 and battery_percentage < 10 and battery_status == 'discharging' then
|
||||
icon = icon .. '-' .. 'alert.svg'
|
||||
naughty.notification {
|
||||
title = "Battery warning",
|
||||
message = "Battery is running low!\n" .. battery_percentage .. "% left",
|
||||
urgency = "critical",
|
||||
title = 'Battery warning',
|
||||
message = 'Battery is running low!\n' .. battery_percentage .. '% left',
|
||||
urgency = 'critical',
|
||||
icon = icondir .. icon,
|
||||
timeout = 60
|
||||
timeout = 60,
|
||||
}
|
||||
battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir
|
||||
battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir
|
||||
.. icon, Theme_config.battery.fg))
|
||||
return
|
||||
end
|
||||
@@ -195,9 +198,9 @@ return function(battery_kind)
|
||||
icon = icon .. '-' .. battery_status .. '-' .. '90'
|
||||
end
|
||||
|
||||
battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir ..
|
||||
battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir ..
|
||||
icon .. '.svg', Theme_config.battery.fg))
|
||||
capi.awesome.emit_signal("update::battery_widget", battery_percentage, icondir .. icon .. ".svg")
|
||||
capi.awesome.emit_signal('update::battery_widget', battery_percentage, icondir .. icon .. '.svg')
|
||||
|
||||
end
|
||||
|
||||
@@ -208,12 +211,12 @@ return function(battery_kind)
|
||||
---Will report to the bluetooth widget.
|
||||
---@param path string device path /org/freedesktop/...
|
||||
local function attach_to_device(path)
|
||||
local device_path = User_config.battery_path or path or ""
|
||||
local device_path = User_config.battery_path or path or ''
|
||||
|
||||
battery_widget.device = get_device_from_path(device_path) or upower_glib.Client():get_display_device()
|
||||
|
||||
battery_widget.device.on_notify = function(device)
|
||||
battery_widget:emit_signal("upower::update", device)
|
||||
battery_widget:emit_signal('upower::update', device)
|
||||
end
|
||||
|
||||
-- Check which device kind the user wants to display
|
||||
@@ -223,7 +226,7 @@ return function(battery_kind)
|
||||
end
|
||||
|
||||
-- The delayed call will fire every time awesome finishes its main event loop
|
||||
gears.timer.delayed_call(battery_widget.emit_signal, battery_widget, "upower::update", battery_widget.device)
|
||||
gears.timer.delayed_call(battery_widget.emit_signal, battery_widget, 'upower::update', battery_widget.device)
|
||||
end
|
||||
|
||||
for _, device in ipairs(get_device_path()) do
|
||||
@@ -231,7 +234,7 @@ return function(battery_kind)
|
||||
end
|
||||
|
||||
battery_widget:connect_signal(
|
||||
"upower::update",
|
||||
'upower::update',
|
||||
function(_, device)
|
||||
if upower_glib.DeviceKind[battery_widget.device.kind] == battery_kind then
|
||||
set_battery(device)
|
||||
|
||||
@@ -3,21 +3,22 @@
|
||||
----------------------------------
|
||||
|
||||
-- Awesome libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local awful = require('awful')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Own libs
|
||||
local bt_module = require("src.modules.bluetooth.init")
|
||||
local bt_module = require('src.modules.bluetooth.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/'
|
||||
|
||||
-- Returns the bluetooth widget
|
||||
return function(s)
|
||||
@@ -29,29 +30,31 @@ return function(s)
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
image = gears.color.recolor_image(icondir .. "bluetooth-off.svg", Theme_config.bluetooth.fg),
|
||||
id = 'icon',
|
||||
image = gears.color.recolor_image(icondir .. 'bluetooth-off.svg', Theme_config.bluetooth.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = false,
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
id = 'icon_layout',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "icon_margin",
|
||||
id = 'icon_margin',
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.bluetooth.bg,
|
||||
fg = Theme_config.bluetooth.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = bluetooth_widget }
|
||||
|
||||
-- If bt_widget is nil then there is no bluetooth adapter and there shouldn't be done
|
||||
-- anything besides returning the widget without any logic behind
|
||||
if not bt_widget then
|
||||
@@ -67,27 +70,24 @@ return function(s)
|
||||
screen = s,
|
||||
border_color = Theme_config.bluetooth_controller.container_border_color,
|
||||
border_width = Theme_config.bluetooth_controller.container_border_width,
|
||||
bg = Theme_config.bluetooth_controller.container_bg
|
||||
bg = Theme_config.bluetooth_controller.container_bg,
|
||||
}
|
||||
|
||||
-- When the status changes update the icon
|
||||
bt_widget:connect_signal("bluetooth::status", function(status)
|
||||
bluetooth_widget:get_children_by_id("icon")[1].image = gears.color.recolor_image(status._private.Adapter1.Powered and
|
||||
icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg", Theme_config.bluetooth.fg)
|
||||
bt_widget:connect_signal('bluetooth::status', function(status)
|
||||
bluetooth_widget:get_children_by_id('icon')[1].image = gears.color.recolor_image(status._private.Adapter1.Powered and
|
||||
icondir .. 'bluetooth-on.svg' or icondir .. 'bluetooth-off.svg', Theme_config.bluetooth.fg)
|
||||
end)
|
||||
|
||||
-- Hover signal to change color when mouse is over
|
||||
Hover_signal(bluetooth_widget)
|
||||
|
||||
-- On left click toggle the bluetooth container else toggle the bluetooth on/off
|
||||
bluetooth_widget:connect_signal("button::press", function(_, _, _, key)
|
||||
bluetooth_widget:connect_signal('button::press', function(_, _, _, key)
|
||||
if key == 1 then
|
||||
local geo = capi.mouse.current_wibox:geometry()
|
||||
bluetooth_container.x = geo.x
|
||||
bluetooth_container.y = geo.y + dpi(55)
|
||||
bluetooth_container.visible = not bluetooth_container.visible
|
||||
else
|
||||
capi.awesome.emit_signal("toggle_bluetooth")
|
||||
capi.awesome.emit_signal('toggle_bluetooth')
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@@ -3,62 +3,55 @@
|
||||
------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Local libs
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/clock/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/clock/'
|
||||
|
||||
-- Returns the clock widget
|
||||
return function()
|
||||
|
||||
return setmetatable({}, { __call = function()
|
||||
local clock_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
image = gears.color.recolor_image(icondir .. "clock.svg", Theme_config.clock.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
image = gcolor.recolor_image(icondir .. 'clock.svg', Theme_config.clock.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
},
|
||||
id = "icon_margin",
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
format = '%H:%M',
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
format = "%H:%M",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
id = "clock_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.clock.bg,
|
||||
fg = Theme_config.clock.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
shape = Theme_config.clock.shape,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
Hover_signal(clock_widget)
|
||||
hover.bg_hover { widget = clock_widget }
|
||||
|
||||
return clock_widget
|
||||
end
|
||||
end, })
|
||||
|
||||
@@ -3,217 +3,234 @@
|
||||
---------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local color = require("src.lib.color")
|
||||
local rubato = require("src.lib.rubato")
|
||||
-- Third Party Libs
|
||||
local color = require('src.lib.color')
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
require("src.tools.helpers.cpu_freq")
|
||||
require("src.tools.helpers.cpu_temp")
|
||||
require("src.tools.helpers.cpu_usage")
|
||||
local icon_dir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/cpu/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local cpu_info = {}
|
||||
|
||||
local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/"
|
||||
local function cpu_temp_new()
|
||||
local cpu_temp_helper = require('src.tools.helpers.cpu_temp')
|
||||
|
||||
--TODO: Add tooltip with more CPU and per core information
|
||||
return function(widget)
|
||||
|
||||
local cpu_usage_widget = wibox.widget {
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icon_dir .. "cpu.svg", Theme_config.cpu_usage.fg),
|
||||
resize = false
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icon_dir .. 'thermometer.svg', Theme_config.cpu_temp.fg),
|
||||
resize = true,
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "cpu_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = Theme_config.cpu_usage.bg,
|
||||
fg = Theme_config.cpu_usage.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local cpu_temp = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
image = gears.color.recolor_image(icon_dir .. "thermometer.svg", Theme_config.cpu_temp.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
id = 'text_role',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "cpu_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.cpu_temp.bg_low,
|
||||
bg = Theme_config.cpu_temp.bg,
|
||||
fg = Theme_config.cpu_temp.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
shape = Theme_config.cpu_temp.shape,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
local cpu_clock = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icon_dir .. "cpu.svg", Theme_config.cpu_freq.fg),
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "cpu_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = Theme_config.cpu_freq.bg,
|
||||
fg = Theme_config.cpu_freq.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
assert(w, 'Failed to create widget')
|
||||
|
||||
capi.awesome.connect_signal("update::cpu_usage", function(usage)
|
||||
cpu_usage_widget.container.cpu_layout.label.text = usage .. "%"
|
||||
end)
|
||||
gtable.crush(w, cpu_info, true)
|
||||
|
||||
local r_timed_cpu_bg = rubato.timed { duration = 2.5 }
|
||||
local g_timed_cpu_bg = rubato.timed { duration = 2.5 }
|
||||
local b_timed_cpu_bg = rubato.timed { duration = 2.5 }
|
||||
local r = rubato.timed { duration = 2.5 }
|
||||
local g = rubato.timed { duration = 2.5 }
|
||||
local b = rubato.timed { duration = 2.5 }
|
||||
|
||||
r_timed_cpu_bg.pos, g_timed_cpu_bg.pos, b_timed_cpu_bg.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low)
|
||||
r.pos, g.pos, b.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low)
|
||||
|
||||
-- Subscribable function to have rubato set the bg/fg color
|
||||
local function update_bg()
|
||||
cpu_temp:set_bg("#" .. color.utils.rgba_to_hex { r_timed_cpu_bg.pos, g_timed_cpu_bg.pos, b_timed_cpu_bg.pos })
|
||||
w:set_bg('#' .. color.utils.rgba_to_hex { r.pos, g.pos, b.pos })
|
||||
end
|
||||
|
||||
r_timed_cpu_bg:subscribe(update_bg)
|
||||
g_timed_cpu_bg:subscribe(update_bg)
|
||||
b_timed_cpu_bg:subscribe(update_bg)
|
||||
r:subscribe(update_bg)
|
||||
g:subscribe(update_bg)
|
||||
b:subscribe(update_bg)
|
||||
|
||||
-- Both functions to set a color, if called they take a new color
|
||||
local function set_bg(newbg)
|
||||
r_timed_cpu_bg.target, g_timed_cpu_bg.target, b_timed_cpu_bg.target = color.utils.hex_to_rgba(newbg)
|
||||
r.target, g.target, b.target = color.utils.hex_to_rgba(newbg)
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal("update::cpu_temp", function(temp)
|
||||
cpu_temp_helper:connect_signal('update::cpu_temp', function(_, temp)
|
||||
local temp_icon
|
||||
local temp_color
|
||||
|
||||
if temp < 50 then
|
||||
temp_color = Theme_config.cpu_temp.bg_low
|
||||
temp_icon = icon_dir .. "thermometer-low.svg"
|
||||
temp_icon = icon_dir .. 'thermometer-low.svg'
|
||||
elseif temp >= 50 and temp < 80 then
|
||||
temp_color = Theme_config.cpu_temp.bg_mid
|
||||
temp_icon = icon_dir .. "thermometer.svg"
|
||||
temp_icon = icon_dir .. 'thermometer.svg'
|
||||
elseif temp >= 80 then
|
||||
temp_color = Theme_config.cpu_temp.bg_high
|
||||
temp_icon = icon_dir .. "thermometer-high.svg"
|
||||
temp_icon = icon_dir .. 'thermometer-high.svg'
|
||||
end
|
||||
cpu_temp.container.cpu_layout.icon_margin.icon_layout.icon:set_image(temp_icon)
|
||||
w:get_children_by_id('icon_role')[1].image = temp_icon
|
||||
set_bg(temp_color)
|
||||
cpu_temp.container.cpu_layout.label.text = math.floor(temp) .. "°C"
|
||||
capi.awesome.emit_signal("update::cpu_temp_widget", temp, temp_icon)
|
||||
w:get_children_by_id('text_role')[1].text = math.floor(temp) .. '°C'
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("update::cpu_freq_average", function(average)
|
||||
cpu_clock.container.cpu_layout.label.text = average .. "Mhz"
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal("update::cpu_freq_core", function(freq)
|
||||
cpu_clock.container.cpu_layout.label.text = freq .. "Mhz"
|
||||
end)
|
||||
|
||||
Hover_signal(cpu_temp)
|
||||
Hover_signal(cpu_usage_widget)
|
||||
Hover_signal(cpu_clock)
|
||||
|
||||
if widget == "usage" then
|
||||
return cpu_usage_widget
|
||||
elseif widget == "temp" then
|
||||
return cpu_temp
|
||||
elseif widget == "freq" then
|
||||
return cpu_clock
|
||||
end
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
local function cpu_usage_new()
|
||||
local cpu_usage_helper = require('src.tools.helpers.cpu_usage')
|
||||
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icon_dir .. 'cpu.svg', Theme_config.cpu_usage.fg),
|
||||
resize = true,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
id = 'text_role',
|
||||
text = '0%',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.cpu_usage.bg,
|
||||
fg = Theme_config.cpu_usage.fg,
|
||||
shape = Theme_config.cpu_usage.shape,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(w, 'failed to create widget')
|
||||
|
||||
hover.bg_hover { widget = w }
|
||||
|
||||
gtable.crush(w, cpu_info, true)
|
||||
|
||||
cpu_usage_helper:connect_signal('update::cpu_usage', function(_, usage)
|
||||
w:get_children_by_id('text_role')[1].text = usage .. '%'
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
local function cpu_freq_new()
|
||||
local cpu_freq_helper = require('src.tools.helpers.cpu_freq')
|
||||
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icon_dir .. 'cpu.svg', Theme_config.cpu_freq.fg),
|
||||
resize = true,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
id = 'text_role',
|
||||
text = '0Mhz',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.cpu_freq.bg,
|
||||
fg = Theme_config.cpu_freq.fg,
|
||||
shape = Theme_config.cpu_freq.shape,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(w, 'failed to create widget')
|
||||
|
||||
hover.bg_hover { widget = w }
|
||||
|
||||
gtable.crush(w, cpu_info, true)
|
||||
|
||||
cpu_freq_helper:connect_signal('update::cpu_freq_average', function(_, average)
|
||||
w:get_children_by_id('text_role')[1].text = average .. 'Mhz'
|
||||
end)
|
||||
|
||||
cpu_freq_helper:connect_signal('update::cpu_freq_core', function(_, freq)
|
||||
w:get_children_by_id('text_role')[1].text = freq .. 'Mhz'
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
return setmetatable(cpu_info, { __call = function(_, widget)
|
||||
if widget == 'temp' then
|
||||
return cpu_temp_new()
|
||||
elseif widget == 'usage' then
|
||||
return cpu_usage_new()
|
||||
elseif widget == 'freq' then
|
||||
return cpu_freq_new()
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end, })
|
||||
|
||||
@@ -3,83 +3,81 @@
|
||||
-----------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local apopup = require('awful.popup')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local abutton = require('awful.button')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local gcolor = require('gears.color')
|
||||
|
||||
-- Local libs
|
||||
local cal = require('src.modules.calendar.init') {}
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/date/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/date/'
|
||||
|
||||
local capi = { mouse = mouse }
|
||||
|
||||
-- Returns the date widget
|
||||
return function(s)
|
||||
local cal = require("src.modules.calendar.init") { screen = s }
|
||||
|
||||
return setmetatable({}, { __call = function(_, screen)
|
||||
local date_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
image = gears.color.recolor_image(icondir .. "calendar.svg", Theme_config.date.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
image = gcolor.recolor_image(icondir .. 'calendar.svg', Theme_config.date.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
resize = true,
|
||||
},
|
||||
id = "icon_margin",
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
format = '%a, %b %d',
|
||||
widget = wibox.widget.textclock,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
format = "%a, %b %d",
|
||||
widget = wibox.widget.textclock
|
||||
},
|
||||
id = "date_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.date.bg,
|
||||
fg = Theme_config.date.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
shape = Theme_config.date.shape,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
local calendar_popup = awful.popup {
|
||||
local calendar_popup = apopup {
|
||||
widget = cal:get_widget(),
|
||||
screen = s,
|
||||
screen = screen,
|
||||
ontop = true,
|
||||
bg = "#00000000",
|
||||
visible = false,
|
||||
}
|
||||
|
||||
-- Signals
|
||||
Hover_signal(date_widget)
|
||||
hover.bg_hover { widget = date_widget }
|
||||
|
||||
date_widget:buttons {
|
||||
gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
local geo = mouse.current_wibox:geometry()
|
||||
calendar_popup.x = geo.x
|
||||
calendar_popup.y = geo.y + dpi(55)
|
||||
calendar_popup.visible = not calendar_popup.visible
|
||||
end)
|
||||
)
|
||||
}
|
||||
date_widget:buttons { gtable.join(
|
||||
abutton({}, 1, function()
|
||||
local geo = capi.mouse.coords()
|
||||
calendar_popup.y = dpi(65)
|
||||
if geo.x + (calendar_popup.width / 2) > capi.mouse.screen.geometry.width then
|
||||
calendar_popup.x = capi.mouse.screen.geometry.x + capi.mouse.screen.geometry.width - calendar_popup.width
|
||||
else
|
||||
calendar_popup.x = geo.x - (calendar_popup.width / 2)
|
||||
end
|
||||
calendar_popup.visible = not calendar_popup.visible
|
||||
end)
|
||||
), }
|
||||
|
||||
return date_widget
|
||||
end
|
||||
end, })
|
||||
|
||||
@@ -3,179 +3,173 @@
|
||||
---------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local color = require("src.lib.color")
|
||||
local rubato = require("src.lib.rubato")
|
||||
-- Third Party Libs
|
||||
local color = require('src.lib.color')
|
||||
local rubato = require('src.lib.rubato')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
require("src.tools.helpers.gpu_temp")
|
||||
require("src.tools.helpers.gpu_usage")
|
||||
local icon_dir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/cpu/'
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local gpu_info = {}
|
||||
|
||||
local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/"
|
||||
local function gpu_temp_new()
|
||||
local gpu_temp_helper = require('src.tools.helpers.gpu_temp')
|
||||
|
||||
return function(widget)
|
||||
|
||||
local gpu_usage_widget = wibox.widget {
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icon_dir .. "gpu.svg", Theme_config.gpu_usage.fg),
|
||||
resize = false
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icon_dir .. 'gpu.svg', Theme_config.gpu_temp.fg),
|
||||
resize = true,
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "gpu_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = Theme_config.gpu_usage.bg,
|
||||
fg = Theme_config.gpu_usage.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local gpu_temp_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icon_dir .. "gpu.svg", Theme_config.gpu_temp.fg),
|
||||
resize = false
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
id = 'text_role',
|
||||
text = '0°C',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "gpu_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.gpu_temp.bg_low,
|
||||
bg = Theme_config.gpu_temp.bg,
|
||||
fg = Theme_config.gpu_temp.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
shape = Theme_config.gpu_temp.shape,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
Hover_signal(gpu_temp_widget)
|
||||
Hover_signal(gpu_usage_widget)
|
||||
assert(w, 'Widget not created')
|
||||
|
||||
-- GPU Utilization
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_usage",
|
||||
function(stdout)
|
||||
gpu_usage_widget.container.gpu_layout.label.text = stdout:gsub("\n", "") .. "%"
|
||||
end
|
||||
)
|
||||
local r = rubato.timed { duration = 2.5 }
|
||||
local g = rubato.timed { duration = 2.5 }
|
||||
local b = rubato.timed { duration = 2.5 }
|
||||
|
||||
local r_timed_gpu_bg = rubato.timed { duration = 2.5 }
|
||||
local g_timed_gpu_bg = rubato.timed { duration = 2.5 }
|
||||
local b_timed_gpu_bg = rubato.timed { duration = 2.5 }
|
||||
|
||||
r_timed_gpu_bg.pos, g_timed_gpu_bg.pos, b_timed_gpu_bg.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low)
|
||||
r.pos, g.pos, b.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low)
|
||||
|
||||
-- Subscribable function to have rubato set the bg/fg color
|
||||
local function update_bg()
|
||||
gpu_temp_widget:set_bg("#" ..
|
||||
color.utils.rgba_to_hex { math.max(0, r_timed_gpu_bg.pos), math.max(0, g_timed_gpu_bg.pos),
|
||||
math.max(0, b_timed_gpu_bg.pos) })
|
||||
w:set_bg('#' .. color.utils.rgba_to_hex { math.max(0, r.pos), math.max(0, g.pos),
|
||||
math.max(0, b.pos), })
|
||||
end
|
||||
|
||||
r_timed_gpu_bg:subscribe(update_bg)
|
||||
g_timed_gpu_bg:subscribe(update_bg)
|
||||
b_timed_gpu_bg:subscribe(update_bg)
|
||||
r:subscribe(update_bg)
|
||||
g:subscribe(update_bg)
|
||||
b:subscribe(update_bg)
|
||||
|
||||
-- Both functions to set a color, if called they take a new color
|
||||
local function set_bg(newbg)
|
||||
r_timed_gpu_bg.target, g_timed_gpu_bg.target, b_timed_gpu_bg.target = color.utils.hex_to_rgba(newbg)
|
||||
r.target, g.target, b.target = color.utils.hex_to_rgba(newbg)
|
||||
end
|
||||
|
||||
-- GPU Temperature
|
||||
capi.awesome.connect_signal(
|
||||
"update::gpu_temp",
|
||||
function(stdout)
|
||||
|
||||
local temp_icon
|
||||
local temp_color
|
||||
local temp_num = tonumber(stdout) or "N/A"
|
||||
|
||||
if temp_num then
|
||||
|
||||
if temp_num < 50 then
|
||||
temp_color = Theme_config.gpu_temp.bg_low
|
||||
temp_icon = icon_dir .. "thermometer-low.svg"
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_color = Theme_config.gpu_temp.bg_mid
|
||||
temp_icon = icon_dir .. "thermometer.svg"
|
||||
elseif temp_num >= 80 then
|
||||
temp_color = Theme_config.gpu_temp.bg_high
|
||||
temp_icon = icon_dir .. "thermometer-high.svg"
|
||||
end
|
||||
else
|
||||
temp_num = "N/A"
|
||||
gpu_temp_helper:connect_signal('update::gpu_temp', function(_, stdout)
|
||||
local temp_icon
|
||||
local temp_color
|
||||
local temp_num = tonumber(stdout) or 0
|
||||
if temp_num then
|
||||
if temp_num < 50 then
|
||||
temp_color = Theme_config.gpu_temp.bg_low
|
||||
temp_icon = icon_dir .. "thermometer-low.svg"
|
||||
temp_icon = icon_dir .. 'thermometer-low.svg'
|
||||
elseif temp_num >= 50 and temp_num < 80 then
|
||||
temp_color = Theme_config.gpu_temp.bg_mid
|
||||
temp_icon = icon_dir .. 'thermometer.svg'
|
||||
elseif temp_num >= 80 then
|
||||
temp_color = Theme_config.gpu_temp.bg_high
|
||||
temp_icon = icon_dir .. 'thermometer-high.svg'
|
||||
end
|
||||
gpu_temp_widget.container.gpu_layout.icon_margin.icon_layout.icon:set_image(temp_icon)
|
||||
set_bg(temp_color)
|
||||
gpu_temp_widget.container.gpu_layout.label.text = tostring(temp_num) .. "°C"
|
||||
else
|
||||
temp_color = Theme_config.gpu_temp.bg_low
|
||||
temp_icon = icon_dir .. 'thermometer-low.svg'
|
||||
end
|
||||
)
|
||||
w:get_children_by_id('icon_role')[1]:set_image(temp_icon)
|
||||
set_bg(temp_color)
|
||||
w:get_children_by_id('text_role')[1].text = tostring(temp_num) .. '°C'
|
||||
end)
|
||||
|
||||
if widget == "usage" then
|
||||
return gpu_usage_widget
|
||||
elseif widget == "temp" then
|
||||
return gpu_temp_widget
|
||||
end
|
||||
return w
|
||||
end
|
||||
|
||||
local function gpu_usage_new()
|
||||
local gpu_usage_helper = require('src.tools.helpers.gpu_usage')
|
||||
|
||||
local w = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icon_dir .. 'gpu.svg', Theme_config.gpu_usage.fg),
|
||||
resize = true,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(25),
|
||||
height = dpi(25),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
id = 'text_role',
|
||||
text = '0%',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.gpu_usage.bg,
|
||||
fg = Theme_config.gpu_usage.fg,
|
||||
shape = Theme_config.gpu_usage.shape,
|
||||
widget = wibox.container.background,
|
||||
})
|
||||
|
||||
assert(w, 'Widget not created')
|
||||
|
||||
hover.bg_hover { widget = w }
|
||||
|
||||
gpu_usage_helper:connect_signal('update::gpu_usage', function(_, stdout)
|
||||
w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '') .. '%'
|
||||
end)
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
return setmetatable(gpu_info, { __call = function(_, widget)
|
||||
if widget == 'usage' then
|
||||
return gpu_usage_new()
|
||||
elseif widget == 'temp' then
|
||||
return gpu_temp_new()
|
||||
end
|
||||
end, })
|
||||
|
||||
@@ -3,395 +3,278 @@
|
||||
------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local wibox = require('wibox')
|
||||
local gcolor = require('gears.color')
|
||||
local gfilesystem = require('gears.filesystem')
|
||||
local gtable = require('gears.table')
|
||||
local abutton = require('awful.button')
|
||||
local apopup = require('awful.popup')
|
||||
|
||||
-- Local libs
|
||||
local kb_helper = require('src.tools.helpers.kb_helper')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mousegrabber = mousegrabber,
|
||||
mouse = mouse,
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/kblayout/"
|
||||
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/kblayout/'
|
||||
|
||||
return function(s)
|
||||
local kb_layout_popup
|
||||
|
||||
local function create_kb_layout_list()
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
id = 'list',
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(10),
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(10),
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.kblayout.bg_container,
|
||||
}
|
||||
|
||||
local list = widget:get_children_by_id('list')[1]
|
||||
for _, keymap in pairs(User_config.kblayout) do
|
||||
-- TODO: Add more, too lazy rn
|
||||
local xkeyboard_country_code = {
|
||||
['af'] = { 'أفغانيش(Afghanistan)', 'AFG' }, -- Afghanistan
|
||||
['al'] = { 'Shqip(Albania)', 'ALB' }, -- Albania
|
||||
['am'] = { 'Hայերեն(Armenia)', 'ARM' }, -- Armenia
|
||||
['ara'] = { 'عربي(Arab)', 'ARB' }, -- Arabic
|
||||
['at'] = { 'Österreichisch (Austria)', 'AUT' }, -- Austria
|
||||
['az'] = { 'Azərbaycan(Azerbaijan)', 'AZE' }, -- Azerbaijan
|
||||
['ba'] = { 'Bosanski(Bosnia and Herzegovina)', 'BIH' }, -- Bosnia and Herzegovina
|
||||
['bd'] = { '', 'BGD' }, -- Bangladesh
|
||||
['be'] = { '', 'BEL' }, -- Belgium
|
||||
['bg'] = { '', 'BGR' }, -- Bulgaria
|
||||
['br'] = { '', 'BRA' }, -- Brazil
|
||||
['bt'] = { '', 'BTN' }, -- Bhutan
|
||||
['bw'] = { '', 'BWA' }, -- Botswana
|
||||
['by'] = { '', 'BLR' }, -- Belarus
|
||||
['ca'] = { '', 'CAN' }, -- Canada
|
||||
['cd'] = { '', 'COD' }, -- Congo
|
||||
['ch'] = { '', 'CHE' }, -- Switzerland
|
||||
['cm'] = { '', 'CMR' }, -- Cameroon
|
||||
['cn'] = { '', 'CHN' }, -- China
|
||||
['cz'] = { '', 'CZE' }, -- Czechia
|
||||
['de'] = { 'Deutsch (Germany)', 'GER' }, -- Germany
|
||||
['dk'] = { '', 'DNK' }, -- Denmark
|
||||
['ee'] = { '', 'EST' }, -- Estonia
|
||||
['es'] = { '', 'ESP' }, -- Spain
|
||||
['et'] = { '', 'ETH' }, -- Ethiopia
|
||||
['eu'] = { '?', '?' }, -- EurKey
|
||||
['fi'] = { '', 'FIN' }, -- Finland
|
||||
['fo'] = { '', 'FRO' }, -- Faroe Islands
|
||||
['fr'] = { '', 'FRA' }, -- France
|
||||
['gb'] = { "English (Bri'ish)", 'ENG' }, -- United Kingdom
|
||||
['ge'] = { '', 'GEO' }, -- Georgia
|
||||
['gh'] = { '', 'GHA' }, -- Ghana
|
||||
['gn'] = { '', 'GIN' }, -- Guinea
|
||||
['gr'] = { '', 'GRC' }, -- Greece
|
||||
['hr'] = { '', 'HRV' }, -- Croatia
|
||||
['hu'] = { '', 'HUN' }, -- Hungary
|
||||
['ie'] = { '', 'IRL' }, -- Ireland
|
||||
['il'] = { '', 'ISR' }, -- Israel
|
||||
['in'] = { '', 'IND' }, -- India
|
||||
['iq'] = { '', 'IRQ' }, -- Iraq
|
||||
['ir'] = { '', 'IRN' }, -- Iran
|
||||
['is'] = { '', 'ISL' }, -- Iceland
|
||||
['it'] = { '', 'ITA' }, -- Italy
|
||||
['jp'] = { '', 'JPN' }, -- Japan
|
||||
['ke'] = { '', 'KEN' }, -- Kenya
|
||||
['kg'] = { '', 'KGZ' }, -- Kyrgyzstan
|
||||
['kh'] = { '', 'KHM' }, -- Cambodia
|
||||
['kr'] = { '', 'KOR' }, -- Korea
|
||||
['kz'] = { '', 'KAZ' }, -- Kazakhstan
|
||||
['la'] = { '', 'LAO' }, -- Laos
|
||||
['latm'] = { '?', '?' }, -- Latin America
|
||||
['latn'] = { '?', '?' }, -- Latin
|
||||
['lk'] = { '', 'LKA' }, -- Sri Lanka
|
||||
['lt'] = { '', 'LTU' }, -- Lithuania
|
||||
['lv'] = { '', 'LVA' }, -- Latvia
|
||||
['ma'] = { '', 'MAR' }, -- Morocco
|
||||
['mao'] = { '?', '?' }, -- Maori
|
||||
['me'] = { '', 'MNE' }, -- Montenegro
|
||||
['mk'] = { '', 'MKD' }, -- Macedonia
|
||||
['ml'] = { '', 'MLI' }, -- Mali
|
||||
['mm'] = { '', 'MMR' }, -- Myanmar
|
||||
['mn'] = { '', 'MNG' }, -- Mongolia
|
||||
['mt'] = { '', 'MLT' }, -- Malta
|
||||
['mv'] = { '', 'MDV' }, -- Maldives
|
||||
['ng'] = { '', 'NGA' }, -- Nigeria
|
||||
['nl'] = { '', 'NLD' }, -- Netherlands
|
||||
['no'] = { '', 'NOR' }, -- Norway
|
||||
['np'] = { '', 'NRL' }, -- Nepal
|
||||
['ph'] = { '', 'PHL' }, -- Philippines
|
||||
['pk'] = { '', 'PAK' }, -- Pakistan
|
||||
['pl'] = { '', 'POL' }, -- Poland
|
||||
['pt'] = { '', 'PRT' }, -- Portugal
|
||||
['ro'] = { '', 'ROU' }, -- Romania
|
||||
['rs'] = { '', 'SRB' }, -- Serbia
|
||||
['ru'] = { 'Русский (Russia)', 'RUS' }, -- Russia
|
||||
['se'] = { '', 'SWE' }, -- Sweden
|
||||
['si'] = { '', 'SVN' }, -- Slovenia
|
||||
['sk'] = { '', 'SVK' }, -- Slovakia
|
||||
['sn'] = { '', 'SEN' }, -- Senegal
|
||||
['sy'] = { '', 'SYR' }, -- Syria
|
||||
['th'] = { '', 'THA' }, -- Thailand
|
||||
['tj'] = { '', 'TJK' }, -- Tajikistan
|
||||
['tm'] = { '', 'TKM' }, -- Turkmenistan
|
||||
['tr'] = { '', 'TUR' }, -- Turkey
|
||||
['tw'] = { '', 'TWN' }, -- Taiwan
|
||||
['tz'] = { '', 'TZA' }, -- Tanzania
|
||||
['ua'] = { '', 'UKR' }, -- Ukraine
|
||||
['us'] = { 'English (United States)', 'USA' }, -- USA
|
||||
['uz'] = { '', 'UZB' }, -- Uzbekistan
|
||||
['vn'] = { '', 'VNM' }, -- Vietnam
|
||||
['za'] = { '', 'ZAF' }, -- South Africa
|
||||
}
|
||||
|
||||
local longname, shortname = table.unpack(xkeyboard_country_code[keymap])
|
||||
|
||||
local kb_layout_item = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'shortname',
|
||||
markup = '<span foreground="' .. Theme_config.kblayout.item.fg_short .. '">' .. shortname .. '</span>',
|
||||
widget = wibox.widget.textbox,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
},
|
||||
{
|
||||
id = 'longname',
|
||||
markup = '<span foreground="' .. Theme_config.kblayout.item.fg_long .. '">' .. longname .. '</span>',
|
||||
widget = wibox.widget.textbox,
|
||||
font = User_config.font.bold,
|
||||
},
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
id = 'hover',
|
||||
shape = Theme_config.kblayout.item.shape,
|
||||
border_width = Theme_config.kblayout.item.border_width,
|
||||
border_color = Theme_config.kblayout.item.border_color,
|
||||
bg = Theme_config.kblayout.item.bg,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
kb_helper:connect_signal('KB::layout_changed', function(_, k)
|
||||
if keymap == k then
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg_selected
|
||||
kb_layout_item.border_color = Theme_config.kblayout.item.bg_selected
|
||||
kb_layout_item:get_children_by_id('shortname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_selected .. '">' .. shortname .. '</span>'
|
||||
kb_layout_item:get_children_by_id('longname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_selected .. '">' .. longname .. '</span>'
|
||||
else
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg
|
||||
kb_layout_item.border_color = Theme_config.kblayout.item.border_color
|
||||
kb_layout_item:get_children_by_id('shortname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_short .. '">' .. shortname .. '</span>'
|
||||
kb_layout_item:get_children_by_id('longname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_long .. '">' .. longname .. '</span>'
|
||||
end
|
||||
end)
|
||||
|
||||
kb_helper:get_layout_async(function(k)
|
||||
if keymap == k then
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg_selected
|
||||
kb_layout_item.border_color = Theme_config.kblayout.item.bg_selected
|
||||
kb_layout_item:get_children_by_id('shortname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_selected .. '">' .. shortname .. '</span>'
|
||||
kb_layout_item:get_children_by_id('longname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_selected .. '">' .. longname .. '</span>'
|
||||
else
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg
|
||||
kb_layout_item.border_color = Theme_config.kblayout.item.border_color
|
||||
kb_layout_item:get_children_by_id('shortname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_short .. '">' .. shortname .. '</span>'
|
||||
kb_layout_item:get_children_by_id('longname')[1].markup = '<span foreground="' .. Theme_config.kblayout.item.fg_long .. '">' .. longname .. '</span>'
|
||||
end
|
||||
end)
|
||||
|
||||
hover.bg_hover { widget = kb_layout_item }
|
||||
|
||||
kb_layout_item:buttons { gtable.join(
|
||||
abutton({}, 1, function()
|
||||
kb_helper:set_layout(keymap)
|
||||
--kb_layout_popup.visible = not kb_layout_popup.visible
|
||||
end)
|
||||
), }
|
||||
|
||||
list:add(kb_layout_item)
|
||||
end
|
||||
|
||||
return widget
|
||||
end
|
||||
|
||||
return setmetatable({}, { __call = function(_, screen)
|
||||
local kblayout_widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = "icon",
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
image = gears.color.recolor_image(icondir .. "keyboard.svg", Theme_config.kblayout.fg)
|
||||
},
|
||||
id = "icon_layout",
|
||||
widget = wibox.container.place
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = 'center',
|
||||
halign = 'center',
|
||||
image = gcolor.recolor_image(icondir .. 'keyboard.svg', Theme_config.kblayout.fg),
|
||||
},
|
||||
top = dpi(2),
|
||||
widget = wibox.container.margin,
|
||||
id = "icon_margin"
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
strategy = 'exact',
|
||||
},
|
||||
{
|
||||
id = 'text_role',
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
{
|
||||
id = "label",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
id = "kblayout_layout",
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
id = "container",
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = Theme_config.kblayout.bg,
|
||||
fg = Theme_config.kblayout.fg,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(6))
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local function get_kblayout()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
[[ setxkbmap -query | grep layout | awk '{print $2}' ]],
|
||||
function(stdout)
|
||||
local layout = stdout:gsub("\n", "")
|
||||
kblayout_widget.container.kblayout_layout.label.text = layout
|
||||
capi.awesome.emit_signal("update::background:kblayout")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function create_kb_layout_item(keymap)
|
||||
-- TODO: Add more, too lazy rn
|
||||
local longname, shortname
|
||||
|
||||
local xkeyboard_country_code = {
|
||||
{ "af", "أفغانيش(Afghanistan)", "AFG" }, -- Afghanistan
|
||||
{ "al", "Shqip(Albania)", "ALB" }, -- Albania
|
||||
{ "am", "Hայերեն(Armenia)", "ARM" }, -- Armenia
|
||||
{ "ara", "عربي(Arab)", "ARB" }, -- Arabic
|
||||
{ "at", "Österreichisch (Austria)", "AUT" }, -- Austria
|
||||
{ "az", "Azərbaycan(Azerbaijan)", "AZE" }, -- Azerbaijan
|
||||
{ "ba", "Bosanski(Bosnia and Herzegovina)", "BIH" }, -- Bosnia and Herzegovina
|
||||
{ "bd", "", "BGD" }, -- Bangladesh
|
||||
{ "be", "", "BEL" }, -- Belgium
|
||||
{ "bg", "", "BGR" }, -- Bulgaria
|
||||
{ "br", "", "BRA" }, -- Brazil
|
||||
{ "bt", "", "BTN" }, -- Bhutan
|
||||
{ "bw", "", "BWA" }, -- Botswana
|
||||
{ "by", "", "BLR" }, -- Belarus
|
||||
{ "ca", "", "CAN" }, -- Canada
|
||||
{ "cd", "", "COD" }, -- Congo
|
||||
{ "ch", "", "CHE" }, -- Switzerland
|
||||
{ "cm", "", "CMR" }, -- Cameroon
|
||||
{ "cn", "", "CHN" }, -- China
|
||||
{ "cz", "", "CZE" }, -- Czechia
|
||||
{ "de", "Deutsch (Germany)", "GER" }, -- Germany
|
||||
{ "dk", "", "DNK" }, -- Denmark
|
||||
{ "ee", "", "EST" }, -- Estonia
|
||||
{ "es", "", "ESP" }, -- Spain
|
||||
{ "et", "", "ETH" }, -- Ethiopia
|
||||
{ "eu", "?", "?" }, -- EurKey
|
||||
{ "fi", "", "FIN" }, -- Finland
|
||||
{ "fo", "", "FRO" }, -- Faroe Islands
|
||||
{ "fr", "", "FRA" }, -- France
|
||||
{ "gb", "English (Bri'ish)", "ENG" }, -- United Kingdom
|
||||
{ "ge", "", "GEO" }, -- Georgia
|
||||
{ "gh", "", "GHA" }, -- Ghana
|
||||
{ "gn", "", "GIN" }, -- Guinea
|
||||
{ "gr", "", "GRC" }, -- Greece
|
||||
{ "hr", "", "HRV" }, -- Croatia
|
||||
{ "hu", "", "HUN" }, -- Hungary
|
||||
{ "ie", "", "IRL" }, -- Ireland
|
||||
{ "il", "", "ISR" }, -- Israel
|
||||
{ "in", "", "IND" }, -- India
|
||||
{ "iq", "", "IRQ" }, -- Iraq
|
||||
{ "ir", "", "IRN" }, -- Iran
|
||||
{ "is", "", "ISL" }, -- Iceland
|
||||
{ "it", "", "ITA" }, -- Italy
|
||||
{ "jp", "", "JPN" }, -- Japan
|
||||
{ "ke", "", "KEN" }, -- Kenya
|
||||
{ "kg", "", "KGZ" }, -- Kyrgyzstan
|
||||
{ "kh", "", "KHM" }, -- Cambodia
|
||||
{ "kr", "", "KOR" }, -- Korea
|
||||
{ "kz", "", "KAZ" }, -- Kazakhstan
|
||||
{ "la", "", "LAO" }, -- Laos
|
||||
{ "latam", "?", "?" }, -- Latin America
|
||||
{ "latin", "?", "?" }, -- Latin
|
||||
{ "lk", "", "LKA" }, -- Sri Lanka
|
||||
{ "lt", "", "LTU" }, -- Lithuania
|
||||
{ "lv", "", "LVA" }, -- Latvia
|
||||
{ "ma", "", "MAR" }, -- Morocco
|
||||
{ "mao", "?", "?" }, -- Maori
|
||||
{ "me", "", "MNE" }, -- Montenegro
|
||||
{ "mk", "", "MKD" }, -- Macedonia
|
||||
{ "ml", "", "MLI" }, -- Mali
|
||||
{ "mm", "", "MMR" }, -- Myanmar
|
||||
{ "mn", "", "MNG" }, -- Mongolia
|
||||
{ "mt", "", "MLT" }, -- Malta
|
||||
{ "mv", "", "MDV" }, -- Maldives
|
||||
{ "ng", "", "NGA" }, -- Nigeria
|
||||
{ "nl", "", "NLD" }, -- Netherlands
|
||||
{ "no", "", "NOR" }, -- Norway
|
||||
{ "np", "", "NRL" }, -- Nepal
|
||||
{ "ph", "", "PHL" }, -- Philippines
|
||||
{ "pk", "", "PAK" }, -- Pakistan
|
||||
{ "pl", "", "POL" }, -- Poland
|
||||
{ "pt", "", "PRT" }, -- Portugal
|
||||
{ "ro", "", "ROU" }, -- Romania
|
||||
{ "rs", "", "SRB" }, -- Serbia
|
||||
{ "ru", "Русский (Russia)", "RUS" }, -- Russia
|
||||
{ "se", "", "SWE" }, -- Sweden
|
||||
{ "si", "", "SVN" }, -- Slovenia
|
||||
{ "sk", "", "SVK" }, -- Slovakia
|
||||
{ "sn", "", "SEN" }, -- Senegal
|
||||
{ "sy", "", "SYR" }, -- Syria
|
||||
{ "th", "", "THA" }, -- Thailand
|
||||
{ "tj", "", "TJK" }, -- Tajikistan
|
||||
{ "tm", "", "TKM" }, -- Turkmenistan
|
||||
{ "tr", "", "TUR" }, -- Turkey
|
||||
{ "tw", "", "TWN" }, -- Taiwan
|
||||
{ "tz", "", "TZA" }, -- Tanzania
|
||||
{ "ua", "", "UKR" }, -- Ukraine
|
||||
{ "us", "English (United States)", "USA" }, -- USA
|
||||
{ "uz", "", "UZB" }, -- Uzbekistan
|
||||
{ "vn", "", "VNM" }, -- Vietnam
|
||||
{ "za", "", "ZAF" } -- South Africa
|
||||
}
|
||||
|
||||
for _, c in ipairs(xkeyboard_country_code) do
|
||||
if c[1] == keymap then
|
||||
longname = c[2]
|
||||
shortname = c[3]
|
||||
end
|
||||
end
|
||||
|
||||
local kb_layout_item = wibox.widget {
|
||||
{
|
||||
{
|
||||
-- Short name e.g. GER, ENG, RUS
|
||||
{
|
||||
{
|
||||
text = shortname,
|
||||
widget = wibox.widget.textbox,
|
||||
font = User_config.font.extrabold,
|
||||
id = "shortname"
|
||||
},
|
||||
fg = Theme_config.kblayout.item.fg_short,
|
||||
widget = wibox.container.background,
|
||||
id = "background2"
|
||||
},
|
||||
{
|
||||
{
|
||||
text = longname,
|
||||
widget = wibox.widget.textbox,
|
||||
font = User_config.font.bold,
|
||||
id = "longname",
|
||||
},
|
||||
fg = Theme_config.kblayout.item.fg_long,
|
||||
widget = wibox.container.background,
|
||||
id = "background1"
|
||||
},
|
||||
spacing = dpi(15),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
id = "container"
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin,
|
||||
id = "margin"
|
||||
},
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(8))
|
||||
end,
|
||||
bg = Theme_config.kblayout.item.bg,
|
||||
widget = wibox.container.background,
|
||||
id = "background",
|
||||
keymap = keymap
|
||||
}
|
||||
|
||||
Hover_signal(kb_layout_item)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"update::background:kblayout",
|
||||
function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
[[ setxkbmap -query | grep layout | awk '{print $2}' ]],
|
||||
function(stdout)
|
||||
local layout = stdout:gsub("\n", "")
|
||||
if kb_layout_item.keymap == layout then
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg_selected
|
||||
kb_layout_item:get_children_by_id("background2")[1].fg = Theme_config.kblayout.item.fg_selected
|
||||
kb_layout_item:get_children_by_id("background1")[1].fg = Theme_config.kblayout.item.fg_selected
|
||||
else
|
||||
kb_layout_item.bg = Theme_config.kblayout.item.bg
|
||||
kb_layout_item:get_children_by_id("background2")[1].fg = Theme_config.kblayout.item.fg_short
|
||||
kb_layout_item:get_children_by_id("background1")[1].fg = Theme_config.kblayout.item.fg_long
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
get_kblayout()
|
||||
|
||||
kb_layout_item:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"setxkbmap " .. keymap,
|
||||
function()
|
||||
capi.awesome.emit_signal("kblayout::hide:kbmenu")
|
||||
capi.mousegrabber.stop()
|
||||
get_kblayout()
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
return kb_layout_item
|
||||
end
|
||||
|
||||
local function get_kblist()
|
||||
local kb_layout_items = {
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(10)
|
||||
}
|
||||
for i, keymap in pairs(User_config.kblayout) do
|
||||
kb_layout_items[i] = create_kb_layout_item(keymap)
|
||||
end
|
||||
local cont = {
|
||||
{
|
||||
kb_layout_items,
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
}
|
||||
return cont
|
||||
end
|
||||
|
||||
local kb_menu_widget = awful.popup {
|
||||
screen = s,
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, dpi(12))
|
||||
end,
|
||||
shape = Theme_config.kblayout.shape,
|
||||
widget = wibox.container.background,
|
||||
bg = Theme_config.kblayout.bg_container,
|
||||
border_width = dpi(4),
|
||||
border_color = Theme_config.kblayout.border_color_container,
|
||||
width = dpi(100),
|
||||
max_height = dpi(600),
|
||||
visible = false,
|
||||
}
|
||||
|
||||
hover.bg_hover { widget = kblayout_widget }
|
||||
|
||||
kb_helper:get_layout_async(function(stdout)
|
||||
kblayout_widget:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '')
|
||||
end)
|
||||
|
||||
kb_helper:connect_signal('KB::layout_changed', function(_, k)
|
||||
kblayout_widget:get_children_by_id('text_role')[1].text = k
|
||||
end)
|
||||
|
||||
kb_layout_popup = apopup {
|
||||
widget = create_kb_layout_list(),
|
||||
border_color = Theme_config.kblayout.border_color,
|
||||
border_width = Theme_config.kblayout.border_width,
|
||||
screen = screen,
|
||||
ontop = true,
|
||||
placement = function(c) awful.placement.align(c,
|
||||
{ position = "top_right", margins = { right = dpi(255), top = dpi(60) } })
|
||||
end
|
||||
visible = false,
|
||||
bg = Theme_config.kblayout.bg_container,
|
||||
}
|
||||
|
||||
kb_menu_widget:connect_signal(
|
||||
"mouse::leave",
|
||||
function()
|
||||
capi.mousegrabber.run(
|
||||
function()
|
||||
kblayout_widget.bg = Theme_config.kblayout.bg
|
||||
capi.awesome.emit_signal("kblayout::hide:kbmenu")
|
||||
capi.mousegrabber.stop()
|
||||
return true
|
||||
end,
|
||||
"arrow"
|
||||
)
|
||||
end
|
||||
)
|
||||
kblayout_widget:buttons { gtable.join(
|
||||
abutton({}, 1, function()
|
||||
local geo = capi.mouse.coords()
|
||||
kb_layout_popup.y = dpi(65)
|
||||
kb_layout_popup.x = geo.x - kb_layout_popup.width / 2
|
||||
kb_layout_popup.visible = not kb_layout_popup.visible
|
||||
end)
|
||||
), }
|
||||
|
||||
kb_menu_widget:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
mousegrabber.stop()
|
||||
end
|
||||
)
|
||||
|
||||
kb_menu_widget:setup(
|
||||
get_kblist()
|
||||
)
|
||||
|
||||
local function toggle_kb_layout()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"setxkbmap -query | grep layout: | awk '{print $2}'",
|
||||
function(stdout)
|
||||
for j, n in ipairs(User_config.kblayout) do
|
||||
if stdout:match(n) then
|
||||
if j == #User_config.kblayout then
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"setxkbmap " .. User_config.kblayout[1],
|
||||
function()
|
||||
get_kblayout()
|
||||
end
|
||||
)
|
||||
else
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"setxkbmap " .. User_config.kblayout[j + 1],
|
||||
function()
|
||||
get_kblayout()
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"kblayout::toggle",
|
||||
function()
|
||||
toggle_kb_layout()
|
||||
end
|
||||
)
|
||||
|
||||
-- Signals
|
||||
Hover_signal(kblayout_widget)
|
||||
|
||||
local kblayout_keygrabber = awful.keygrabber {
|
||||
autostart = false,
|
||||
stop_event = 'release',
|
||||
keypressed_callback = function(self, mod, key, command)
|
||||
capi.awesome.emit_signal("kblayout::hide:kbmenu")
|
||||
capi.mousegrabber.stop()
|
||||
end
|
||||
}
|
||||
|
||||
kblayout_widget:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
capi.mousegrabber.stop()
|
||||
if kb_menu_widget.visible then
|
||||
kb_menu_widget.visible = false
|
||||
kblayout_keygrabber:stop()
|
||||
else
|
||||
kb_menu_widget.visible = true
|
||||
kblayout_keygrabber:start()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"kblayout::hide:kbmenu",
|
||||
function()
|
||||
kb_menu_widget.visible = false
|
||||
kblayout_keygrabber:stop()
|
||||
end
|
||||
)
|
||||
|
||||
get_kblayout()
|
||||
kb_menu_widget.visible = false
|
||||
return kblayout_widget
|
||||
end
|
||||
end, })
|
||||
|
||||
@@ -3,32 +3,35 @@
|
||||
----------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local alayout = require("awful.layout")
|
||||
local awidget = require("awful.widget")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gtable = require("gears.table")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local alayout = require('awful.layout')
|
||||
local awidget = require('awful.widget')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
-- Local libs
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
--#region Layout icons
|
||||
local layout_path = Theme_path .. "../assets/layout/"
|
||||
local layout_path = Theme_path .. '../assets/layout/'
|
||||
|
||||
Theme.layout_cornerne = layout_path .. "cornerne.png"
|
||||
Theme.layout_cornernw = layout_path .. "cornernw.png"
|
||||
Theme.layout_cornerse = layout_path .. "cornerse.png"
|
||||
Theme.layout_cornersw = layout_path .. "cornersw.png"
|
||||
Theme.layout_dwindle = layout_path .. "dwindle.png"
|
||||
Theme.layout_fairh = layout_path .. "fairh.png"
|
||||
Theme.layout_fairv = layout_path .. "fairv.png"
|
||||
Theme.layout_floating = layout_path .. "floating.png"
|
||||
Theme.layout_fullscreen = layout_path .. "fullscreen.png"
|
||||
Theme.layout_magnifier = layout_path .. "magnifier.png"
|
||||
Theme.layout_max = layout_path .. "max.png"
|
||||
Theme.layout_spiral = layout_path .. "spiral.png"
|
||||
Theme.layout_tile = layout_path .. "tile.png"
|
||||
Theme.layout_tilebottom = layout_path .. "tilebottom.png"
|
||||
Theme.layout_tileleft = layout_path .. "tileleft.png"
|
||||
Theme.layout_tiletop = layout_path .. "tiletop.png"
|
||||
Theme.layout_cornerne = layout_path .. 'cornerne.png'
|
||||
Theme.layout_cornernw = layout_path .. 'cornernw.png'
|
||||
Theme.layout_cornerse = layout_path .. 'cornerse.png'
|
||||
Theme.layout_cornersw = layout_path .. 'cornersw.png'
|
||||
Theme.layout_dwindle = layout_path .. 'dwindle.png'
|
||||
Theme.layout_fairh = layout_path .. 'fairh.png'
|
||||
Theme.layout_fairv = layout_path .. 'fairv.png'
|
||||
Theme.layout_floating = layout_path .. 'floating.png'
|
||||
Theme.layout_fullscreen = layout_path .. 'fullscreen.png'
|
||||
Theme.layout_magnifier = layout_path .. 'magnifier.png'
|
||||
Theme.layout_max = layout_path .. 'max.png'
|
||||
Theme.layout_spiral = layout_path .. 'spiral.png'
|
||||
Theme.layout_tile = layout_path .. 'tile.png'
|
||||
Theme.layout_tilebottom = layout_path .. 'tilebottom.png'
|
||||
Theme.layout_tileleft = layout_path .. 'tileleft.png'
|
||||
Theme.layout_tiletop = layout_path .. 'tiletop.png'
|
||||
--#endregion
|
||||
|
||||
-- Returns the layoutbox widget
|
||||
@@ -39,22 +42,21 @@ return function()
|
||||
{
|
||||
awidget.layoutbox(),
|
||||
widget = wibox.container.place,
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
},
|
||||
left = dpi(5),
|
||||
right = dpi(5),
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
width = dpi(40)
|
||||
strategy = 'exact',
|
||||
width = dpi(40),
|
||||
},
|
||||
bg = Theme_config.layout_list.bg,
|
||||
shape = Theme_config.layout_list.shape,
|
||||
widget = wibox.container.background
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
Hover_signal(layout)
|
||||
hover.bg_hover { widget = layout }
|
||||
|
||||
layout:buttons(gtable.join(
|
||||
abutton({}, 1, function()
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
--------------------------------
|
||||
|
||||
-- Awesome Libs
|
||||
local abutton = require("awful.button")
|
||||
local apopup = require("awful.popup")
|
||||
local atooltip = require("awful.tooltip")
|
||||
local base = require("wibox.widget.base")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gears = require("gears")
|
||||
local gtable = require("gears.table")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local abutton = require('awful.button')
|
||||
local apopup = require('awful.popup')
|
||||
local atooltip = require('awful.tooltip')
|
||||
local base = require('wibox.widget.base')
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
local gears = require('gears')
|
||||
local gtable = require('gears.table')
|
||||
local wibox = require('wibox')
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
@@ -19,51 +18,79 @@ local capi = {
|
||||
}
|
||||
|
||||
-- Icon directory path
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
||||
local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/network/'
|
||||
|
||||
local nm_widget = require("src.modules.network_controller.init")
|
||||
local nm_widget = require('src.modules.network_controller.init')
|
||||
local hover = require('src.tools.hover')
|
||||
|
||||
local network = { mt = {} }
|
||||
|
||||
function network.new(args)
|
||||
args = args or {}
|
||||
|
||||
local w = base.make_widget_from_value({
|
||||
local w = base.make_widget_from_value {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'wifi_icon',
|
||||
image = gears.color.recolor_image(icondir .. "no-internet" .. ".svg", Theme_config.network.fg),
|
||||
image = gears.color.recolor_image(icondir .. 'no-internet.svg', Theme_config.network.fg),
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = false
|
||||
resize = false,
|
||||
},
|
||||
{
|
||||
id = "wifi_strength",
|
||||
id = 'wifi_strength',
|
||||
visible = true,
|
||||
widget = wibox.widget.textbox
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
left = dpi(8),
|
||||
right = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
halign = "center",
|
||||
valign = "center"
|
||||
halign = 'center',
|
||||
valign = 'center',
|
||||
},
|
||||
bg = Theme_config.network.bg,
|
||||
fg = Theme_config.network.fg,
|
||||
shape = Theme_config.network.shape,
|
||||
widget = wibox.container.background
|
||||
})
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
Hover_signal(w)
|
||||
assert(w, 'Failed to create widget')
|
||||
|
||||
hover.bg_hover { widget = w }
|
||||
|
||||
gtable.crush(w, network, true)
|
||||
|
||||
capi.awesome.connect_signal('NM::AccessPointStrength', function(strength)
|
||||
strength = math.floor(strength)
|
||||
w:get_children_by_id('wifi_strength')[1].text = strength .. '%'
|
||||
w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir ..
|
||||
'wifi-strength-' .. math.floor(strength / 25) + 1 .. '.svg', Theme_config.network.fg)
|
||||
end)
|
||||
|
||||
capi.awesome.connect_signal('NM::EthernetStatus', function(connected, speed)
|
||||
local tt = atooltip {
|
||||
objects = { w },
|
||||
mode = 'outside',
|
||||
preferred_alignments = 'middle',
|
||||
margins = dpi(10),
|
||||
}
|
||||
if connected then
|
||||
w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir .. 'ethernet.svg',
|
||||
Theme_config.network.fg)
|
||||
tt.text = 'Connected via Ethernet at ' .. math.floor(speed or 0) .. '/Mbps'
|
||||
else
|
||||
w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir .. 'no-internet.svg',
|
||||
Theme_config.network.fg)
|
||||
tt.text = 'No connection found'
|
||||
end
|
||||
end)
|
||||
|
||||
local nm = nm_widget { screen = args.screen }
|
||||
|
||||
local network_controler_popup = apopup {
|
||||
@@ -82,25 +109,6 @@ function network.new(args)
|
||||
end)
|
||||
))
|
||||
|
||||
awesome.connect_signal("NM::AccessPointStrength", function(strength)
|
||||
strength = math.floor(strength)
|
||||
w:get_children_by_id("wifi_strength")[1].text = strength .. "%"
|
||||
w:get_children_by_id("wifi_icon")[1].image = gears.color.recolor_image(icondir ..
|
||||
"wifi-strength-" .. math.floor(strength / 25) + 1 .. ".svg", Theme_config.network.fg)
|
||||
end)
|
||||
|
||||
nm:connect_signal("NM::Bitrate", function(_, bitrate)
|
||||
print(bitrate)
|
||||
end)
|
||||
|
||||
atooltip {
|
||||
objects = { w },
|
||||
mode = "outside",
|
||||
preferred_alignments = "middle",
|
||||
margins = dpi(10),
|
||||
text = "Connected to " .. "" .. " with " .. "" .. " signal strength"
|
||||
}
|
||||
|
||||
return w
|
||||
end
|
||||
|
||||
|
||||