desktop, calendar, various other modules

This commit is contained in:
Rene Kievits
2022-11-22 16:59:55 +01:00
parent 210682e955
commit c6341f84e7
74 changed files with 5587 additions and 985 deletions

View File

@@ -0,0 +1,522 @@
---------------------------------------------------------------------------
-- 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 abutton = require("awful.button")
local beautiful = require("beautiful")
local gtable = require("gears.table")
local base = require("wibox.widget.base")
local gstring = require("gears.string")
local keygrabber = require("awful.keygrabber")
local wtemplate = require("wibox.template")
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 text_color = beautiful.inputbox_fg or "#ffffff"
local placeholder_text = beautiful.inputbox_placeholder_text or "Type here..."
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
if #text < cursor_pos then
char = " "
spacer = ""
text_start = gstring.xml_escape(text)
text_end = ""
else
local offset = 0
if #text:sub(cursor_pos, cursor_pos) == -1 then
offset = 1
end
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.cur_pos_start and self._private.highlight.cur_pos_end 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.cur_pos_start - 1))
local text_highlighted = gstring.xml_escape(text:sub(self._private.highlight.cur_pos_start,
self._private.highlight.cur_pos_end))
local text_end_highlight = gstring.xml_escape(text:sub(self._private.highlight.cur_pos_end + 1))
return "<span foreground='" .. text_color .. "'>" .. text_start_highlight .. "</span>" ..
"<span foreground='" .. highlight_fg .. "' background='" .. highlight_bg .. "'>" ..
text_highlighted ..
"</span>" .. "<span foreground='" .. text_color .. "'>" .. text_end_highlight .. "</span>"
else
return "<span foreground='" .. text_color .. "'>" .. text_start .. "</span>" ..
"<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
char .. "</span>" .. "<span foreground='" .. text_color .. "'>" .. text_end .. spacer .. "</span>"
end
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
function inputbox:set_widget_template(widget_template)
self._private.widget_template = widget_template
self:set_widget(widget_template)
end
function inputbox:get_widget()
return self._private.widget
end
function inputbox:get_children()
return { self._private.widget }
end
function inputbox:set_children(children)
self:set_widget(children[1])
end
function inputbox:reset()
self._private.widget_template = nil
self:set_widget(nil)
end
--- The inputbox border color
--
-- @DOC_awful_widget_inputbox_border_color_EXAMPLE@
--
-- @property border_color
-- @tparam[opt=gears.color] string border_color
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_border_color(v)
self._private.border_color = v
self:emit_signal("property::border_color", v)
end
--- The inputbox border width
--
-- @DOC_awful_widget_inputbox_border_width_EXAMPLE@
--
-- @property border_width
-- @tparam[opt=0] number|nil border_width
-- @negativeallowed false
-- @propertyunit pixel
-- @propemits true false
-- @propbeautiful
function inputbox:set_border_width(v)
self._private.border_width = v
self:emit_signal("property::border_width", v)
end
--- The inputbox background color
--
-- @DOC_awful_widget_inputbox_bg_EXAMPLE@
--
-- @property bg
-- @tparam[opt=gears.color] string foreground
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_bg(v)
self._private.bg = v
self:emit_signal("property::bg", v)
end
--- The text foreground color
--
-- @DOC_awful_widget_inputbox_fg_EXAMPLE@
--
-- @property string
-- @tparam[opt=gears.color] string foreground
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_fg(v)
self._private.fg = v
self:emit_signal("property::fg", v)
end
--- The shape of the inputbox
--
-- @DOC_awful_widget_inputbox_shape_EXAMPLE@
--
-- @property shape
-- @tparam[opt=gears.shape.rectangle] shape|nil shape
-- @see gears.shape
-- @propemits true false
-- @propbeautiful
function inputbox:set_shape(v)
self._private.shape = v
self:emit_signal("property::shape", v)
end
--- 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:emit_signal("property::text", text)
end
--- Stop the keygrabber and mousegrabber
function inputbox:stop()
self:emit_signal("stopped")
keygrabber.stop()
capi.mousegrabber.stop()
end
function inputbox:focus()
keygrabber.stop()
if not keygrabber.is_running then
self:run()
end
-- Stops the mousegrabber when not clicked on the widget
--[[ capi.mousegrabber.run(
function(m)
if m.buttons[1] then
if capi.mouse.current_wibox ~= self:get_widget().widget then
self:emit_signal("keygrabber::stop", "")
return false
end
end
return true
end, "left_ptr"
) ]]
self:connect_signal("button::press", function()
if capi.mouse.current_widget ~= self then
self:emit_signal("keygrabber::stop", "")
end
end)
end
--[[ local function widget_update(text, cursor_pos, widget)
text = text or ""
cursor_pos = cursor_pos or 1
widget:set_text(text)
widget:emit_signal("property::markup", text)
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:get_text() + 1
self:emit_signal("started")
-- Init and reset(when refocused) the highlight
self._private.highlight = {}
-- Emitted when the keygrabber is stopped
self:connect_signal("cancel", function()
self:stop()
self:emit_signal("stopped")
end)
-- Emitted when the keygrabber should submit the text
self:connect_signal("submit", function(text)
self:stop()
self:emit_signal("stopped", text)
end)
self:emit_signal("key_pressed", "B", "A")
keygrabber.run(function(mod, key, event)
local mod_keys = {}
for _, v in ipairs(mod) do
mod_keys[v] = true
end
if not (event == "press") then return end
--Escape cases
-- Just quit and leave the text as is
if (not mod_keys.Control) and (key == "Escape") then
self:emit_signal("cancel")
elseif (not mod_keys.Control and key == "KP_Enter") or (not mod_keys.Control and key == "Return") then
self:emit_signal("submit", self:get_text())
self:set_text("")
end
-- All shift, control or key cases
if mod_keys.Shift then
if key == "Left" then
if cursor_pos > 1 then
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos - 1
end
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos
end
if self._private.highlight.cur_pos_start < cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end - 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start - 1
end
cursor_pos = cursor_pos - 1
end
elseif key == "Right" then
if #self._private.text >= cursor_pos then
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos - 1
end
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos
end
if self._private.highlight.cur_pos_end <= cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end + 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start + 1
end
cursor_pos = cursor_pos + 1
if cursor_pos > #self._private.text + 1 then
self._private.highlight = {}
end
end
else
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 + 1
end
end
elseif mod_keys.Control then
if key == "a" then
-- Mark the entire text
self._private.highlight = {
cur_pos_start = 1,
cur_pos_end = #self._private.text
}
elseif key == "c" then
-- TODO: Copy the highlighted text when the selection setter gets implemented
elseif key == "v" then
local sel = capi.selection()
if sel then
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
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 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
elseif key == "x" then
--TODO: "cut". Copy selected then clear text, this requires to add the c function first.
self._private.highlight = {}
elseif key == "Left" then
-- 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
elseif key == "Right" then
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
end
else
if key == "BackSpace" then
-- 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
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + 1
else
if cursor_pos > 1 then
self:set_text(self._private.text:sub(1, cursor_pos - 2) ..
self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos - 1
end
end
elseif key == "Delete" then
-- 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
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 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
elseif key == "Left" then
-- Move cursor ro the left
if cursor_pos > 1 then
cursor_pos = cursor_pos - 1
end
self._private.highlight = {}
elseif key == "Right" then
-- Move cursor to the right
if cursor_pos <= #self._private.text then
cursor_pos = cursor_pos + 1
end
self._private.highlight = {}
else
-- Print every alphanumeric key
-- It seems like gears.xmlescape doesn't support non alphanumeric characters
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 + 1
end
end
-- Make sure the cursor cannot go out of bounds
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
end
-- Update cycle
self:get_widget():update {
text = text_with_cursor(self:get_text(), cursor_pos, self)
}
-- using self:emit_signal... results in nil tables beeing send
awesome.emit_signal("inputbox::key_pressed", mod_keys, key)
end)
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)
local w = base.make_widget(nil, nil, { enable_properties = true })
gtable.crush(w, inputbox, true)
w:set_widget(wtemplate.make_from_value(args.widget_template))
w:buttons(
gtable.join {
abutton({}, 1, function()
w:focus()
end),
abutton({}, 3, function()
-- TODO: Figure out how to paste with highlighted support
-- Maybe with a signal?
end)
}
)
-- Change the cursor to "xterm" on hover over
local old_cursor, old_wibox
w:connect_signal(
"mouse::enter",
function()
local wid = capi.mouse.current_wibox
if wid then
old_cursor, old_wibox = wid.cursor, wid
wid.cursor = "xterm"
end
end
)
-- Change the cursor back once leaving the widget
w:connect_signal(
"mouse::leave",
function()
old_wibox.cursor = old_cursor
old_wibox = nil
end
)
-- Initialize the text and placeholder with a first update
w:get_widget():update {
text = text_with_cursor("", 1, w)
}
return w
end
function inputbox.mt:__call(...)
return inputbox.new(...)
end
return setmetatable(inputbox, inputbox.mt)

View File

@@ -14,8 +14,12 @@ mouse = mouse
mousegrabber = mousegrabber
root = root
screen = screen
selection = selection
tag = tag
-- Do not touch as this is used to share some variables between files
Global_config = {}
require("src.theme.user_config")
require("src.theme.theme_config")
@@ -30,5 +34,5 @@ require("src.bindings.global_buttons")
require("src.bindings.bind_to_tags")
require("src.modules.init")
require("src.tools.helpers.init")
require("src.tools.auto_starter")(User_config.autostart)
require("src.tools.dbus.bluetooth_dbus")()
--require("src.tools.auto_starter")(User_config.autostart)
--require("src.tools.dbus.bluetooth_dbus")()

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.56,5.44L15.11,6.89C16.84,7.94 18,9.83 18,12A6,6 0 0,1 12,18A6,6 0 0,1 6,12C6,9.83 7.16,7.94 8.88,6.88L7.44,5.44C5.36,6.88 4,9.28 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12C20,9.28 18.64,6.88 16.56,5.44M13,3H11V13H13" /></svg>

After

Width:  |  Height:  |  Size: 508 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z" /></svg>

After

Width:  |  Height:  |  Size: 289 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,20C8.13,20 5,16.87 5,13C5,9.13 8.13,6 12,6C15.87,6 19,9.13 19,13C19,16.87 15.87,20 12,20M12,4C7.03,4 3,8.03 3,13C3,17.97 7.03,22 12,22C16.97,22 21,17.97 21,13C21,8.03 16.97,4 12,4M12.5,8H11V14L15.75,16.85L16.5,15.62L12.5,13.25V8M7.88,3.39L6.6,1.86L2,5.71L3.29,7.24L7.88,3.39M22,5.72L17.4,1.86L16.11,3.39L20.71,7.25L22,5.72Z" /></svg>

After

Width:  |  Height:  |  Size: 406 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,11.5C10.62,11.5 9.5,10.38 9.5,9C9.5,7.62 10.62,6.5 12,6.5C13.38,6.5 14.5,7.62 14.5,9C14.5,10.38 13.38,11.5 12,11.5M12,2C8.13,2 5,5.13 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9C19,5.13 15.87,2 12,2Z" /></svg>

After

Width:  |  Height:  |  Size: 283 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21,2H3C1.9,2 1,2.9 1,4V20C1,21.1 1.9,22 3,22H21C22.1,22 23,21.1 23,20V4C23,2.9 22.1,2 21,2M21,7H3V4H21V7Z" /></svg>

After

Width:  |  Height:  |  Size: 185 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8C6.9,5 6,5.9 6,7V21C6,22.1 6.9,23 8,23H19C20.1,23 21,22.1 21,21V7C21,5.9 20.1,5 19,5M16,1H4C2.9,1 2,1.9 2,3V17H4V3H16V1Z" /></svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,3L13,9L15,11L22,4V3M12,12.5C11.72,12.5 11.5,12.28 11.5,12C11.5,11.72 11.72,11.5 12,11.5C12.28,11.5 12.5,11.72 12.5,12C12.5,12.28 12.28,12.5 12,12.5M6,20C4.9,20 4,19.1 4,18C4,16.89 4.9,16 6,16C7.1,16 8,16.9 8,18C8,19.11 7.1,20 6,20M6,8C4.9,8 4,7.1 4,6C4,4.89 4.9,4 6,4C7.1,4 8,4.9 8,6C8,7.11 7.1,8 6,8M9.64,7.64C9.87,7.14 10,6.59 10,6C10,3.79 8.21,2 6,2C3.79,2 2,3.79 2,6C2,8.21 3.79,10 6,10C6.59,10 7.14,9.87 7.64,9.64L10,12L7.64,14.36C7.14,14.13 6.59,14 6,14C3.79,14 2,15.79 2,18C2,20.21 3.79,22 6,22C8.21,22 10,20.21 10,18C10,17.41 9.87,16.86 9.64,16.36L12,14L19,21H22V20L9.64,7.64Z" /></svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6,19C6,20.1 6.9,21 8,21H16C17.1,21 18,20.1 18,19V7H6V19M8,9H16V19H8V9M15.5,4L14.5,3H9.5L8.5,4H5V6H19V4H15.5Z" /></svg>

After

Width:  |  Height:  |  Size: 188 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,16C13.1,16 14,16.9 14,18C14,19.1 13.1,20 12,20C10.9,20 10,19.1 10,18C10,16.9 10.9,16 12,16M12,10C13.1,10 14,10.9 14,12C14,13.1 13.1,14 12,14C10.9,14 10,13.1 10,12C10,10.9 10.9,10 12,10M12,4C13.1,4 14,4.9 14,6C14,7.1 13.1,8 12,8C10.9,8 10,7.1 10,6C10,4.9 10.9,4 12,4Z" /></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.06,9L15,9.94L5.92,19H5V18.08L14.06,9M17.66,3C17.41,3 17.15,3.1 16.96,3.29L15.13,5.12L18.88,8.87L20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18.17,3.09 17.92,3 17.66,3M14.06,6.19L3,17.25V21H6.75L17.81,9.94L14.06,6.19Z" /></svg>

After

Width:  |  Height:  |  Size: 305 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5,20L16.36,10.27H13V4L8,13.73H11.5V20M12,2C14.75,2 17.1,3 19.05,4.95C21,6.9 22,9.25 22,12C22,14.75 21,17.1 19.05,19.05C17.1,21 14.75,22 12,22C9.25,22 6.9,21 4.95,19.05C3,17.1 2,14.75 2,12C2,9.25 3,6.9 4.95,4.95C6.9,3 9.25,2 12,2Z" /></svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14,2H6C4.9,2 4,2.9 4,4V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V8L14,2M18,20H6V4H13V9H18V20Z" /></svg>

After

Width:  |  Height:  |  Size: 178 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.81,22H6C4.89,22 4,21.11 4,20V4C4,2.9 4.89,2 6,2H14L20,8V13.09C19.67,13.04 19.34,13 19,13V9H13V4H6V20H13.09C13.21,20.72 13.46,21.39 13.81,22M23,18H20V15H18V18H15V20H18V23H20V20H23V18Z" /></svg>

After

Width:  |  Height:  |  Size: 265 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20,18H4V8H20M20,6H12L10,4H4C2.89,4 2,4.89 2,6V18C2,19.1 2.9,20 4,20H20C21.1,20 22,19.1 22,18V8C22,6.89 21.1,6 20,6Z" /></svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20,18H4V8H20M20,6H12L10,4H4C2.89,4 2,4.89 2,6V18C2,19.1 2.9,20 4,20H20C21.1,20 22,19.1 22,18V8C22,6.89 21.1,6 20,6Z" /></svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,8C14.21,8 16,9.79 16,12C16,14.21 14.21,16 12,16C9.79,16 8,14.21 8,12C8,9.79 9.79,8 12,8M12,10C10.9,10 10,10.9 10,12C10,13.1 10.9,14 12,14C13.1,14 14,13.1 14,12C14,10.9 13.1,10 12,10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V12H19V19Z" /></svg>

After

Width:  |  Height:  |  Size: 222 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12,3V13.55C12,15.76 11.79,17 14,17V7H18V3M10,19C10,17.9 10.9,17 12,17C12,18.1 11.1,19 10,19Z" />
</svg>

After

Width:  |  Height:  |  Size: 177 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.56,5.44L15.11,6.89C16.84,7.94 18,9.83 18,12A6,6 0 0,1 12,18A6,6 0 0,1 6,12C6,9.83 7.16,7.94 8.88,6.88L7.44,5.44C5.36,6.88 4,9.28 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12C20,9.28 18.64,6.88 16.56,5.44M13,3H11V13H13" /></svg>

After

Width:  |  Height:  |  Size: 508 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.56,5.44L15.11,6.89C16.84,7.94 18,9.83 18,12A6,6 0 0,1 12,18A6,6 0 0,1 6,12C6,9.83 7.16,7.94 8.88,6.88L7.44,5.44C5.36,6.88 4,9.28 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12C20,9.28 18.64,6.88 16.56,5.44M13,3H11V13H13" /></svg>

After

Width:  |  Height:  |  Size: 508 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z" /></svg>

After

Width:  |  Height:  |  Size: 289 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22,17V7H6V17H22M22,5C23.1,5 24,5.9 24,7V17C24,18.11 23.1,19 22,19H16V21H18V23H10V21H12V19H6C4.89,19 4,18.11 4,17V7C4,5.9 4.9,5 6,5H22M2,3V15H0V3C0,1.9 0.9,1 2,1H20V3H2Z" /></svg>

After

Width:  |  Height:  |  Size: 248 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5,3C13.09,3 16,5.91 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16C5.91,16 3,13.09 3,9.5C3,5.91 5.91,3 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" /></svg>

After

Width:  |  Height:  |  Size: 340 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20,19V7H4V19H20M20,3C21.1,3 22,3.9 22,5V19C22,20.1 21.1,21 20,21H4C2.9,21 2,20.1 2,19V5C2,3.89 2.9,3 4,3H20M13,17V15H18V17H13M9.58,13L5.57,9H8.4L11.7,12.3C12.09,12.69 12.09,13.33 11.7,13.72L8.42,17H5.59L9.58,13Z" /></svg>

After

Width:  |  Height:  |  Size: 291 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10,21H5C3.89,21 3,20.11 3,19V5C3,3.89 3.89,3 5,3H19C20.11,3 21,3.89 21,5V10.33C20.7,10.21 20.37,10.14 20.04,10.14C19.67,10.14 19.32,10.22 19,10.37V5H5V19H10.11L10,19.11V21M7,9H17V7H7V9M7,17H12.11L14,15.12V15H7V17M7,13H16.12L17,12.12V11H7V13M21.7,13.58L20.42,12.3C20.21,12.09 19.86,12.09 19.65,12.3L18.65,13.3L20.7,15.35L21.7,14.35C21.91,14.14 21.91,13.79 21.7,13.58M12,22H14.06L20.11,15.93L18.06,13.88L12,19.94V22Z" /></svg>

After

Width:  |  Height:  |  Size: 494 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z" /></svg>

After

Width:  |  Height:  |  Size: 1009 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.84,22.73L18,19.9L17.38,20.53L16,17.89L12.35,14.24L9.6,17L9.96,19.47L8.89,20.53L7.13,17.35L3.94,15.58L5,14.5L7.5,14.87L10.23,12.12L6.59,8.5L3.94,7.09L4.57,6.46L1.11,3L2.39,1.73L22.11,21.46L20.84,22.73M16.67,9.92L20.56,6.03C21.15,5.45 21.15,4.5 20.56,3.91L14.55,7.8L9.94,6.74L17.74,14.54L16.67,9.92Z" /></svg>

After

Width:  |  Height:  |  Size: 380 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.56,3.91C21.15,4.5 21.15,5.45 20.56,6.03L16.67,9.92L18.79,19.11L17.38,20.53L13.5,13.1L9.6,17L9.96,19.47L8.89,20.53L7.13,17.35L3.94,15.58L5,14.5L7.5,14.87L11.37,11L3.94,7.09L5.36,5.68L14.55,7.8L18.44,3.91C19,3.33 20,3.33 20.56,3.91Z" /></svg>

After

Width:  |  Height:  |  Size: 313 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M3.9,12C3.9,10.29 5.29,8.9 7,8.9H11V7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H11V15.1H7C5.29,15.1 3.9,13.71 3.9,12M8,13H16V11H8V13M17,7H13V8.9H17C18.71,8.9 20.1,10.29 20.1,12C20.1,13.71 18.71,15.1 17,15.1H13V17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7Z" /></svg>

After

Width:  |  Height:  |  Size: 532 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M7,10L12,15L17,10H7Z" /></svg>

After

Width:  |  Height:  |  Size: 315 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M7,15L12,10L17,15H7Z" /></svg>

After

Width:  |  Height:  |  Size: 315 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,3C7.79,3 3.7,4.41 0.38,7C4.41,12.06 7.89,16.37 12,21.5C16.08,16.42 20.24,11.24 23.65,7C20.32,4.41 16.22,3 12,3Z" /></svg>

After

Width:  |  Height:  |  Size: 410 B

View File

@@ -418,10 +418,6 @@ naughty.connect_signal(
widget_template = w_template
}
awful.spawn.easy_async_with_shell(
"paplay /usr/share/sounds/freedesktop/stereo/message.oga"
)
box.buttons = {}
n.buttons = {}
end

View File

@@ -47,6 +47,13 @@ capi.client.connect_signal(
if c.transient_for then
c.floating = true
end
if c.fullscreen then
gears.timer.delayed_call(function()
if c.valid then
c:geometry(c.screen.geometry)
end
end)
end
end
)

View File

@@ -0,0 +1,60 @@
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)

View File

@@ -9,43 +9,42 @@ local gfilesystem = require("gears").filesystem
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local base = require("wibox.widget.base")
local gtable = require("gears.table")
local json = require("src.lib.json-lua.json-lua")
local cm = require("src.modules.context_menu.init")
local capi = {
awesome = awesome,
mouse = mouse,
}
local json = require("src.lib.json-lua.json-lua")
local cm = require("src.modules.context_menu")
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
return function(s)
local application_grid = { mt = {} }
local application_grid = wibox.widget {
homogenous = true,
expand = false,
spacing = dpi(10),
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
}
-- Selected application position, default is first at 1,1
-- The typo *might* be intentional
local curser = {
x = 1,
y = 1
}
function application_grid:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
local filter = ""
function application_grid: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
---Executes only once to create a widget from each desktop file
---@return table widgets Unsorted widget table
local function get_applications_from_file()
application_grid.set_widget = base.set_widget_common
function application_grid:get_widget()
return self._private.widget
end
function application_grid:get_applications_from_file()
local list = {}
local app_info = Gio.AppInfo
local apps = app_info.get_all()
@@ -108,11 +107,42 @@ return function(s)
widget = wibox.container.background
}
local context_menu = cm({
local context_menu = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
layout = wibox.layout.fixed.horizontal
},
widget = wibox.container.margin
},
widget = wibox.container.background,
},
spacing = dpi(10),
entries = {
{
name = "Execute as sudo",
icon = gears.color.recolor_image(icondir .. "launch.svg", Theme_config.context_menu.icon_color),
icon = gears.color.recolor_image(icondir .. "launch.svg",
Theme_config.application_launcher.application.cm_icon_color),
callback = function()
capi.awesome.emit_signal("application_launcher::show")
awful.spawn("/home/crylia/.config/awesome/src/scripts/start_as_admin.sh " .. app_widget.exec)
@@ -120,14 +150,15 @@ return function(s)
},
{
name = "Pin to dock",
icon = gears.color.recolor_image(icondir .. "pin.svg", Theme_config.context_menu.icon_color),
icon = gears.color.recolor_image(icondir .. "pin.svg",
Theme_config.application_launcher.application.cm_icon_color),
callback = function()
local dir = gears.filesystem.get_configuration_dir() .. "src/config"
gfilesystem.make_directories(dir)
if not gfilesystem.file_readable(dir) then
os.execute("touch " .. dir .. "/dock.json")
end
local handler = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r")
local handler = io.open(dir .. "/dock.json", "r")
if not handler then
return
end
@@ -158,14 +189,24 @@ return function(s)
},
{
name = "Add to desktop",
icon = gears.color.recolor_image(icondir .. "desktop.svg", Theme_config.context_menu.icon_color),
icon = gears.color.recolor_image(icondir .. "desktop.svg",
Theme_config.application_launcher.application.cm_icon_color),
callback = function()
capi.awesome.emit_signal("application_launcher::show")
--!TODO: Add to desktop
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 ""
})
end
}
}
})
}
context_menu:connect_signal("mouse::leave", function()
context_menu.visible = false
end)
-- Execute command on left click and hide launcher
app_widget:buttons(
@@ -175,6 +216,7 @@ return function(s)
button = 1,
on_release = function()
Gio.AppInfo.launch_uris_async(app)
--!Change!
capi.awesome.emit_signal("application_launcher::show")
end
}),
@@ -182,13 +224,7 @@ return function(s)
modifiers = {},
button = 3,
on_release = function()
if not context_menu then
return
end
-- add offset so mouse is above widget, this is so the mouse::leave event triggers always
context_menu.x = capi.mouse.coords().x - 10
context_menu.y = capi.mouse.coords().y - 10
context_menu.visible = not context_menu.visible
context_menu:toggle()
end
})
)
@@ -197,116 +233,126 @@ return function(s)
table.insert(list, app_widget)
end
end
return list
self.app_list = list
end
-- Table to hold all application widgets unsorted
local application_list = get_applications_from_file()
---Function to filter the applications and sort them into a widget grid
---@param search_filter string Filter string from the searchbar
---@return wibox.layout.grid wibox.layout.grid Sorted grid with all applications matching the filter
local function get_applications(search_filter)
filter = search_filter or filter
--Clear grid from previous widgets
application_grid:reset()
function application_grid:set_applications(search_filter)
local filter = search_filter or self.filter or ""
-- Reset to first position
curser = {
self._private.curser = {
x = 1,
y = 1
}
for _, application in ipairs(application_list) do
local grid = wibox.widget {
homogenous = true,
expand = false,
spacing = dpi(10),
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
}
for _, application in ipairs(self.app_list) do
-- Match the filter
if string.match(string.lower(application.name), string.lower(filter)) or
string.match(string.lower(application.categories), string.lower(filter)) or
string.match(string.lower(application.keywords), string.lower(filter)) then
application_grid:add(application)
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
grid:add(application)
-- Get the current position in the grid of the application as a table
local pos = application_grid:get_widget_position(application)
local pos = grid:get_widget_position(application)
-- Check if the curser is currently at the same position as the application
capi.awesome.connect_signal(
"update::selected",
function()
if curser.y == pos.row and curser.x == pos.col then
if self._private.curser.y == pos.row and self._private.curser.x == pos.col then
application.border_color = Theme_config.application_launcher.application.border_color_active
else
application.border_color = Theme_config.application_launcher.application.border_color
end
end
)
end
end
capi.awesome.emit_signal("update::selected")
end
self:set_widget(grid)
end
return application_grid
end
application_grid = get_applications(filter)
capi.awesome.connect_signal(
"application::left",
function()
curser.x = curser.x - 1
if curser.x < 1 then
curser.x = 1
function application_grid:move_up()
self._private.curser.y = self._private.curser.y - 1
if self._private.curser.y < 1 then
self._private.curser.y = 1
end
capi.awesome.emit_signal("update::selected")
end
)
capi.awesome.connect_signal(
"application::right",
function()
curser.x = curser.x + 1
local _, grid_cols = application_grid:get_dimension()
if curser.x > grid_cols then
curser.x = grid_cols
function application_grid:move_down()
print(self._private.curser.y)
self._private.curser.y = self._private.curser.y + 1
local grid_rows, _ = self:get_widget():get_dimension()
if self._private.curser.y > grid_rows then
self._private.curser.y = grid_rows
end
capi.awesome.emit_signal("update::selected")
end
)
capi.awesome.connect_signal(
"application::up",
function()
curser.y = curser.y - 1
if curser.y < 1 then
curser.y = 1
function application_grid:move_left()
self._private.curser.x = self._private.curser.x - 1
if self._private.curser.x < 1 then
self._private.curser.x = 1
end
capi.awesome.emit_signal("update::selected")
end
)
capi.awesome.connect_signal(
"application::down",
function()
curser.y = curser.y + 1
local grid_rows, _ = application_grid:get_dimension()
if curser.y > grid_rows then
curser.y = grid_rows
function application_grid:move_right()
self._private.curser.x = self._private.curser.x + 1
local _, grid_cols = self:get_widget():get_dimension()
if self._private.curser.x > grid_cols then
self._private.curser.x = grid_cols
end
capi.awesome.emit_signal("update::selected")
end
)
capi.awesome.connect_signal(
"update::application_list",
function(f)
application_grid = get_applications(f)
end
)
capi.awesome.connect_signal(
"application_launcher::execute",
function()
capi.awesome.emit_signal("searchbar::stop")
local selected_widget = application_grid:get_widgets_at(curser.y, curser.x)[1]
function application_grid:execute()
local selected_widget = self:get_widget():get_widgets_at(self._private.curser.y,
self._private.curser.x)[1]
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(selected_widget.exec, nil, 0))
end
)
return application_grid
function application_grid:reset()
self._private.curser = {
x = 1,
y = 1
}
capi.awesome.emit_signal("update::selected")
end
function application_grid.new(args)
args = args or {}
local w = base.make_widget(nil, nil, { enable_properties = true })
gtable.crush(w, application_grid, true)
w._private.curser = {
x = 1,
y = 1
}
w:get_applications_from_file()
w:set_applications()
return w
end
function application_grid.mt:__call(...)
return application_grid.new(...)
end
return setmetatable(application_grid, application_grid.mt)

View File

@@ -7,23 +7,67 @@ local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local gshape = require("gears.shape")
local gtable = require("gears.table")
local gobject = require("gears.object")
local capi = {
awesome = awesome,
mouse = mouse,
}
local application_grid = require("src.modules.application_launcher.application")()
local searchbar = require("src.modules.application_launcher.searchbar")()
local application_launcher = { mt = {} }
return function(s)
application_launcher.searchbar = awful.widget.inputbox {
widget_template = wibox.template {
widget = wibox.widget {
{
{
{
widget = wibox.widget.textbox,
halign = "left",
valign = "center",
id = "text_role",
},
widget = wibox.container.margin,
margins = 5,
id = "marg"
},
widget = wibox.container.constraint,
strategy = "exact",
width = 400,
height = 50,
id = "const"
},
widget = wibox.container.background,
bg = "#212121",
fg = "#F0F0F0",
border_color = "#414141",
border_width = 2,
shape = gshape.rounded_rect,
},
update_callback = function(template_widget, args)
template_widget.widget.const.marg.text_role.markup = args.text
end
}
}
application_launcher.application_grid = require("src.modules.application_launcher.application") {}
function application_launcher.new(args)
args = args or {}
local ret = gobject { enable_properties = true }
gtable.crush(ret, application_launcher, true)
local applicaton_launcher = wibox.widget {
{
{
searchbar,
ret.searchbar,
{
application_grid,
ret.application_grid,
spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0,
@@ -36,18 +80,18 @@ return function(s)
margins = dpi(20),
widget = wibox.container.margin
},
height = s.geometry.height / 100 * 60,
height = args.screen.geometry.height / 100 * 60,
--width = s.geometry.width / 100 * 60,
strategy = "exact",
widget = wibox.container.constraint
}
local application_container = awful.popup {
widget = wibox.container.background,
ret.application_container = awful.popup {
widget = applicaton_launcher,
ontop = true,
visible = false,
stretch = false,
screen = s,
screen = args.screen,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
@@ -57,24 +101,90 @@ return function(s)
border_width = Theme_config.application_launcher.border_width
}
application_container:setup {
applicaton_launcher,
layout = wibox.layout.fixed.vertical
}
capi.awesome.connect_signal(
"application_launcher::show",
function()
if capi.mouse.screen == s then
application_container.visible = not application_container.visible
if application_container.visible == false then
capi.awesome.emit_signal("searchbar::stop")
if capi.mouse.screen == args.screen then
ret.application_container.visible = not ret.application_container.visible
end
end
if application_container.visible then
capi.awesome.emit_signal("searchbar::start")
if ret.application_container.visible then
ret.searchbar:focus()
else
awful.keygrabber.stop()
end
end
)
ret.searchbar:connect_signal(
"submit",
function(text)
ret.application_grid:execute()
capi.awesome.emit_signal("application_launcher::show")
end
)
ret.searchbar:connect_signal(
"stopped",
function()
ret.searchbar:get_widget().widget.border_color = Theme_config.application_launcher.searchbar.border_color
end
)
ret.searchbar:connect_signal(
"started",
function()
ret.searchbar:get_widget().widget.border_color = Theme_config.application_launcher.searchbar.border_active
end
)
awesome.connect_signal(
"inputbox::key_pressed",
function(modkey, key)
if key == "Escape" then
ret.searchbar:stop()
capi.awesome.emit_signal("application_launcher::show")
ret.application_grid:reset()
ret.searchbar:set_text("")
elseif key == "Down" or key == "Right" then
ret.searchbar:stop()
awful.keygrabber.run(function(mod, key2, event)
if event == "press" then
if key2 == "Down" then
ret.application_grid:move_down()
elseif key2 == "Up" then
local old_y = ret.application_grid._private.curser.y
ret.application_grid:move_up()
if old_y - ret.application_grid._private.curser.y == 0 then
ret.searchbar:focus()
end
elseif key2 == "Left" then
ret.application_grid:move_left()
elseif key2 == "Right" then
ret.application_grid:move_right()
elseif key2 == "Return" then
awful.keygrabber.stop()
ret.application_grid:execute()
capi.awesome.emit_signal("application_launcher::show")
ret.application_grid:reset()
ret.searchbar:set_text("")
elseif key2 == "Escape" then
capi.awesome.emit_signal("application_launcher::show")
ret.application_grid:reset()
ret.searchbar:set_text("")
awful.keygrabber.stop()
end
end
end)
end
ret.application_grid:set_applications(ret.searchbar:get_text())
end
)
return ret
end
function application_launcher.mt:__call(...)
return application_launcher.new(...)
end
return setmetatable(application_launcher, application_launcher.mt)

View File

@@ -0,0 +1,553 @@
-----------------------------------
-- 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)

View File

@@ -0,0 +1,153 @@
-----------------------------------
-- This is the volume_old module --
-----------------------------------
-- 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,
mouse = mouse,
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
local osd = { mt = {} }
function osd.new(args)
args = args or {}
args.screen = args.screen or 1
local ret = gobject {}
ret.w = wibox.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
{
{
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
},
id = "progressbar_container2",
halign = "center",
valign = "center",
widget = wibox.container.place
},
id = "progressbar_container",
width = dpi(240),
heigth = dpi(20),
stragety = "max",
widget = wibox.container.constraint
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
forced_width = dpi(300),
forced_height = dpi(80),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
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
}
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
}
local hide_volume_osd = gears.timer {
timeout = 2,
autostart = true,
callback = function()
volume_container.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))
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
end
)
end
function osd.mt:__call(...)
return osd.new(...)
end
return setmetatable(osd, osd.mt)

View File

@@ -181,7 +181,7 @@ function device.new(args)
return ret
end
function device.mt.__call(...)
function device.mt:__call(...)
return device.new(...)
end

View File

@@ -51,8 +51,12 @@ local function add_device(self, device, battery)
end
end
function bluetooth.remove_device(self, device)
local function remove_device(self, device)
for i, dev in pairs(self.devices) do
if dev.Address == device.Address then
table.remove(self.devices, i)
end
end
end
function bluetooth.new(args)
@@ -108,7 +112,6 @@ function bluetooth.new(args)
},
{
id = "connected_list",
{
{
{
step = dpi(50),
@@ -121,11 +124,6 @@ function bluetooth.new(args)
margins = dpi(10),
widget = wibox.container.margin
},
id = "place",
height = dpi(200),
strategy = "max",
widget = wibox.container.constraint
},
border_color = Theme_config.bluetooth_controller.con_device_border_color,
border_width = Theme_config.bluetooth_controller.con_device_border_width,
shape = function(cr, width, height)
@@ -178,7 +176,6 @@ function bluetooth.new(args)
},
{
id = "discovered_list",
{
{
{
id = "discovered_device_list",
@@ -191,11 +188,6 @@ function bluetooth.new(args)
margins = dpi(10),
widget = wibox.container.margin
},
id = "place",
height = dpi(200),
strategy = "max",
widget = wibox.container.constraint
},
border_color = Theme_config.bluetooth_controller.con_device_border_color,
border_width = Theme_config.bluetooth_controller.con_device_border_width,
shape = function(cr, width, height)
@@ -204,6 +196,59 @@ function bluetooth.new(args)
widget = wibox.container.background,
forced_height = 0
},
{
{ -- action buttons
{ -- turn off
{
{
image = gcolor.recolor_image(icondir .. "power.svg",
Theme_config.bluetooth_controller.power_icon_color),
resize = false,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox,
id = "icon"
},
widget = wibox.container.margin,
margins = dpi(5),
id = "center"
},
border_width = dpi(2),
border_color = Theme_config.bluetooth_controller.border_color,
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(4))
end,
bg = Theme_config.bluetooth_controller.power_bg,
widget = wibox.container.background,
id = "power",
},
nil,
{ -- refresh
{
{
image = gcolor.recolor_image(icondir .. "refresh.svg",
Theme_config.bluetooth_controller.refresh_icon_color),
resize = false,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox,
},
widget = wibox.container.margin,
margins = dpi(5),
},
border_width = dpi(2),
border_color = Theme_config.bluetooth_controller.border_color,
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(4))
end,
bg = Theme_config.bluetooth_controller.refresh_bg,
widget = wibox.container.background
},
layout = wibox.layout.align.horizontal
},
widget = wibox.container.margin,
top = dpi(10),
},
id = "layout1",
layout = wibox.layout.fixed.vertical
},
@@ -229,15 +274,14 @@ function bluetooth.new(args)
"bluetooth::device_changed",
function(device, battery)
add_device(ret, device, battery)
remove_device(ret, device)
bluetooth_container:get_children_by_id("connected_device_list")[1].children = ret:get_devices().paired
bluetooth_container:get_children_by_id("discovered_device_list")[1].children = ret:get_devices().discovered
end
)
local connected_margin = bluetooth_container:get_children_by_id("connected_margin")[1]
local connected_list = bluetooth_container:get_children_by_id("connected_list")[1]
local connected_bg = bluetooth_container:get_children_by_id("connected_bg")[1]
local connected = bluetooth_container:get_children_by_id("connected")[1].center
connected_margin:connect_signal(
@@ -264,7 +308,7 @@ function bluetooth.new(args)
Theme_config.bluetooth_controller.connected_icon_color))
else
rubato_timer.target = 0
connected_bg.shape = function(cr, width, height)
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",
@@ -294,9 +338,10 @@ function bluetooth.new(args)
if discovered_list.forced_height == 0 then
local size = (#ret:get_devices().discovered * 60) + 1
if size < 210 then
rubato_timer.target = dpi(size)
if size > 210 then
size = 210
end
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

View File

@@ -0,0 +1,133 @@
---------------------------------------
-- This is the brightness_osd module --
---------------------------------------
-- 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/brightness/"
return function(s)
local brightness_osd_widget = wibox.widget {
{
{
{ -- Brightness Icon
image = gears.color.recolor_image(icondir .. "brightness-high.svg", Theme_config.brightness_osd.icon_color),
valign = "center",
halign = "center",
resize = false,
id = "icon",
widget = wibox.widget.imagebox
},
{ -- Brightness Bar
{
{
id = "progressbar1",
color = Theme_config.brightness_osd.bar_bg_active,
background_color = Theme_config.brightness_osd.bar_bg,
max_value = 100,
value = 0,
forced_height = dpi(6),
shape = function(cr, width, height)
gears.shape.rounded_bar(cr, width, height, dpi(6))
end,
widget = wibox.widget.progressbar
},
id = "progressbar_container2",
halign = "center",
valign = "center",
widget = wibox.container.place
},
id = "progressbar_container",
width = dpi(240),
heigth = dpi(20),
stragety = "max",
widget = wibox.container.constraint
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
forced_width = dpi(300),
forced_height = dpi(80),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
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,
widget = wibox.container.background
}
capi.awesome.connect_signal(
"brightness::get",
function(brightness)
brightness_osd_widget:get_children_by_id("progressbar1")[1].value = 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
brightness_osd_widget:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
Theme_config.brightness_osd.icon_color))
end
)
local brightness_container = awful.popup {
widget = {},
ontop = true,
stretch = false,
visible = false,
screen = s,
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
}
local hide_brightness_osd = gears.timer {
timeout = 2,
autostart = true,
callback = function()
brightness_container.visible = false
end
}
brightness_container:setup {
brightness_osd_widget,
layout = wibox.layout.fixed.horizontal
}
capi.awesome.connect_signal(
"brightness::rerun",
function()
if capi.mouse.screen == s then
brightness_container.visible = true
if hide_brightness_osd.started then
hide_brightness_osd:again()
else
hide_brightness_osd:start()
end
end
end
)
end

View File

@@ -7,6 +7,7 @@ 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 capi = {
awesome = awesome,
@@ -14,12 +15,13 @@ local capi = {
}
local ical_parser = require("src.tools.ical_parser")()
--local task_info = require("src.modules.calendar.task_info")
local task_info = require("src.modules.calendar.task_info")
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
local calendar = { mt = {} }
calendar.tasks = {}
calendar.calendars = {}
calendar._private = {}
@@ -57,6 +59,29 @@ calendar.date = {
year = tonumber(os.date("%Y")) or 1970
}
--#region base widget functions
function calendar:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
function calendar: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
calendar.set_widget = base.set_widget_common
function calendar:get_widget()
return self._private.widget
end
--#endregion
---Checks how many days a month has and returns the ammount. Also takes leap years into account.
---@param month number|nil
---@param year number|nil
@@ -147,6 +172,33 @@ end
function calendar:get_tasks()
if not ical_parser or not ical_parser.VCALENDAR then return end
local tasks = {}
local function task_factory(start_date, end_date, sum, loc, des, uid, freq)
table.insert(tasks, {
date_start = {
year = start_date.y,
month = start_date.m,
day = start_date.d,
hour = start_date.hour or 0,
min = start_date.min or 0,
sec = start_date.sec or 0
},
date_end = {
year = end_date.y,
month = end_date.m,
day = end_date.d,
hour = end_date.hour or 0,
min = end_date.min or 0,
sec = end_date.sec or 0
},
summary = sum,
location = loc,
description = des,
uid = uid,
freq = freq,
})
end
for _, cal in ipairs(ical_parser.VCALENDAR) do
for _, event in ipairs(cal.VEVENT) do
if not self:check_event_uid(event.UID) then
@@ -158,44 +210,60 @@ function calendar:get_tasks()
if event.DTEND then
end_time = event.DTEND.DTEND
end
-- Get repeat cases
if event.RRULE then
if event.RRULE.FREQ == "DAILY" then
elseif event.RRULE.FREQ == "WEEKLY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
end_time = event.RRULE.UNTIL
if not event.RRULE.UNTIL then
-- If there is no end time then we just set it to the start time
if not event.DTEND.DTEND then
end_time = {
year = start_time.year + 1000,
month = start_time.month,
day = start_time.day
day = start_time.day,
hour = start_time.hour,
min = start_time.min,
sec = start_time.sec
}
end
-- Get repeat cases
if event.RRULE 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
(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
}, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
while (year_counter < end_time.year) or (month_counter < end_time.month) or (day_counter <= end_time.day) do
table.insert(tasks, {
date_start = {
year = year_counter,
month = month_counter,
day = day_counter,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
date_end = {
year = year_counter,
month = month_counter,
day = day_counter,
hour = end_time.hour or 0,
minute = end_time.min or 0,
second = end_time.sec or 0
},
summary = event.SUMMARY,
location = event.LOCATION,
description = event.DESCRIPTION,
uid = event.UID
})
day_counter = day_counter + 1
if day_counter > calendar:get_last_day_in_month(month_counter, year_counter) then
day_counter = 1
month_counter = month_counter + 1
if month_counter > 12 then
month_counter = 1
year_counter = year_counter + 1
end
end
end
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 },
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)
if day_counter > month_length then
@@ -208,6 +276,20 @@ function calendar:get_tasks()
end
end
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 },
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
month_counter = month_counter + 1
if month_counter > 12 then
month_counter = 1
year_counter = year_counter + 1
end
end
elseif event.RRULE.FREQ == "YEARLY" then
end_time = event.RRULE.UNTIL
if not event.RRULE.UNTIL then
@@ -218,65 +300,32 @@ function calendar:get_tasks()
}
end
for i = start_time.year, end_time.year, 1 do
table.insert(tasks, {
date_start = {
year = i,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
date_end = {
year = i,
month = end_time.month,
day = end_time.day,
hour = end_time.hour or 0,
minute = end_time.min or 0,
second = end_time.sec or 0
},
summary = event.SUMMARY,
location = event.LOCATION,
description = event.DESCRIPTION,
url = event.URL.URL,
uid = event.UID
})
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,
event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
end
end
-- If RRULE is empty we just add a single day event
else
table.insert(tasks, {
date_start = {
year = start_time.year,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
date_end = {
year = start_time.year,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
summary = event.SUMMARY,
description = event.DESCRIPTION,
location = event.LOCATION,
url = event.URL,
uid = event.UID,
})
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 },
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
end
if event.VALARM then
-- send a notification 15 minutes before an event starts
-- send a notification X minutes before an event starts
end
end
end
end
--table.insert(calendars, tasks)
table.insert(self.tasks, tasks)
table.insert(self.calendars, {
tasks = self.tasks,
color = cal.color
})
end
end
---!Fix later, I have no idea how to calculate it and the internet has no clue either
@@ -360,10 +409,9 @@ function calendar:create_calendar_widget()
step = dpi(50),
spacing = dpi(2)
}
for _, cal in ipairs(self.tasks) do
for _, task in ipairs(cal) do
if (task.date_start.year == year) and (task.date_start.month == month) and (task.date_start.day == day) then
local tw = wibox.widget {
local function task_factory(task, bg)
return wibox.widget {
{
{
text = task.summary,
@@ -376,126 +424,67 @@ function calendar:create_calendar_widget()
widget = wibox.container.margin
},
fg = Theme_config.calendar.task.fg,
bg = Theme_config.calendar.task.bg,
bg = bg,
shape = Theme_config.calendar.task.shape,
forced_height = dpi(20),
widget = wibox.container.background
}
end
--[[ local ti = task_info {
for _, cal in ipairs(self.calendars) do
for _, tasks in ipairs(cal.tasks) do
for _, task in ipairs(tasks) do
if (task.date_start.year == year) and (task.date_start.month == month) and (task.date_start.day == day) then
-- Check if task if before the current date
local tw
if task.date_start.year < self.date.year or
(task.date_start.year == self.date.year and task.date_start.month < self.date.month) or
(
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")
else
tw = task_factory(task, cal.color)
end
local ti = task_info {
summary = task.summary,
description = task.description,
location = task.location,
url = task.url,
uid = task.uid,
date_start = task.date_start,
start_time = task.start_time,
date_end = task.date_end,
} ]]
local task_info_widget = wibox.widget {
{
{ -- Task detail
{ -- Calendar color
widget = wibox.container.background,
shape = function(cr, _, height)
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
end,
},
{
{ -- Summary
widget = wibox.widget.textbox,
text = task.summary,
valign = "center",
align = "left",
id = "summary",
},
{ -- Date long
widget = wibox.widget.textbox,
text = task.date_long,
valign = "center",
align = "right",
id = "date_long",
},
{ -- From - To
widget = wibox.widget.textbox,
text = task.from_to,
valign = "center",
align = "left",
id = "from_to",
},
{ -- Repeat information
widget = wibox.widget.textbox,
text = task.repeat_info,
valign = "center",
align = "right",
id = "repeat_info",
},
layout = wibox.layout.fixed.vertical,
},
layout = wibox.layout.fixed.horizontal
},
{ -- Location
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "location.svg",
Theme_config.calendar.border_color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = task.location,
valign = "center",
align = "left",
id = "location",
},
id = "location_container",
layout = wibox.layout.fixed.horizontal
},
{ -- Alarm
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "alarm.svg", Theme_config.calendar.fg),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = task.alarm,
valign = "center",
align = "left",
id = "alarm",
},
id = "alarm_container",
layout = wibox.layout.fixed.horizontal
},
id = "task_detail",
layout = wibox.layout.fixed.vertical
},
bg = Theme_config.calendar.bg,
fg = Theme_config.calendar.fg,
shape = function(cr, _, height)
gshape.rounded_rect(cr, height, height, dpi(8))
end,
widget = wibox.container.background,
end_time = task.end_time,
freq = task.freq,
task = task,
color = cal.color,
}
local task_popup = awful.popup {
widget = task_info_widget,
widget = ti,
ontop = true,
visible = true,
visible = false,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = self.screen
}
tw:connect_signal("button::down", function()
--ti:toggle()
tw:buttons(
gtable.join(
awful.button({}, 1, function()
task_popup.x = capi.mouse.coords().x
task_popup.y = capi.mouse.coords().y
task_popup.visible = not task_popup.visible
end)
)
)
tw:connect_signal("mouse::leave", function()
task_popup.visible = false
end)
Hover_signal(tw)
@@ -503,6 +492,8 @@ function calendar:create_calendar_widget()
end
end
end
end
return tasks_layout
end
@@ -749,10 +740,11 @@ end
function calendar.new(args)
args = args or {}
local ret = gobject { enable_properties = true, enable_auto_signals = true }
local ret = base.make_widget(nil, nil, { enable_properties = true })
gtable.crush(ret, calendar, true)
local calendar_widget = wibox.widget {
ret:set_widget(wibox.widget {
{
{
{
@@ -892,7 +884,7 @@ function calendar.new(args)
border_strategy = "inner",
fg = Theme_config.calendar.fg,
shape = Theme_config.calendar.shape,
}
})
ret:get_tasks()
@@ -901,37 +893,22 @@ function calendar.new(args)
ret:create_weekdays_widget()
ret:create_calendar_weeks_widget()
ret.widget = awful.popup {
widget = calendar_widget,
screen = args.screen,
ontop = true,
bg = "#00000000",
visible = false,
placement = function(c) awful.placement.align(c,
{ position = "top_right", margins = { right = dpi(10), top = dpi(65) } })
end
}
calendar_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 then return end
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()
end
)
end)
)
)
))
calendar_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'",
@@ -940,70 +917,57 @@ function calendar.new(args)
end
)
end)
)
)
))
calendar_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
calendar_widget:get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
calendar_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_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
calendar_widget:get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
calendar_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
calendar_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
calendar_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
calendar_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
calendar_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)
)
)
))
capi.awesome.connect_signal("calendar::toggle", function()
if capi.mouse.screen == args.screen then
ret.widget.visible = not ret.widget.visible
end
end)
return ret
end
function calendar.mt:__call(...)

View File

@@ -20,15 +20,24 @@ task_info._private = {}
function task_info.new(args)
args = args or {}
if not args.task then return end
args.screen = args.screen or awful.screen.focused()
local ret = gobject {}
gtable.crush(ret, task_info, true)
args.color = args.color or "#ffffff"
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 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,
@@ -36,74 +45,95 @@ function task_info.new(args)
{
{ -- Summary
widget = wibox.widget.textbox,
text = ret.summary,
text = args.summary:sub(1, -2) or "NO SUMMARY",
valign = "center",
align = "left",
halign = "left",
id = "summary",
},
{ -- Date long
widget = wibox.widget.textbox,
text = ret.date_long,
text = date_long_written or "01.12.1970",
valign = "center",
align = "right",
halign = "right",
id = "date_long",
},
{ -- From - To
widget = wibox.widget.textbox,
text = ret.from_to,
text = from_to or "",
valign = "center",
align = "left",
halign = "left",
id = "from_to",
},
{ -- Repeat information
widget = wibox.widget.textbox,
text = ret.repeat_info,
text = args.freq or "0",
valign = "center",
align = "right",
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)
},
{ -- Location
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "location.svg", Theme_config.calendar.task_info.location_icon_color),
image = gcolor.recolor_image(icondir .. "location.svg", args.color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = ret.location,
text = args.location:sub(1, -2) or "F303",
valign = "center",
align = "left",
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", Theme_config.calendar.task_info.alarm_icon_color),
image = gcolor.recolor_image(icondir .. "alarm.svg", args.color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = ret.alarm,
text = args.alarm or "NO ALARM",
valign = "center",
align = "left",
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(6),
right = dpi(15),
top = dpi(15),
bottom = dpi(15),
},
bg = Theme_config.calendar.task_info.bg,
fg = Theme_config.calendar.task_info.fg,
@@ -111,20 +141,13 @@ function task_info.new(args)
widget = wibox.container.background,
}
ret.widget = awful.popup {
widget = task_info_widget,
ontop = true,
visible = true,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = args.screen
}
ret.widget = task_info_widget
return ret.widget
end
function task_info.mt:__call(...)
task_info.new(...)
return task_info.new(...)
end
return setmetatable(task_info, task_info.mt)

View File

@@ -0,0 +1,214 @@
---------------------------------------
-- This is the brightness_osd module --
---------------------------------------
-- Awesome Libs
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 capi = {
awesome = awesome,
mouse = mouse
}
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
local context_menu = {
mt = {}
}
function context_menu:layout(_, width, height)
if self._private.widget then
return {
base.place_widget_at(self._private.widget, 0, 0, width, height)
}
end
end
function context_menu: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
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
}
if not wtemplate then
return
end
for _, entry in ipairs(entries) do
-- TODO: Figure out how to make a new widget from etemplate
local menu_entry = wibox.widget {
{
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role"
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
nil,
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "arrow_role"
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
layout = wibox.layout.align.horizontal
},
margins = dpi(5),
widget = wibox.container.margin
},
bg = Theme_config.desktop.context_menu.entry_bg,
fg = Theme_config.desktop.context_menu.entry_fg,
widget = wibox.container.background
}
Hover_signal(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)
end
gtable.crush(menu_entry, entry, true)
menu_entry:buttons(gtable.join {
abutton({
modifiers = {},
button = 1,
on_release = function()
if not entry.submenu then
entry.callback()
end
self.visible = false
end
})
})
if entry.submenu then
menu_entry.popup = awful.popup {
widget = self:make_entries(wtemplate, entry.submenu, spacing),
bg = Theme_config.desktop.context_menu.bg,
ontop = true,
fg = Theme_config.desktop.context_menu.fg,
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
}
local hide_timer = gtimer {
timeout = 0.1,
autostart = false,
single_shot = true,
callback = function()
menu_entry.popup.visible = false
end
}
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()
hide_timer:again()
end)
menu_entry.popup:connect_signal("mouse::enter", function()
hide_timer:stop()
end)
menu_entry:connect_signal("mouse::leave", function()
hide_timer:again()
end)
capi.awesome.connect_signal("submenu::close", function()
menu_entry.popup.visible = false
end)
end
table.insert(menu_entries, menu_entry)
end
return menu_entries
end
function context_menu:toggle()
self.x = capi.mouse.coords().x
self.y = capi.mouse.coords().y
self.visible = not self.visible
end
function context_menu.new(args)
args = args or {}
local ret = {}
gtable.crush(ret, context_menu, true)
ret = awful.popup {
widget = ret:make_entries(args.widget_template, args.entries, args.spacing),
bg = Theme_config.desktop.context_menu.bg,
fg = Theme_config.desktop.context_menu.fg,
ontop = true,
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,
x = capi.mouse.coords().x + 10,
y = capi.mouse.coords().y - 10
}
gtable.crush(ret, context_menu, true)
return ret
end
function context_menu.mt:__call(...)
return context_menu.new(...)
end
return setmetatable(context_menu, context_menu.mt)

View File

@@ -14,23 +14,6 @@ local capi = {
return function(s, widgets)
local top_center = awful.popup {
screen = s,
widget = wibox.container.background,
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,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
top_center:struts {
top = dpi(55)
}
local function prepare_widgets(w)
local layout = {
forced_height = dpi(50),
@@ -72,55 +55,53 @@ return function(s, widgets)
return layout
end
top_center:setup {
nil,
prepare_widgets(widgets),
nil,
layout = wibox.layout.fixed.horizontal
local top_center = awful.popup {
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,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
capi.client.connect_signal(
"manage",
function(c)
top_center:struts {
top = dpi(55)
}
capi.client.connect_signal("manage", function(c)
if #s.selected_tag:clients() < 1 then
top_center.visible = false
else
top_center.visible = true
end
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
top_center.visible = true
end
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
top_center.visible = true
end
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
top_center.visible = true
end
end
)
end)
end

View File

@@ -18,7 +18,7 @@ local json = require("src.lib.json-lua.json-lua")
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
local cm = require("src.modules.context_menu")
local cm = require("src.modules.context_menu.init")
return function(screen)
@@ -76,7 +76,7 @@ return function(screen)
for _, action in ipairs(program.actions) do
table.insert(action_entries, {
name = Gio.DesktopAppInfo.get_action_name(DAI, action) or "",
icon = action.icon or icondir .. "entry.svg",
icon = gears.color.recolor_image(action.icon or icondir .. "entry.svg", Theme_config.dock.cm_icon),
callback = function()
Gio.DesktopAppInfo.launch_action(DAI, action)
end
@@ -85,7 +85,7 @@ return function(screen)
table.insert(action_entries, {
name = "Remove from Dock",
icon = icondir .. "entry.svg",
icon = gears.color.recolor_image(icondir .. "entry.svg", Theme_config.dock.cm_icon),
callback = function()
local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r")
if not data then
@@ -111,9 +111,41 @@ return function(screen)
end
})
local context_menu = cm({
entries = action_entries
})
local context_menu = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
margins = dpi(5),
widget = wibox.container.margin
},
widget = wibox.container.background,
},
entries = action_entries,
spacing = dpi(10),
}
dock_element:buttons(gears.table.join(
awful.button({
@@ -131,10 +163,7 @@ return function(screen)
return
end
-- add offset so mouse is above widget, this is so the mouse::leave event triggers always
context_menu.x = capi.mouse.coords().x - 10
context_menu.y = capi.mouse.coords().y + 10 - context_menu.height
context_menu.visible = not context_menu.visible
cm_open = context_menu.visible
context_menu:toggle()
end
})
))

View File

@@ -25,7 +25,7 @@ return function(s)
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")())
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
@@ -52,8 +52,8 @@ return function(s)
return widget_table
end
if User_config.widgets then
for index, screen in ipairs(User_config.widgets) do
if User_config.crylia_bar then
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))

View File

@@ -9,25 +9,6 @@ local wibox = require("wibox")
return function(s, w)
local top_left = awful.popup {
screen = s,
widget = {
},
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,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
top_left:struts {
top = dpi(55)
}
local function prepare_widgets(widgets)
local layout = {
forced_height = dpi(50),
@@ -69,10 +50,22 @@ return function(s, w)
return layout
end
top_left:setup {
prepare_widgets(w),
nil,
nil,
layout = wibox.layout.fixed.horizontal
}
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,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
top_left:struts {
top = dpi(55)
}
Global_config.top_struts = dpi(55)
end

View File

@@ -9,22 +9,6 @@ local wibox = require("wibox")
return function(s, w)
local top_right = awful.popup {
widget = wibox.container.background,
ontop = false,
bg = Theme_config.right_bar.bg,
visible = true,
screen = s,
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
top_right:struts {
top = dpi(55)
}
local function prepare_widgets(widgets)
local layout = {
forced_height = dpi(50),
@@ -66,10 +50,21 @@ return function(s, w)
return layout
end
top_right:setup {
nil,
nil,
prepare_widgets(w),
layout = wibox.layout.align.horizontal
}
local top_right = awful.popup {
widget = prepare_widgets(w),
ontop = false,
bg = Theme_config.right_bar.bg,
visible = true,
screen = s,
placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end
}
top_right:struts {
top = dpi(55)
}
Global_config.top_struts = top_right
end

View File

@@ -0,0 +1,129 @@
--------------------------------------------------------------------------------------------------------------
-- 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")
return function(s)
---Lookup function to return the widget from its easy name string
---@param widgets table
---@return widget
local function get_widgets(widgets)
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))
end
end
end
return widget_table
end
if User_config.crylia_wibox then
for index, screen in ipairs(User_config.crylia_wibox) do
if index == s.index then
local function prepare_widgets(widgets)
local layout = {
forced_height = dpi(50),
layout = wibox.layout.fixed.horizontal
}
for i, widget in pairs(widgets) do
if i == 1 then
table.insert(layout,
{
widget,
left = dpi(6),
right = dpi(3),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
elseif i == #widgets then
table.insert(layout,
{
widget,
left = dpi(3),
right = dpi(6),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
else
table.insert(layout,
{
widget,
left = dpi(3),
right = dpi(3),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
end
end
return layout
end
local w = wibox {
widget = {
prepare_widgets(get_widgets(screen.left_bar)),
prepare_widgets(get_widgets(screen.center_bar)),
prepare_widgets(get_widgets(screen.right_bar)),
layout = wibox.layout.align.horizontal,
},
visible = true,
x = 0,
y = 1035,
type = "desktop",
height = dpi(55),
width = 1920,
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)
}
Global_config.bottom_struts = dpi(55)
end
end
end
end

View File

@@ -0,0 +1,54 @@
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 w
end
function context_menu.mt:__call(...)
return context_menu.new(...)
end
return setmetatable(context_menu, context_menu.mt)

View File

@@ -0,0 +1,605 @@
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 element = require("src.modules.desktop.element")
local cm = require("src.modules.context_menu.init")
local capi = {
mouse = mouse,
awesome = awesome
}
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/"
if not gfilesystem.dir_readable(dir) then
gfilesystem.make_directories(dir)
end
for i, widget in ipairs(self.widget.mrgn.grid.children) do
local pos = self.widget.mrgn.grid:get_widget_position(widget)
layout[i] = {
row = pos.row,
col = pos.col,
widget = {
icon = widget.icon,
label = widget:get_children_by_id("text_role")[1].text,
exec = widget.exec,
icon_size = widget.icon_size
}
}
end
local dir = gfilesystem.get_configuration_dir() .. "src/config"
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()
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 layout = json:decode(handler:read("*all"))
handler:close()
if not layout then return end
for i, value in pairs(layout) 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]
end
function desktop:add_desktop_file(app_info)
self:add_element({
icon = app_info.icon,
label = app_info.label,
exec = app_info.exec,
icon_size = dpi(96),
desktop_file = app_info.desktop_file,
parent = self.widget.mrgn.grid,
})
end
--[[
Removes a given widget and returns it
]]
function desktop:remove_element(e)
return (self.widget.mrgn.grid:remove(e) and e) or nil
end
function desktop:get_grid_index_at(y, x)
local col, row = 1, 1
local width = dpi(96) * 1.75 * (4 / 3)
local height = dpi(96) * 1.75
local spacing = dpi(10)
while width * col + spacing * (col - 1) < x do
col = col + 1
end
while height * row + spacing * (row - 1) < y do
row = row + 1
end
return col, row
end
---Main function to add an element to the desktop
---it will automatically place it on an empty spot and save it
---@param args table widget arguments
---@param pos table|nil {x = , y = }
function desktop:add_element(args, pos)
-- add into next available position
local x, y = self.widget.mrgn.grid:get_next_empty()
if pos then
x = pos.x
y = pos.y
end
local e = element {
icon = args.icon,
label = args.label,
exec = args.exec,
icon_size = args.icon_size,
desktop_file = args.desktop_file,
parent = args.parent
}
local cm_popup = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
layout = wibox.layout.fixed.horizontal
},
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),
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),
callback = function()
end
},
{
name = "Cut",
icon = gcolor.recolor_image(icondir .. "cut.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
name = "Rename",
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
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
},
{
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.visible = false
end)
-- 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()
if not mousegrabber.isrunning() then
local width = args.icon_size * 1.75 * (4 / 3)
local height = args.icon_size * 1.75
local dnd_widget = element {
icon = args.icon,
label = args.label,
on_click = args.on_click,
icon_size = args.icon_size,
parent = args.parent,
width = width,
height = 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 }
local old_pos = self.widget.mrgn.grid:get_widget_position(e)
self.widget.manual:add(dnd_widget)
mousegrabber.run(function(m)
if (math.abs(m.x - start_pos.x) > 10 or
math.abs(m.x - start_pos.x) < -10 or
math.abs(m.y - start_pos.y) > 10 or
math.abs(m.y - start_pos.y) < -10) and
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 })
end
if not m.buttons[1] then
if b == 1 then
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)
self:save_layout()
else
self.widget.mrgn.grid:add_widget_at(e, old_pos.row, old_pos.col)
end
else
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(e.exec, nil, 0))
self.widget.manual:reset()
end
mousegrabber.stop()
elseif b == 3 then
cm_popup:toggle()
mousegrabber.stop()
end
end
return m.buttons[1]
end, "left_ptr")
end
end)
self.widget.mrgn.grid:add_widget_at(e, x, y)
self:save_layout()
end
function desktop:draw_selector()
local start_pos = mouse.coords()
if not mousegrabber.isrunning() then
local selector = wibox.widget {
widget = wibox.container.background,
bg = gcolor("#0ffff088"),
border_color = gcolor("#0ffff0"),
border_width = dpi(2),
width = 100,
height = 100,
visible = true,
shape = function(cr, w, h)
gshape.rounded_rect(cr, w, h, dpi(10))
end
}
local coords = capi.mouse.coords()
selector.point = { x = coords.x, y = coords.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
mousegrabber.stop()
selector.visible = false
self.widget.manual:reset()
end
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-home.svg",
label = "Persönlicher Ordner",
exec = "nautilus file:/home/crylia",
icon_size = 96,
})
end
function desktop.new(args)
args = args or {}
args.screen = args.screen or awful.screen.focused()
local icon_size = args.icon_size or dpi(96)
-- calculate the row and column count based on the screen size and icon size and aspect ratio of 16:9
local screen_width = awful.screen.focused().geometry.width
local screen_height = awful.screen.focused().geometry.height
local aspect_ratio = 4 / 3
local cols = math.floor(screen_width / (icon_size * 1.75 * aspect_ratio))
local rows = math.floor((screen_height - (dpi(75 + 95))) / (icon_size * 1.75))
--[[
The wibox has a stacked layout with a manual layout over a grid.
stacked
manual
grid
manual: For positioning the dragged element since this layout allows for arbitrary positioning.
grid: For positioning the elements in a grid.
]]
local w = wibox {
ontop = false,
visible = true,
type = "desktop",
input_passthrough = false,
x = 0,
y = 0,
bg = gcolor.transparent,
width = 1920,
height = 1080,
screen = args.screen,
widget = wibox.widget {
{
{
layout = grid,
homogeneous = true,
spacing = dpi(10),
expand = true,
orientation = "horizontal",
forced_num_cols = cols,
forced_num_rows = rows,
id = "grid",
},
widget = wibox.container.margin,
left = dpi(10),
right = dpi(10),
top = dpi(75),
bottom = dpi(95),
id = "mrgn"
},
{
layout = wibox.layout.manual,
id = "manual",
},
layout = wibox.layout.stack,
}
}
local cm_popup = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
layout = wibox.layout.fixed.horizontal
},
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),
submenu = {
{
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 i = 1
while gfilesystem.dir_readable(folder_path) do
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",
label = folder_name,
exec = "nautilus file:\"" .. folder_path .. "\"",
icon_size = icon_size,
})
end
},
{
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 i = 1
while gfilesystem.file_readable(file_path) do
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",
label = file_name,
exec = "xdg-open " .. file_path,
icon_size = icon_size,
})
end
}
}
},
{
name = "Terminal",
icon = gcolor.recolor_image(icondir .. "terminal.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.terminal)
end
},
{
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
},
{
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
},
{
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
},
{
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
},
{
name = "Applications",
icon = gcolor.recolor_image(icondir .. "application.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
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
},
{
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
},
{
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
},
{
name = "Reload Awesome",
icon = gcolor.recolor_image(icondir .. "refresh.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
capi.awesome.restart()
end
},
{
name = "Quit",
icon = gcolor.recolor_image(icondir .. "quit.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
capi.awesome.quit()
end
},
--cm_awesome
}
}
w.widget.manual:buttons(
gtable.join(
awful.button(
{},
1,
function()
cm_popup.visible = false
if capi.mouse.current_widgets[4] == w.widget.manual then
--w:draw_selector()
end
end
),
awful.button(
{},
3,
function()
if capi.mouse.current_widgets[4] == w.widget.manual then
cm_popup:toggle()
end
end
)
)
)
gtable.crush(w, desktop, true)
w:load_layout()
capi.awesome.connect_signal("desktop::add_to_desktop", function(args2)
w:add_desktop_file(args2)
end)
return w
end
function desktop.mt:__call(...)
return desktop.new(...)
end
return setmetatable(desktop, desktop.mt)

View File

@@ -0,0 +1,119 @@
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 element = { mt = {} }
function element:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
function element: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
function element:get_widget()
return self._private.widget
end
function element:on_hover()
self:connect_signal("mouse::enter", function()
self.bg = "#0ffff033"
self.border_color = "#0ffff099"
end)
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"
end)
end
function element.new(args)
args = args or {}
local w = base.make_widget_from_value(wibox.widget {
{
{
{
{
image = args.icon,
resize = true,
clip_shape = gshape.rounded_rect,
valign = "center",
halign = "center",
id = "icon_role",
widget = wibox.widget.imagebox
},
strategy = "exact",
height = args.icon_size,
width = args.icon_size,
widget = wibox.container.constraint
},
{
text = args.label,
id = "text_role",
valign = "center",
halign = "center",
widget = wibox.widget.textbox
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
widget = wibox.container.place,
valign = "center",
halign = "center"
},
fg = "#ffffff",
bg = gcolor.transparent,
border_color = gcolor.transparent,
border_width = dpi(2),
shape = gshape.rounded_rect,
forced_width = args.width,
forced_height = args.height,
width = args.width,
height = args.height,
exec = args.exec,
icon_size = args.icon_size,
icon = args.icon,
widget = wibox.container.background
})
gtable.crush(w, element, true)
w:on_hover()
return w
end
function element.mt:__call(...)
return element.new(...)
end
return setmetatable(element, element.mt)

View File

@@ -17,16 +17,20 @@ awful.screen.connect_for_each_screen(
User_config.layouts[1]
)
require("src.modules.powermenu")(s)
require("src.modules.volume_osd")(s)
require("src.modules.brightness_osd")(s)
require("src.modules.desktop.context_menu") { screen = s }
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")(s)
require("src.modules.bluetooth.init") { screen = s }
require("src.modules.titlebar")
require("src.modules.volume_controller")(s)
require("src.modules.titlebar.titlebar")
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")(s)
require("src.modules.calendar.init") { screen = s }
require("src.modules.application_launcher.init") { screen = s }
--require("src.modules.calendar.init") { screen = s }
require("src.modules.network_controller.init") { screen = s }
end
)

View File

@@ -0,0 +1,168 @@
------------------------------------
-- This is the network controller --
------------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears").table
local gfilesystem = require("gears").filesystem
local gobject = require("gears").object
local gcolor = require("gears").color
local wibox = require("wibox")
local ap_form = require("src.modules.network_controller.ap_form")
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
local access_point = { mt = {} }
access_point.connected = false
function access_point.new(args)
args = args or {}
if not args.access_point then return end
local ret = gobject { enable_properties = true, enable_auto_signals = true }
gtable.crush(ret, access_point, true)
local strength = args.access_point.strength or 0
--normalize strength between 1 and 4
strength = math.floor(strength / 25) + 1
local icon = "wifi-strength-" .. strength .. ".svg"
local bg, fg, icon_color = Theme_config.network_manager.access_point.bg, Theme_config.network_manager.access_point.fg,
Theme_config.network_manager.access_point.icon_color
if args.active == args.access_point.access_point_path then
bg, fg, icon_color = Theme_config.network_manager.access_point.fg, Theme_config.network_manager.access_point.bg,
Theme_config.network_manager.access_point.icon_color2
end
local ap_widget = wibox.widget {
{
{
{
{
{
image = gcolor.recolor_image(
icondir .. icon, icon_color),
id = "icon",
resize = true,
valign = "center",
halign = "center",
forced_width = dpi(24),
forced_height = dpi(24),
widget = wibox.widget.imagebox
},
id = "icon_container",
strategy = "max",
width = dpi(24),
height = dpi(24),
widget = wibox.container.constraint
},
{
{
{
text = args.access_point.ssid or args.access_point.hw_address or "Unknown",
id = "alias",
widget = wibox.widget.textbox
},
{
text = "Connecting...",
id = "connecting",
visible = false,
font = User_config.font.specify .. ", regular 10",
widget = wibox.widget.textbox
},
id = "alias_container",
layout = wibox.layout.fixed.horizontal
},
width = dpi(260),
height = dpi(40),
strategy = "max",
widget = wibox.container.constraint
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
{ -- Spacing
forced_width = dpi(10),
widget = wibox.container.background
},
{
{
{
{
id = "con",
resize = false,
valign = "center",
halign = "center",
forced_width = dpi(24),
forced_height = dpi(24),
widget = wibox.widget.imagebox
},
id = "place",
strategy = "max",
width = dpi(24),
height = dpi(24),
widget = wibox.container.constraint
},
id = "margin",
margins = dpi(2),
widget = wibox.container.margin
},
id = "margin0",
margin = dpi(5),
widget = wibox.container.margin
},
id = "device_layout",
layout = wibox.layout.align.horizontal
},
id = "device_margin",
margins = dpi(5),
widget = wibox.container.margin
},
bg = bg,
fg = fg,
border_color = Theme_config.network_manager.access_point.border_color,
border_width = Theme_config.network_manager.access_point.border_width,
id = "background",
shape = Theme_config.network_manager.access_point.device_shape,
device = ret.access_point,
widget = wibox.container.background
}
ap_form { screen = args.screen, SSID = args.access_point.ssid }
ap_widget:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
ap_form:popup_toggle()
end
)
)
)
ap_widget:get_children_by_id("con")[1].image = gcolor.recolor_image(
icondir .. "link.svg", icon_color)
Hover_signal(ap_widget)
ret.widget = ap_widget
return ret
end
function access_point.mt:__call(...)
return access_point.new(...)
end
return setmetatable(access_point, access_point.mt)

View File

@@ -0,0 +1,262 @@
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears.table")
local gobject = require("gears.object")
local gcolor = require("gears.color")
local gshape = require("gears.shape")
local gfilesystem = require("gears.filesystem")
local wibox = require("wibox")
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
local capi = {
awesome = awesome,
mousegrabber = mousegrabber
}
local ap_form = { mt = {} }
ap_form._private = {}
ap_form.settigns_form = {
ssid = awful.widget.inputbox {
widget_template = wibox.template {
widget = wibox.widget {
{
{
{
widget = wibox.widget.textbox,
halign = "left",
valign = "center",
id = "text_role",
},
widget = wibox.container.margin,
margins = 5,
id = "marg"
},
widget = wibox.container.constraint,
strategy = "exact",
width = 400,
height = 50,
id = "const"
},
widget = wibox.container.background,
bg = "#212121",
fg = "#F0F0F0",
border_color = "#414141",
border_width = 2,
shape = gshape.rounded_rect,
forced_width = 300,
forced_height = 50,
},
update_callback = function(template_widget, args)
template_widget.widget.const.marg.text_role.markup = args.text
end
}
},
password = awful.widget.inputbox {
widget_template = wibox.template {
widget = wibox.widget {
{
{
{
widget = wibox.widget.textbox,
halign = "left",
valign = "center",
id = "text_role",
},
widget = wibox.container.margin,
margins = 5,
id = "marg"
},
widget = wibox.container.constraint,
strategy = "exact",
width = 400,
height = 50,
id = "const"
},
widget = wibox.container.background,
bg = "#212121",
fg = "#F0F0F0",
border_color = "#414141",
border_width = 2,
shape = gshape.rounded_rect,
forced_width = 300,
forced_height = 50,
},
update_callback = function(template_widget, args)
template_widget.widget.const.marg.text_role.markup = args.text
end
}
},
}
function ap_form:popup_toggle()
self._private.popup.visible = not self._private.popup.visible
end
function ap_form.new(args)
args = args or {}
args.screen = args.screen or awful.screen.preferred()
local ret = gobject {}
ret._private = {}
gtable.crush(ret, ap_form, true)
gtable.crush(ret, args)
ret._private.popup = awful.popup {
widget = {
{ -- Header
{
nil,
{
{
widget = wibox.widget.textbox,
text = args.SSID,
halign = "center",
valign = "center",
},
widget = wibox.container.margin,
margins = dpi(5)
},
{ -- Close button
{
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "close.svg", Theme_config.network_manager.form.icon_fg),
resize = false,
valign = "center",
halign = "center",
},
widget = wibox.container.margin,
},
widget = wibox.container.background,
id = "close_button",
bg = Theme_config.network_manager.form.close_bg
},
layout = wibox.layout.align.horizontal
},
widget = wibox.container.background,
bg = Theme_config.network_manager.form.header_bg,
fg = Theme_config.network_manager.form.header_fg,
},
{ -- Form
{ -- SSID
{
widget = wibox.widget.textbox,
text = "SSID",
halign = "center",
valign = "center"
},
nil,
-- Change to inputtextbox container
ret.settigns_form.ssid,
layout = wibox.layout.align.horizontal
},
{ -- Password
{
widget = wibox.widget.textbox,
text = "Password",
halign = "center",
valign = "center"
},
nil,
-- Change to inputtextbox container
ret.settigns_form.password,
layout = wibox.layout.align.horizontal
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
{ -- Actions
{ -- Auto connect
{
{
checked = false,
shape = Theme_config.network_manager.form.checkbox_shape,
color = Theme_config.network_manager.form.checkbox_bg,
check_color = Theme_config.network_manager.form.checkbox_fg,
check_border_color = Theme_config.network_manager.form.check_border_color,
check_border_width = Theme_config.network_manager.form.check_border_width,
widget = wibox.widget.checkbox
},
widget = wibox.container.constraint,
strategy = "exact",
width = dpi(30),
height = dpi(30)
},
{
widget = wibox.widget.textbox,
text = "Auto connect",
halign = "center",
valign = "center"
},
layout = wibox.layout.fixed.horizontal
},
nil,
{ -- Connect
{
{
widget = wibox.widget.textbox,
text = "Connect",
halign = "center",
valign = "center"
},
widget = wibox.container.background,
bg = Theme_config.network_manager.form.button_bg,
fg = Theme_config.network_manager.form.button_fg,
},
widget = wibox.container.margin,
margins = dpi(10),
},
layout = wibox.layout.align.horizontal
},
layout = wibox.layout.align.vertical
},
placement = awful.placement.centered,
ontop = true,
visible = false,
width = dpi(600),
height = dpi(400),
bg = Theme_config.network_manager.form.bg,
fg = Theme_config.network_manager.form.fg,
shape = Theme_config.network_manager.form.shape,
type = "dialog",
screen = args.screen,
}
ret._private.popup.widget:get_children_by_id("close_button")[1]:connect_signal("button::press", function()
ret:popup_toggle()
end)
ret.settigns_form.ssid:connect_signal(
"submit",
function(text)
end
)
ret.settigns_form.ssid:connect_signal(
"stopped",
function()
end
)
ret.settigns_form.password:connect_signal(
"submit",
function(text)
end
)
ret.settigns_form.password:connect_signal(
"stopped",
function()
end
)
return ret
end
function ap_form.mt:__call(...)
return ap_form.new(...)
end
return setmetatable(ap_form, ap_form.mt)

View File

@@ -4,113 +4,657 @@
-- Awesome Libs
local awful = require("awful")
local dbus_proxy = require("dbus_proxy")
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears").table
local gtimer = require("gears").timer
local gshape = require("gears").shape
local gobject = require("gears").object
local gcolor = require("gears").color
local gears = require("gears")
local lgi = require("lgi")
local wibox = require("wibox")
local NM = require("lgi").NM
local rubato = require("src.lib.rubato")
local access_point = require("src.modules.network_controller.access_point")
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/network/"
return function(s)
local capi = {
awesome = awesome,
}
local function get_connected_network()
local network = { mt = {} }
network.access_points = { layout = wibox.layout.fixed.vertical }
network.NMState = {
UNKNOWN = 0,
ASLEEP = 10,
DISCONNECTED = 20,
DISCONNECTING = 30,
CONNECTING = 40,
CONNECTED_LOCAL = 50,
CONNECTED_SITE = 60,
CONNECTED_GLOBAL = 70,
}
network.DeviceType = {
ETHERNET = 1,
WIFI = 2
}
network.DeviceState = {
UNKNOWN = 0,
UNMANAGED = 10,
UNAVAILABLE = 20,
DISCONNECTED = 30,
PREPARE = 40,
CONFIG = 50,
NEED_AUTH = 60,
IP_CONFIG = 70,
IP_CHECK = 80,
SECONDARIES = 90,
ACTIVATED = 100,
DEACTIVATING = 110,
FAILED = 120
}
local function flags_to_security(flags, wpa_flags, rsn_flags)
local str = ""
if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then
str = str .. " WEP"
end
if wpa_flags ~= 0 then
str = str .. " WPA1"
end
if not rsn_flags ~= 0 then
str = str .. " WPA2"
end
if wpa_flags == 512 or rsn_flags == 512 then
str = str .. " 802.1X"
end
local network_controller = wibox.widget {
{
{
{ -- Connected
{ --Connected header
{
{
text = "Connected to",
widget = wibox.widget.textbox
},
widget = wibox.container.background
},
widget = wibox.container.margin
},
{ -- Connected network
{
get_connected_network(),
widget = wibox.container.background
},
widget = wibox.container.margin
},
layout = wibox.layout.fixed.vertical
},
{ -- Discovered networks
{ --Discovered header
{
{
text = "Available networks",
widget = wibox.widget.textbox
},
widget = wibox.container.background
},
widget = wibox.container.margin
},
{ -- Discovered networks list
return (str:gsub("^%s", ""))
end
local function get_wifi_proxy(self)
local devices = self._private.client_proxy:GetDevices()
for _, device in ipairs(devices) do
local device_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.Device",
path = device
}
if device_proxy.DeviceType == network.DeviceType.WIFI then
self._private.device_proxy = device_proxy
self._private.wifi_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.Device.Wireless",
path = device
}
self._private.device_proxy:connect_signal(function(proxy, new_state, old_state, reason)
local active_access_point_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.AccessPoint",
path = self._private.wifi_proxy.ActiveAccessPoint
}
self:emit_signal(tostring(active_access_point_proxy.HwAddress) .. "::state", new_state, old_state)
if new_state == network.DeviceState.ACTIVATED then
local ssid = NM.utils_ssid_to_utf8(active_access_point_proxy.Ssid)
self:emit_signal("NM::AccessPointConnected", ssid, active_access_point_proxy.Strength)
end
end, "StateChanged")
end
end
end
function network.device_state_to_string(state)
local device_state_to_string =
{
[0] = "Unknown",
[10] = "Unmanaged",
[20] = "Unavailable",
[30] = "Disconnected",
[40] = "Prepare",
[50] = "Config",
[60] = "Need Auth",
[70] = "IP Config",
[80] = "IP Check",
[90] = "Secondaries",
[100] = "Activated",
[110] = "Deactivated",
[120] = "Failed"
}
return device_state_to_string[state]
end
local function get_access_point_connections(self, ssid)
local connection_proxies = {}
local connections = self._private.settings_proxy:ListConnections()
for _, connection_path in ipairs(connections) do
local connection_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.Settings.Connection",
path = connection_path
}
if connection_proxy.Filename:find(ssid) then
table.insert(connection_proxies, connection_proxy)
end
end
return connection_proxies
end
local function generate_uuid()
local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
local uuid = string.gsub(template, '[xy]', function(c)
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
return string.format('%x', v)
end)
return uuid
end
local function create_profile(ap, password, auto_connect)
local s_con =
{
-- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface),
["uuid"] = lgi.GLib.Variant("s", generate_uuid()),
["id"] = lgi.GLib.Variant("s", ap.ssid),
["type"] = lgi.GLib.Variant("s", "802-11-wireless"),
["autoconnect"] = lgi.GLib.Variant("b", auto_connect),
}
local s_ip4 =
{
["method"] = lgi.GLib.Variant("s", "auto")
}
local s_ip6 =
{
["method"] = lgi.GLib.Variant("s", "auto"),
}
local s_wifi =
{
["mode"] = lgi.GLib.Variant("s", "infrastructure"),
}
local s_wsec = {}
if ap.security ~= "" then
if ap.security:match("WPA") ~= nil 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", helpers.string.trim(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", helpers.string.trim(password))
end
end
return {
["connection"] = s_con,
["ipv4"] = s_ip4,
["ipv6"] = s_ip6,
["802-11-wireless"] = s_wifi,
["802-11-wireless-security"] = s_wsec
}
end
function network:scan_access_points()
self._private.access_points = {}
self._private.wifi_proxy:RequestScanAsync(function(proxy, context, success, failure)
if failure ~= nil then
self.access_points = { layout = wibox.layout.fixed.vertical }
self:emit_signal("NM::AccessPointsFound", self.access_points[1].ssid)
self:emit_signal("NM::ScanFailed", tostring(failure))
return
end
local access_points = self._private.wifi_proxy:GetAllAccessPoints()
self._private.access_points = {}
if (not access_point) or (#access_points == 0) then
self.access_points = { layout = wibox.layout.fixed.vertical }
self:emit_signal("NM::AccessPointsFound", self.access_points[1].ssid)
end
for _, ap in ipairs(access_points) do
local access_point_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.AccessPoint",
path = ap
}
if access_point_proxy.Ssid then
local appSsid = access_point_proxy.Ssid or ""
local ssid = NM.utils_ssid_to_utf8(appSsid) or ""
local security = flags_to_security(access_point_proxy.Flags, access_point_proxy.WpaFlags)
local password = ""
local connections = get_access_point_connections(self, ssid)
for _, connection in ipairs(connections) do
if connection.Filename:find(ssid) then
local secrets = connection:GetSecrets("802-11-wireless-security")
if secrets then
password = secrets["802-11-wireless-security"].psk
end
end
end
table.insert(self._private.access_points, {
ssid = ssid,
security = security,
password = password,
strength = access_point_proxy.Strength,
hw_address = access_point_proxy.HwAddress,
device_interface = self._private.device_proxy.Interface,
device_path = self._private.device_proxy.object_path,
access_point_path = ap
})
end
end
self.access_points = { layout = wibox.layout.fixed.vertical }
local seen = {}
for _, ap2 in ipairs(self._private.access_points) do
if not seen[ap2.ssid] then
seen[ap2.ssid] = true
table.insert(self.access_points,
access_point.new { access_point = ap2, active = self._private.wifi_proxy.ActiveAccessPoint }.widget)
end
end
table.sort(self._private.access_points, function(a, b)
return a.strength > b.strength
end)
self:emit_signal("NM::AccessPointsFound", self.access_points[1].ssid)
end, { call_id = "my-id" }, {})
end
function network:toggle()
self.container.visible = not self.container.visible
end
function network:is_ap_active(ap)
print(self._private.wifi_proxy.ActiveAccessPoint)
return ap.path == self._private.wifi_proxy.ActiveAccessPoint
end
function network:disconnect_ap()
self._private.client_proxy:DeactivateConnection(self._private.device_proxy.ActiveConnection)
end
function network:connect_ap(ap, pw, auto_connect)
local connections = get_access_point_connections(self, ap.ssid)
local profile = create_profile(ap, pw, auto_connect)
if #connections == 0 then
self._private.client_proxy:AddAndActivateConnectionAsync(function(proxy, context, success, failure)
if failure then
self:emit_signal("NM::AccessPointFailed", tostring(failure))
return
end
self:emit_signal("NM::AccessPointConnected", ap.ssid)
end, { call_id = "my-id", profile, ap.device_proxy_path, ap.path })
else
connections[1]:Update(profile)
self._private.client_proxy:ActivateConnectionAsync(function(proxy, context, success, failure)
if failure then
self:emit_signal("NM::AccessPointFailed", tostring(failure))
return
end
self:emit_signal("NM::AccessPointConnected", ap.ssid)
end, { call_id = "my-id", connections[1].object_path, ap.device_proxy_path, ap.path })
end
end
function network:toggle_access_point(ap, password, auto_connect)
if self:is_ap_active(ap) then
self:disconnect_ap()
else
self:connect_ap(ap, password, auto_connect)
end
end
function network:toggle_wireless()
local enable = not self._private.client_proxy.WirelessEnabled
if enable then
self._private.client_proxy:Enable(true)
end
self._private.client_proxy:Set("org.freedesktop.NetworkManager", "WirelessEnabled", lgi.GLib.Variant("b", enable))
return enable
end
function network.new(args)
args = args or {}
local ret = gobject {}
gtable.crush(ret, network, true)
ret._private = {}
ret._private.client_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager",
path = "/org/freedesktop/NetworkManager",
}
ret._private.settings_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.Settings",
path = "/org/freedesktop/NetworkManager/Settings",
}
local property_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.DBus.Properties",
path = "/org/freedesktop/NetworkManager",
}
-- dbus proxy signals are in reversed order (function, signal)
property_proxy:connect_signal(function(_, properties, data)
if data.WirelessEnables ~= nil and ret._private.WirelessEnabled ~= data.WirelessEnabled then
ret._private.WirelessEnabled = data.WirelessEnabled
ret:emit_signal("NM::WirelessStateChanged", ret._private.WirelessEnabled)
if data.WirelessEnabled then
gtimer {
timeout = 5,
autostart = true,
call_now = false,
single_shot = true,
callback = function()
ret:get_access_points()
end
}
end
end
end, "PropertiesChanged")
get_wifi_proxy(ret)
ret:scan_access_points()
gtimer.delayed_call(function()
ret:emit_signal("NM::WirelessStateChanged", ret._private.client_proxy.WirelessEnabled)
local active_access_point = ret._private.wifi_proxy.ActiveAccessPoint
if ret._private.device_proxy.State == network.DeviceState.ACTIVATED and active_access_point ~= "/" then
local active_access_point_proxy = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = "org.freedesktop.NetworkManager",
interface = "org.freedesktop.NetworkManager.AccessPoint",
path = active_access_point,
}
local ssid = NM.utils_ssid_to_utf8(active_access_point_proxy.Ssid)
ret:emit_signal("NM:AccessPointConnected", ssid, active_access_point_proxy.Strength)
end
end)
local network_widget = wibox.widget {
{
{
{
{
{
{
{
{
resize = false,
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"
},
id = "center",
halign = "center",
valign = "center",
widget = wibox.container.place,
},
{
{
text = "Wifi Networks",
widget = wibox.widget.textbox,
id = "ap_name"
},
margins = dpi(5),
widget = wibox.container.margin
},
id = "wifi",
layout = wibox.layout.fixed.horizontal
},
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
},
id = "wifi_margin",
widget = wibox.container.margin
},
{
id = "wifi_list",
{
{
step = dpi(50),
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
{ -- Airplanemode/Refresh buttons
{ -- Airplane mode toggle
{
{
{
-- TODO: Replace with image
text = "Airplane mode",
widget = wibox.widgeet.textbox
layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0,
id = "wifi_ap_list"
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
border_color = Theme_config.network_manager.ap_border_color,
border_width = Theme_config.network_manager.ap_border_width,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5))
gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4))
end,
widget = wibox.container.background
widget = wibox.container.background,
forced_height = 0
},
widget = wibox.container.margin
},
{ -- Refresh button
{
{ -- action buttons
{ -- refresh
{
{
{
-- TODO: Replace with image
text = "Refresh",
widget = wibox.widgeet.textbox
image = gcolor.recolor_image(icondir .. "refresh.svg",
Theme_config.network_manager.refresh_icon_color),
resize = false,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox,
id = "icon"
},
widget = wibox.container.margin
widget = wibox.container.margin,
margins = dpi(5),
id = "center",
},
border_width = dpi(2),
border_color = Theme_config.network_manager.border_color,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5))
gshape.rounded_rect(cr, width, height, dpi(4))
end,
widget = wibox.container.background
bg = Theme_config.network_manager.refresh_bg,
widget = wibox.container.background,
id = "refresh"
},
widget = wibox.container.margin
nil,
{ -- airplane mode
{
{
image = gcolor.recolor_image(icondir .. "airplane-off.svg",
Theme_config.network_manager.airplane_icon_color),
resize = false,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox,
id = "icon"
},
widget = wibox.container.margin,
margins = dpi(5),
id = "center",
},
border_width = dpi(2),
border_color = Theme_config.network_manager.border_color,
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(4))
end,
bg = Theme_config.network_manager.refresh_bg,
widget = wibox.container.background,
id = "airplane"
},
layout = wibox.layout.align.horizontal
},
widget = wibox.container.margin,
top = dpi(10),
id = "action_buttons"
},
id = "layout1",
layout = wibox.layout.fixed.vertical
},
margins = dpi(10),
id = "margin",
margins = dpi(15),
widget = wibox.container.margin
},
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(8))
end,
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
},
width = dpi(400),
strategy = "exact",
widget = wibox.container.constraint
}
local network_controller_container = awful.popup {
widget = wibox.container.background,
bg = Theme_config.network_controller.bg,
border_color = Theme_config.network_controller.border_color,
border_width = Theme_config.network_controller.border_width,
screen = s,
local refresh_button = network_widget:get_children_by_id("refresh")[1]
refresh_button:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
ret:scan_access_points()
end
)
)
)
Hover_signal(refresh_button)
local airplane_button = network_widget:get_children_by_id("airplane")[1]
airplane_button:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
if ret:toggle_wireless() then
airplane_button.center.icon.image = gcolor.recolor_image(icondir
.. "airplane-off.svg",
Theme_config.network_manager.airplane_icon_color)
else
airplane_button.center.icon.image = gcolor.recolor_image(icondir
.. "airplane-on.svg",
Theme_config.network_manager.airplane_icon_color)
end
ret:scan_access_points()
end
)
)
)
Hover_signal(airplane_button)
local wifi_margin = network_widget:get_children_by_id("wifi_margin")[1]
local wifi_list = network_widget:get_children_by_id("wifi_list")[1]
local wifi = network_widget:get_children_by_id("wifi")[1].center
local rubato_timer = rubato.timed {
duration = 0.2,
pos = wifi_list.forced_height,
easing = rubato.linear,
subscribed = function(v)
wifi_list.forced_height = v
end
}
wifi_margin:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
if wifi_list.forced_height == 0 then
local size = (#ret.access_points * 49) + 1
size = size > 210 and 210 or size
rubato_timer.target = dpi(size)
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",
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",
Theme_config.network_manager.wifi_icon_color))
end
end
)
)
)
ret.widget = awful.popup {
widget = network_widget,
bg = Theme_config.network_manager.bg,
screen = args.screen,
stretch = false,
visible = false,
ontop = true,
@@ -122,9 +666,22 @@ return function(s)
end
}
network_controller_container:setup {
network_controller,
layout = wibox.layout.fixed.vertical
}
capi.awesome.connect_signal("NM::toggle_container", function()
ret.widget.visible = not ret.widget.visible
ret:scan_access_points()
end)
capi.awesome.connect_signal("NM::toggle_wifi", function()
ret:toggle_wireless()
end)
ret:connect_signal("NM::AccessPointsFound", function(tab)
network_widget:get_children_by_id("wifi_ap_list")[1].children = ret.access_points
end)
end
function network.mt:__call(...)
return network.new(...)
end
return setmetatable(network, network.mt)

View File

@@ -254,7 +254,7 @@ function nl.create_notification(n)
end
)
table.insert(nl.notification_list, notification)
table.insert(nl.notification_list, 1, notification)
end
naughty.connect_signal(

View File

@@ -0,0 +1,249 @@
--------------------------------
-- 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

View File

@@ -0,0 +1,447 @@
-----------------------------------
-- This is the titlebar module --
-----------------------------------
-- 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,
client = client
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/titlebar/"
awful.titlebar.enable_tooltip = true
awful.titlebar.fallback_name = 'Client'
-- Normal AND Focus(active/inactive) have to be set or errors will appear in stdout
Theme.titlebar_close_button_normal = icondir .. "close.svg"
Theme.titlebar_close_button_focus = icondir .. "close.svg"
Theme.titlebar_minimize_button_normal = icondir .. "minimize.svg"
Theme.titlebar_minimize_button_focus = icondir .. "minimize.svg"
Theme.titlebar_maximized_button_normal = icondir .. "maximize.svg"
Theme.titlebar_maximized_button_active = icondir .. "maximize.svg"
Theme.titlebar_maximized_button_inactive = icondir .. "maximize.svg"
local create_buttons = function(c)
local buttons = gears.table.join(
awful.button(
{},
1,
function()
c:activate { context = 'titlebar', action = 'mouse_move' }
end
),
awful.button(
{},
3,
function()
c:activate { context = 'titlebar', action = 'mouse_resize' }
end
)
)
return buttons
end
local create_titlebar = function(c, size, position)
local close_button = awful.titlebar.widget.closebutton(c)
local minimize_button = awful.titlebar.widget.minimizebutton(c)
local maximize_button = awful.titlebar.widget.maximizedbutton(c)
local tb
if position == "left" then
local titlebar = awful.titlebar(c, {
position = "left",
bg = Theme_config.titlebar.bg,
size = size
})
tb = wibox.widget {
{
{
{
close_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.close_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "closebutton"
},
{
maximize_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.maximize_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "maximizebutton"
},
{
minimize_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.minimize_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "minimizebutton"
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
id = "spacing"
},
margins = dpi(5),
widget = wibox.container.margin,
id = "margin"
},
{
buttons = create_buttons(c),
layout = wibox.layout.flex.vertical
},
{
awful.titlebar.widget.iconwidget(c),
margins = dpi(5),
widget = wibox.container.margin
},
layout = wibox.layout.align.vertical,
id = "main"
}
titlebar:setup { tb, layout = wibox.layout.fixed.horizontal }
elseif position == "top" then
local titlebar = awful.titlebar(c, {
position = "top",
bg = Theme_config.titlebar.bg,
size = size
})
tb = wibox.widget {
{
awful.titlebar.widget.iconwidget(c),
margins = dpi(5),
widget = wibox.container.margin
},
{
{
awful.titlebar.widget.titlewidget(c),
valign = "center",
halign = "center",
layout = wibox.container.place,
},
buttons = create_buttons(c),
fill_space = true,
layout = wibox.layout.stack
},
{
{
{
minimize_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.minimize_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "minimizebutton"
},
{
maximize_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.maximize_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "maximizebutton"
},
{
close_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.close_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "closebutton"
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
id = "spacing"
},
margins = dpi(5),
widget = wibox.container.margin,
id = "margin"
},
layout = wibox.layout.align.horizontal,
id = "main"
}
titlebar:setup { tb, layout = wibox.layout.fixed.vertical }
end
if not tb then return end
close_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.close_button.hover_border
local cb = tb:get_children_by_id("closebutton")[1]
cb.border_color = Theme_config.titlebar.close_button.hover_border
cb.bg = Theme_config.titlebar.close_button.hover_bg
end
)
close_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local cb = tb:get_children_by_id("closebutton")[1]
cb.border_color = Theme_config.titlebar.close_button.border_color
cb.bg = Theme_config.titlebar.close_button.bg
end
)
minimize_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.minimize_button.hover_border
local mb = tb:get_children_by_id("minimizebutton")[1]
mb.border_color = Theme_config.titlebar.minimize_button.hover_border
mb.bg = Theme_config.titlebar.minimize_button.hover_bg
end
)
minimize_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local mb = tb:get_children_by_id("minimizebutton")[1]
mb.border_color = Theme_config.titlebar.minimize_button.border_color
mb.bg = Theme_config.titlebar.minimize_button.bg
end
)
maximize_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.maximize_button.hover_border
local mb = tb:get_children_by_id("maximizebutton")[1]
mb.border_color = Theme_config.titlebar.maximize_button.hover_border
mb.bg = Theme_config.titlebar.maximize_button.hover_bg
end
)
maximize_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local mb = tb:get_children_by_id("maximizebutton")[1]
mb.border_color = Theme_config.titlebar.maximize_button.border_color
mb.bg = Theme_config.titlebar.maximize_button.bg
end
)
end
local create_titlebar_dialog_modal = function(c, size, position)
local close_button = awful.titlebar.widget.closebutton(c)
local minimize_button = awful.titlebar.widget.minimizebutton(c)
local maximize_button = awful.titlebar.widget.maximizedbutton(c)
local tb
if position == "left" then
local titlebar = awful.titlebar(c, {
position = "left",
bg = Theme_config.titlebar.bg,
size = size
})
tb = wibox.widget {
{
{
close_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.close_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "closebutton"
},
margins = dpi(5),
widget = wibox.container.margin,
id = "margin"
},
{
buttons = create_buttons(c),
layout = wibox.layout.flex.vertical
},
{
awful.titlebar.widget.iconwidget(c),
margins = dpi(5),
widget = wibox.container.margin
},
layout = wibox.layout.align.vertical,
id = "main"
}
titlebar:setup { tb, layout = wibox.layout.fixed.horizontal }
elseif position == "top" then
local titlebar = awful.titlebar(c, {
position = "top",
bg = Theme_config.titlebar.bg,
size = size
})
tb = wibox.widget {
{
awful.titlebar.widget.iconwidget(c),
margins = dpi(5),
widget = wibox.container.margin
},
{
{
awful.titlebar.widget.titlewidget(c),
valign = "center",
halign = "center",
layout = wibox.container.place,
},
buttons = create_buttons(c),
fill_space = true,
layout = wibox.layout.stack
},
{
{
close_button,
widget = wibox.container.background,
border_color = Theme_config.titlebar.close_button.border_color,
border_width = dpi(2),
shape = function(cr, height, width)
gears.shape.rounded_rect(cr, width, height, dpi(6))
end,
id = "closebutton"
},
margins = dpi(5),
widget = wibox.container.margin,
id = "margin"
},
layout = wibox.layout.align.horizontal,
id = "main"
}
titlebar:setup { tb, layout = wibox.layout.fixed.vertical }
end
if not tb then return end
close_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.close_button.hover_border
local cb = tb:get_children_by_id("closebutton")[1]
cb.border_color = Theme_config.titlebar.close_button.hover_border
cb.bg = Theme_config.titlebar.close_button.hover_bg
end
)
close_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local cb = tb:get_children_by_id("closebutton")[1]
cb.border_color = Theme_config.titlebar.close_button.border_color
cb.bg = Theme_config.titlebar.close_button.bg
end
)
minimize_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.minimize_button.hover_border
local mb = tb:get_children_by_id("minimizebutton")[1]
mb.border_color = Theme_config.titlebar.minimize_button.hover_border
mb.bg = Theme_config.titlebar.minimize_button.hover_bg
end
)
minimize_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local mb = tb:get_children_by_id("minimizebutton")[1]
mb.border_color = Theme_config.titlebar.minimize_button.border_color
mb.bg = Theme_config.titlebar.minimize_button.bg
end
)
maximize_button:connect_signal(
"mouse::enter",
function()
c.border_color = Theme_config.titlebar.maximize_button.hover_border
local mb = tb:get_children_by_id("maximizebutton")[1]
mb.border_color = Theme_config.titlebar.maximize_button.hover_border
mb.bg = Theme_config.titlebar.maximize_button.hover_bg
end
)
maximize_button:connect_signal(
"mouse::leave",
function()
c.border_color = Theme_config.window.border_normal
local mb = tb:get_children_by_id("maximizebutton")[1]
mb.border_color = Theme_config.titlebar.maximize_button.border_color
mb.bg = Theme_config.titlebar.maximize_button.bg
end
)
end
capi.client.connect_signal(
"request::titlebars",
function(c)
if c.type == "dialog" then
create_titlebar_dialog_modal(c, dpi(35), User_config.titlebar_position)
elseif c.type == "modal" then
create_titlebar_dialog_modal(c, dpi(35), User_config.titlebar_position)
else
create_titlebar(c, dpi(35), User_config.titlebar_position)
end
if not c.floating or c.maximized or c.fullscreen then
if User_config.titlebar_position == "left" then
awful.titlebar.hide(c, "left")
elseif User_config.titlebar_position == "top" then
awful.titlebar.hide(c, "top")
end
end
end
)
capi.client.connect_signal(
"property::floating",
function(c)
if c.floating and not (c.maximized or c.fullscreen) then
if User_config.titlebar_position == "left" then
awful.titlebar.show(c, "left")
elseif User_config.titlebar_position == "top" then
awful.titlebar.show(c, "top")
end
else
if User_config.titlebar_position == "left" then
awful.titlebar.hide(c, "left")
elseif User_config.titlebar_position == "top" then
awful.titlebar.hide(c, "top")
end
end
end
)

View File

@@ -19,56 +19,56 @@ Theme_config = {}
-- #region Widget Settings
Theme_config.audio = {
bg = color["Yellow200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.battery = {
bg = color["Purple200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.bluetooth = {
bg = color["Blue200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.clock = {
bg = color["Orange200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.cpu_freq = {
bg = color["Blue200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.cpu_temp = {
fg = color["Grey900"],
bg_low = color["Green200"],
bg_mid = color["Orange200"],
bg_high = color["Red200"],
bg_high = color["Red200"]
}
Theme_config.cpu_usage = {
bg = color["Blue200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.date = {
bg = color["Teal200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.gpu_usage = {
bg = color["Green200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.gpu_temp = {
fg = color["Grey900"],
bg_low = color["Green200"],
bg_mid = color["Orange200"],
bg_high = color["Red200"],
bg_high = color["Red200"]
}
Theme_config.kblayout = {
@@ -81,13 +81,13 @@ Theme_config.kblayout = {
fg_long = color["Red200"],
fg_short = color["Purple200"],
bg_selected = color["DeepPurple200"],
fg_selected = color["Grey900"],
fg_selected = color["Grey900"]
}
}
Theme_config.layout_list = {
bg = color["LightBlue200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.network = {
@@ -98,16 +98,16 @@ Theme_config.network = {
Theme_config.power_button = {
bg = color["Red200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.ram_info = {
bg = color["Red200"],
fg = color["Grey900"],
fg = color["Grey900"]
}
Theme_config.systray = {
bg = "#3A475C",
bg = "#3A475C"
}
Theme_config.taglist = {
@@ -118,7 +118,7 @@ Theme_config.taglist = {
bg_focus = color["Grey100"],
bg_focus_pressed = "#dddddd",
bg_focus_hover = color["Grey100"],
fg_focus = color["Grey900"],
fg_focus = color["Grey900"]
}
Theme_config.tasklist = {
@@ -129,7 +129,7 @@ Theme_config.tasklist = {
bg_focus = color["Grey100"],
bg_focus_pressed = "#dddddd",
bg_focus_hover = color["Grey100"],
fg_focus = color["Grey900"],
fg_focus = color["Grey900"]
}
-- #endregion
@@ -164,14 +164,15 @@ Theme_config.calendar = {
border_width = dpi(2),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(8))
end,
end
},
task = {
bg = color["Purple200"],
bg_past = color["Grey600"],
fg = color["Grey900"],
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end,
end
},
weekdays = {
bg = color["Grey900"],
@@ -182,14 +183,76 @@ Theme_config.calendar = {
fg = color["Grey900"],
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end,
end
},
add_task = {
bg = color["LightBlue200"],
fg = color["Grey900"],
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end,
end
},
task_info = {
icon_color = color["Blue200"],
bg = color["Grey900"],
fg = color["White"],
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end
}
}
Theme_config.desktop = {
context_menu = {
icon_color = color["Purple200"],
entry_bg = color["Grey900"],
entry_fg = color["Pink200"],
bg = color["Grey900"],
fg = color["Pink200"],
border_color = color["Grey800"],
border_width = dpi(2),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end
}
}
Theme_config.network_manager = {
bg = color["Grey900"],
border_color = color["Grey800"],
border_width = dpi(2),
wifi_icon_color = color["DeepOrange200"],
wifi_bg = color["Grey800"],
wifi_fg = color["Orange200"],
ap_border_color = color["Grey800"],
ap_border_width = dpi(2),
airplane_icon_color = color["Orange200"],
refresh_icon_color = color["Orange200"],
power_icon_color = color["Orange200"],
refresh_bg = color["Grey900"],
power_bg = color["Grey900"],
access_point = {
icon_color = color["Red200"],
button_color = color["Grey900"],
icon_color2 = color["Grey900"],
bg = color["Grey900"],
fg = color["Red200"],
border_color = color["Grey800"],
border_width = dpi(2),
device_shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end
},
form = {
bg = color["Grey900"],
fg = color["Grey100"],
close_bg = color["Red200"],
icon_fg = color["Grey900"],
border_color = color["Grey800"],
border_width = dpi(2),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(8))
end
}
}
@@ -223,7 +286,7 @@ Theme_config.notification = {
fg_close = color["Teal200"],
bg_close = color["Grey900"],
title_border_color = color["Grey800"],
title_border_width = dpi(2),
title_border_width = dpi(2)
}
Theme_config.notification_center = {
@@ -235,7 +298,7 @@ Theme_config.notification_center = {
-- Clear all button
clear_all_button = {
bg = color["Blue200"],
fg = color["Grey900"],
fg = color["Grey900"]
},
-- DnD button
@@ -245,7 +308,7 @@ Theme_config.notification_center = {
disabled = color["Grey700"],
enabled = color["Purple200"],
border_disabled = color["Grey800"],
border_enabled = color["Purple200"],
border_enabled = color["Purple200"]
},
-- Notification_list
@@ -305,7 +368,7 @@ Theme_config.notification_center = {
},
-- Spacing line widget
spacing_line = {
color = color["Grey800"],
color = color["Grey800"]
},
-- Status bar widgets
@@ -324,13 +387,11 @@ Theme_config.notification_center = {
volume_color = color["Yellow200"],
microphone_color = color["Blue200"],
backlight_color = color["Pink200"],
battery_color = color["Purple200"],
battery_color = color["Purple200"]
},
-- Time Date widget
time_date = {
},
time_date = {},
-- Weather widget
weather = {
@@ -343,7 +404,7 @@ Theme_config.notification_center = {
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end
},
}
}
Theme_config.bluetooth_controller = {
@@ -367,6 +428,10 @@ Theme_config.bluetooth_controller = {
container_border_color = color["Grey800"],
container_border_width = dpi(4),
container_bg = color["Grey900"],
refresh_icon_color = color["Grey900"],
refresh_bg = color["LightBlue200"],
power_icon_color = color["Grey900"],
power_bg = color["Blue200"]
}
Theme_config.brightness_osd = {
@@ -376,11 +441,11 @@ Theme_config.brightness_osd = {
border_width = dpi(4),
bar_bg_active = color["Blue200"],
bar_bg = color["Grey800"],
icon_color = color["Blue200"],
icon_color = color["Blue200"]
}
Theme_config.center_bar = {
bg = color["Grey900"],
bg = color["Grey900"]
}
Theme_config.dock = {
@@ -389,16 +454,17 @@ Theme_config.dock = {
element_focused_hover_bg = color["Grey800"],
element_focused_hover_fg = color["Grey100"],
bg = color["Grey900"],
cm_icon = color["LightBlue200"],
indicator_bg = color["Grey600"],
indicator_focused_bg = color["YellowA200"],
indicator_urgent_bg = color["RedA200"],
indicator_maximized_bg = color["GreenA200"],
indicator_bg_mindicator_minimized_bginimized = color["BlueA200"],
indicator_fullscreen_bg = color["PurpleA200"],
indicator_fullscreen_bg = color["PurpleA200"]
}
Theme_config.left_bar = {
bg = color["Grey900"],
bg = color["Grey900"]
}
Theme_config.powermenu = {
@@ -408,11 +474,11 @@ Theme_config.powermenu = {
reboot_button_bg = color["Red200"],
suspend_button_bg = color["Yellow200"],
lock_button_bg = color["Green200"],
logout_button_bg = color["Orange200"],
logout_button_bg = color["Orange200"]
}
Theme_config.right_bar = {
bg = color["Grey900"],
bg = color["Grey900"]
}
Theme_config.titlebar = {
@@ -423,7 +489,7 @@ Theme_config.titlebar = {
fg = color["Grey100"],
hover_border = color["Red800"],
hover_bg = color["Red800"] .. "bb",
hover_fg = color["Red800"],
hover_fg = color["Red800"]
},
minimize_button = {
border_color = "#00000000",
@@ -431,7 +497,7 @@ Theme_config.titlebar = {
bg = "#00000000",
hover_border = color["Orange800"],
hover_fg = color["Orange800"],
hover_bg = color["Orange800"] .. "bb",
hover_bg = color["Orange800"] .. "bb"
},
maximize_button = {
border_color = "#00000000",
@@ -439,8 +505,8 @@ Theme_config.titlebar = {
bg = "#00000000",
hover_border = color["Green800"],
hover_fg = color["Green800"],
hover_bg = color["Green800"] .. "bb",
},
hover_bg = color["Green800"] .. "bb"
}
}
Theme_config.volume_controller = {
@@ -479,7 +545,7 @@ Theme_config.volume_controller = {
gears.shape.rounded_rect(cr, width, height, dpi(4))
end,
volume_fg = color["Purple200"],
microphone_fg = color["Blue200"],
microphone_fg = color["Blue200"]
}
Theme_config.volume_osd = {
@@ -489,7 +555,7 @@ Theme_config.volume_osd = {
border_width = dpi(4),
bar_bg_active = color["Purple200"],
bar_bg = color["Grey800"],
icon_color = color["Purple200"],
icon_color = color["Purple200"]
}
Theme_config.window_switcher = {
@@ -514,6 +580,7 @@ Theme_config.application_launcher = {
bg = "#313131",
fg = color["Grey100"],
hover_bg = color["Grey700"],
cm_icon_color = color["Pink200"]
},
searchbar = {
bg = color["Grey900"],
@@ -531,7 +598,7 @@ Theme_config.application_launcher = {
border_active = color["LightBlue200"],
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end,
end
}
}
@@ -601,7 +668,7 @@ Theme_config.hotkeys = {
font = User_config.font.bold,
group_margin = dpi(20),
label_bg = color["Cyan200"],
label_fg = color["Grey900"],
label_fg = color["Grey900"]
}
-- #endregion

View File

@@ -45,7 +45,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 = "BATTERY",
--[[
If your battery is not found you can specify its path here.
@@ -98,6 +98,8 @@ User_config = {
specify = "JetBrainsMono Nerd Font"
},
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]
@@ -147,6 +149,8 @@ User_config = {
]] --
modkey = "Mod4",
music_player = "flatpak run com.spotify.Client",
--[[
This is the naming sheme used for the powermenu and maybe some other places in the future.
Example:
@@ -168,6 +172,8 @@ User_config = {
ethernet = "eno1"
},
screen_settings = "arandr",
--[[
This is the program that will be executed when hitting the print key.
]] --
@@ -198,7 +204,6 @@ User_config = {
"backlight"
},
--[[
If true the taskbar will shot the client name instead of the class name.
Default: false
@@ -210,6 +215,8 @@ User_config = {
]] --
terminal = "alacritty",
text_editor = "code",
--[[
Add every client that should get no titlebar.
Use xprop WM_ClASS to get the class of the window.
@@ -222,6 +229,7 @@ User_config = {
}
]] --
titlebar_exception = {
"protonvpn"
},
--[[
@@ -235,7 +243,7 @@ User_config = {
This is the path to your wallpaper.
home is $HOME, you can also use an absolute path.
]] --
wallpaper = home .. "/.config/awesome/src/assets/fuji.jpg",
wallpaper = home .. "/Bilder/Hintergründe/784194.jpg",
--[[
This is the weather widget.
@@ -246,11 +254,13 @@ User_config = {
unit = "metric" or "imperial"
]]
weather_secrets = {
key = "",
city_id = "",
key = "e71b00168ca7219563dde4514a425b14",
city_id = "2864118",
unit = "metric"
},
web_browser = "brave-browser",
--[[
You can configure your bar's here, if you leave it empty the bar will not be shown.
If you have multiple monitors you can add [N] where N is to the table below to get a per screen configuration.
@@ -276,7 +286,7 @@ User_config = {
"Tasklist" <-- Shows all programs per tag
!The order goes from left to right!
]]
widgets = {
crylia_bar = {
[1] = {
left_bar = {
"Tiling Layout",
@@ -296,8 +306,11 @@ User_config = {
"Clock",
"Power Button"
}
}
},
[2] = {
crylia_wibox = {
[1] = {
left_bar = {
"Tiling Layout",
"Taglist"
@@ -306,13 +319,14 @@ User_config = {
"Tasklist"
},
right_bar = {
"Ram Usage",
"Systray",
"Battery",
"Bluetooth",
"Audio",
"Keyboard Layout",
"Network",
"Keyboard Layout",
"Date",
"Clock",
"Power Button"
}
}
}

View File

@@ -98,6 +98,13 @@ return function()
end
)
capi.awesome.connect_signal(
"bluetooth::stop",
function()
Adapter:StopDiscovery()
end
)
AdapterProperties:connect_signal(
function(data)
if data.Powered ~= nil then

View File

@@ -1,27 +1,42 @@
local awful = require("awful")
local pulse = require("pulseaudio_dbus")
local capi = {
awesome = awesome,
}
--[[ local lgi = require("lgi")
local lgi = require("lgi")
local pulseaudio = require("lua_libpulse_glib")
local ppretty = require("pl.ppretty")
local pa = pulseaudio.new()
local ctx = pa:context("My Test App")
local ctx = pa:context("awesome")
ctx:connect(nil, function(state)
print(ctx)
--[[ ctx:connect(nil, function(state)
if state == 4 then
print("Connection is ready")
ctx:get_sinks(function(sinks)
ppretty.dump(sinks)
print(sinks[1])
end)
end
end) ]]
--local address = pulse.get_address()
--[[ local connection = pulse.get_connection(address)
local core = pulse.get_core(connection)
local sink = pulse.get_device(connection, core:get_sinks()[1])
sink:set_muted(false)
--assert(not sink:is_muted())
sink:set_volume_percent({ 75 }) ]]
awful.spawn.with_line_callback(
[[bash -c "LC_ALL=C pactl subscribe"]],
{

View File

@@ -9,6 +9,7 @@ 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
)

View File

@@ -10,6 +10,7 @@ watch(
3,
function(_, stdout)
stdout = stdout:match("%d+")
if not stdout then return end
capi.awesome.emit_signal("update::gpu_usage", stdout)
end
)

View File

@@ -3,6 +3,8 @@ local gobject = require("gears.object")
local gtable = require("gears.table")
local naughty = require("naughty")
local color = require("src.theme.colors")
local json = require("src.lib.json-lua.json-lua")
local ical = { mt = {} }
@@ -108,13 +110,11 @@ end
function ical:add_calendar(file)
local handler = io.open(file, "r")
if not handler then return end
-- Check if the line is a BEGIN:VCALENDAR
local v, k = handler:read("l"):match("([A-Z]+):([A-Z]+)")
local vcal = {}
if v:match("BEGIN") and k:match("VCALENDAR") then
vcal = self._private.parser.VCALENDAR(handler)
vcal = self._private.parser:VCALENDAR(handler)
table.insert(self.VCALENDAR, vcal)
self._private.add_to_cache(file, vcal)
end
@@ -122,11 +122,11 @@ end
function ical.new(args)
args = args or {}
local ret = gobject {}
local ret = gobject { enable_properties = true, enable_auto_signals = true }
gtable.crush(ret, ical, true)
local path = gfilesystem.get_configuration_dir() .. "src/config/calendar.json"
local handler = io.open(path, "r")
if not handler then return end
if not handler then return ret end
local json_data = json:decode(handler:read("a"))
handler:close()
if not (type(json_data) == "table") then return end
@@ -135,7 +135,32 @@ function ical.new(args)
ret._private.cache[v.file] = v.VCALENDAR
table.insert(ret.VCALENDAR, v.VCALENDAR)
end
return ical
local function get_random_color()
local colors = {
color["Blue200"],
color["Red200"],
color["Green200"],
color["Yellow200"],
color["Purple200"],
color["Orange200"],
color["Pink200"],
color["Cyan200"],
color["Lime200"],
color["Teal200"],
color["Indigo200"],
color["LightBlue200"],
color["BlueGrey200"],
color["DeepOrange200"],
color["DeepPurple200"],
}
return colors[math.random(1, 15)]
end
ret.color = get_random_color()
return ret
end
function ical._private.parser:VEVENT(handler)
@@ -150,32 +175,34 @@ function ical._private.parser:VEVENT(handler)
local v, k = line:match("(.*):(.*)")
if v:match("CREATED") then
VEVENT.CREATED = self._private.parser.to_datetime(k)
VEVENT.CREATED = self.to_datetime(k)
elseif v:match("LAST-MODIFIED") then
VEVENT.LAST_MODIFIED = self._private.parser.to_datetime(k)
VEVENT.LAST_MODIFIED = self.to_datetime(k)
elseif v:match("DTSTAMP") then
VEVENT.DTSTAMP = self._private.parser.to_datetime(k)
VEVENT.DTSTAMP = self.to_datetime(k)
elseif v:match("UID") then
VEVENT.UID = k
elseif v:match("SUMMARY") then
VEVENT.SUMMARY = k
elseif v:match("STATUS") then
VEVENT.STATUS = k
elseif v:match("RRULE") then
VEVENT.RRULE = {
FREQ = k:match("FREQ=([A-Z]+)"),
UNTIL = self._private.parser.to_datetime(k:match("UNTIL=([TZ0-9]+)")),
UNTIL = self.to_datetime(k:match("UNTIL=([TZ0-9]+)")),
WKST = k:match("WKST=([A-Z]+)"),
COUNT = k:match("COUNT=([0-9]+)"),
INTERVAL = k:match("INTERVAL=([0-9]+)")
}
elseif v:match("DTSTART") then
VEVENT.DTSTART = {
DTSTART = self._private.parser.to_datetime(k),
DTSTART = self.to_datetime(k),
TZID = v:match("TZID=([a-zA-Z-\\/]+)"),
VALUE = v:match("VALUE=([A-Z]+)")
}
elseif v:match("DTEND") then
VEVENT.DTEND = {
DTEND = self._private.parser.to_datetime(k),
DTEND = self.to_datetime(k),
TZID = v:match("TZID=([a-zA-Z-\\/]+)"),
VALUE = v:match("VALUE=([A-Z]+)")
}
@@ -183,6 +210,8 @@ function ical._private.parser:VEVENT(handler)
VEVENT.TRANSP = k
elseif v:match("LOCATION") then
VEVENT.LOCATION = k
elseif v:match("SEQUENCE") then
VEVENT.SEQUENCE = k
elseif v:match("DESCRIPTION") then
VEVENT.DESCRIPTION = k
elseif v:match("URL") then
@@ -192,7 +221,7 @@ function ical._private.parser:VEVENT(handler)
}
elseif v:match("BEGIN") then
if k:match("VALARM") then
VEVENT.VALARM = self._private.parser:VALARM(handler)
VEVENT.VALARM = self:VALARM(handler)
end
elseif v:match("UID") then
VEVENT.UID = k
@@ -258,9 +287,9 @@ function ical._private.parser:VCALENDAR(handler)
VCALENDAR.VERSION = k
elseif v:match("BEGIN") then
if k:match("VTIMEZONE") then
VCALENDAR.VTIMEZONE = self._private.parser:VTIMEZONE(handler)
VCALENDAR.VTIMEZONE = self:VTIMEZONE(handler)
elseif k:match("VEVENT") then
table.insert(VCALENDAR.VEVENT, self._private.parser:VEVENT(handler))
table.insert(VCALENDAR.VEVENT, self:VEVENT(handler))
end
end
end
@@ -286,9 +315,9 @@ function ical._private.parser:VTIMEZONE(handler)
end
if v:match("BEGIN") then
if k:match("DAYLIGHT") then
VTIMEZONE.DAYLIGHT = self._private.parser:DAYLIGHT(handler)
VTIMEZONE.DAYLIGHT = self:DAYLIGHT(handler)
elseif k:match("STANDARD") then
VTIMEZONE.STANDARD = self._private.parser:STANDARD(handler)
VTIMEZONE.STANDARD = self:STANDARD(handler)
end
end
end
@@ -308,13 +337,13 @@ function ical._private.parser:DAYLIGHT(handler)
local v, k = line:match("(.*):(.*)")
if v:match("TZOFFSETFROM") then
DAYLIGHT.TZOFFSETFROM = self._private.parser.offset(k)
DAYLIGHT.TZOFFSETFROM = self.offset(k)
elseif v:match("TZOFFSETTO") then
DAYLIGHT.TZOFFSETTO = self._private.parser.offset(k)
DAYLIGHT.TZOFFSETTO = self.offset(k)
elseif v:match("TZNAME") then
DAYLIGHT.TZNAME = k
elseif v:match("DTSTART") then
DAYLIGHT.DTSTART = self._private.parser.to_datetime(k)
DAYLIGHT.DTSTART = self.to_datetime(k)
elseif v:match("RRULE") then
DAYLIGHT.RRULE = {
FREQ = k:match("FREQ=([A-Z]+)"),
@@ -344,13 +373,13 @@ function ical._private.parser:STANDARD(handler)
-- Break down each line into the property:value
local v, k = line:match("(.*):(.*)")
if v:match("TZOFFSETFROM") then
STANDARD.TZOFFSETFROM = self._private.parser.offset(k)
STANDARD.TZOFFSETFROM = self.offset(k)
elseif v:match("TZOFFSETTO") then
STANDARD.TZOFFSETTO = self._private.parser.offset(k)
STANDARD.TZOFFSETTO = self.offset(k)
elseif v:match("TZNAME") then
STANDARD.TZNAME = k
elseif v:match("DTSTART") then
STANDARD.DTSTART = self._private.parser.to_datetime(k)
STANDARD.DTSTART = self.to_datetime(k)
elseif v:match("RRULE") then
STANDARD.RRULE = {
FREQ = k:match("FREQ=([A-Z]+)"),

View File

@@ -7,17 +7,13 @@ local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
require("src.core.signals")
local capi = {
awesome = awesome,
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/date/"
-- Returns the date widget
return function()
return function(s)
local cal = require("src.modules.calendar.init") { screen = s }
local date_widget = wibox.widget {
{
@@ -63,13 +59,24 @@ return function()
widget = wibox.container.background
}
local calendar_popup = awful.popup {
widget = cal:get_widget(),
screen = s,
ontop = true,
bg = "#00000000",
visible = false,
}
-- Signals
Hover_signal(date_widget)
date_widget:buttons {
gears.table.join(
awful.button({}, 1, function()
capi.awesome.emit_signal("calendar::toggle", date_widget)
local geo = mouse.current_wibox:geometry()
calendar_popup.x = geo.x
calendar_popup.y = geo.y + Global_config.top_struts
calendar_popup.visible = not calendar_popup.visible
end)
)
}

View File

@@ -18,6 +18,7 @@ local capi = {
local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/"
return function(widget)
local gpu_usage_widget = wibox.widget {
{
{

View File

@@ -334,11 +334,25 @@ return function()
-- Signals
Hover_signal(network_widget)
network_widget:connect_signal(
"button::press",
network_widget:buttons(
gears.table.join(
awful.button(
{},
1,
nil,
function()
awful.spawn("gnome-control-center wlan")
capi.awesome.emit_signal("NM::toggle_container")
end
),
awful.button(
{},
3,
nil,
function()
capi.awesome.emit_signal("NM::toggle_wifi")
end
)
)
)
return network_widget

View File

@@ -110,16 +110,6 @@ local list_update = function(widget, buttons, _, _, objects)
strategy = "exact",
layout = wibox.container.constraint,
})
--[[ awful.spawn.easy_async_with_shell(
"ps -o cmd " .. client.pid .. " | tail -n 1",
function(stdout)
local cmd = stdout:gsub("\n", "")
local app_info = Gio.AppInfo.create_from_commandline(cmd, client.name, {})
local exec = Gio.AppInfo.get_executable(app_info)
icon:get_children_by_id("icon")[1].image = Get_icon(exec)
end
) ]]
end
Hover_signal(tag_widget)