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 mousegrabber = mousegrabber
root = root root = root
screen = screen screen = screen
selection = selection
tag = tag 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.user_config")
require("src.theme.theme_config") require("src.theme.theme_config")
@@ -30,5 +34,5 @@ require("src.bindings.global_buttons")
require("src.bindings.bind_to_tags") require("src.bindings.bind_to_tags")
require("src.modules.init") require("src.modules.init")
require("src.tools.helpers.init") require("src.tools.helpers.init")
require("src.tools.auto_starter")(User_config.autostart) --require("src.tools.auto_starter")(User_config.autostart)
require("src.tools.dbus.bluetooth_dbus")() --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 widget_template = w_template
} }
awful.spawn.easy_async_with_shell(
"paplay /usr/share/sounds/freedesktop/stereo/message.oga"
)
box.buttons = {} box.buttons = {}
n.buttons = {} n.buttons = {}
end end

View File

@@ -47,6 +47,13 @@ capi.client.connect_signal(
if c.transient_for then if c.transient_for then
c.floating = true c.floating = true
end end
if c.fullscreen then
gears.timer.delayed_call(function()
if c.valid then
c:geometry(c.screen.geometry)
end
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,21 +9,242 @@ local gfilesystem = require("gears").filesystem
local dpi = require("beautiful").xresources.apply_dpi local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears") local gears = require("gears")
local wibox = require("wibox") 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 = { local capi = {
awesome = awesome, awesome = awesome,
mouse = mouse, 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/" local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
return function(s) local application_grid = { mt = {} }
local application_grid = wibox.widget { 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
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
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()
for _, app in ipairs(apps) do
if app.should_show(app) then -- check no display
local desktop_app_info = Gio.DesktopAppInfo.new(app_info.get_id(app))
local app_widget = wibox.widget {
{
{
{
{
{ -- Icon
valign = "center",
halign = "center",
image = Get_gicon_path(app_info.get_icon(app)),
resize = true,
widget = wibox.widget.imagebox
},
height = dpi(64),
width = dpi(64),
strategy = "exact",
widget = wibox.container.constraint
},
{
{ -- Name
text = app_info.get_name(app),
align = "center",
valign = "center",
widget = wibox.widget.textbox
},
strategy = "exact",
width = dpi(170),
-- Prevents widget from overflowing
height = dpi(40),
widget = wibox.container.constraint
},
layout = wibox.layout.fixed.vertical
},
halign = "center",
valign = "center",
widget = wibox.container.place
},
margins = dpi(10),
widget = wibox.container.margin
},
name = app_info.get_name(app),
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, "Comment") or "",
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, "Keywords") or "",
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or "",
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, "Terminal") == "true",
actions = Gio.DesktopAppInfo.list_actions(desktop_app_info),
border_color = Theme_config.application_launcher.application.border_color,
border_width = Theme_config.application_launcher.application.border_width,
bg = Theme_config.application_launcher.application.bg,
fg = Theme_config.application_launcher.application.fg,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(8))
end,
widget = wibox.container.background
}
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.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)
end
},
{
name = "Pin to dock",
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(dir .. "/dock.json", "r")
if not handler then
return
end
local dock_table = json:decode(handler:read("a")) or {}
handler:close()
---@diagnostic disable-next-line: param-type-mismatch
table.insert(dock_table, {
name = app_widget.name or "",
icon = Get_gicon_path(app_info.get_icon(app)) or "",
comment = app_widget.comment or "",
exec = app_widget.exec or "",
keywords = app_widget.keywords or "",
categories = app_widget.categories or "",
terminal = app_widget.terminal or "",
actions = app_widget.actions or "",
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
})
local dock_encoded = json:encode(dock_table)
handler = io.open("/home/crylia/.config/awesome/src/config/dock.json", "w")
if not handler then
return
end
handler:write(dock_encoded)
handler:close()
capi.awesome.emit_signal("dock::changed")
end
},
{
name = "Add to desktop",
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")
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(
gears.table.join(
awful.button({
modifiers = {},
button = 1,
on_release = function()
Gio.AppInfo.launch_uris_async(app)
--!Change!
capi.awesome.emit_signal("application_launcher::show")
end
}),
awful.button({
modifiers = {},
button = 3,
on_release = function()
context_menu:toggle()
end
})
)
)
Hover_signal(app_widget)
table.insert(list, app_widget)
end
end
self.app_list = list
end
function application_grid:set_applications(search_filter)
local filter = search_filter or self.filter or ""
-- Reset to first position
self._private.curser = {
x = 1,
y = 1
}
local grid = wibox.widget {
homogenous = true, homogenous = true,
expand = false, expand = false,
spacing = dpi(10), spacing = dpi(10),
@@ -34,279 +255,104 @@ return function(s)
orientation = "vertical", orientation = "vertical",
layout = wibox.layout.grid layout = wibox.layout.grid
} }
-- Selected application position, default is first at 1,1
-- The typo *might* be intentional for _, application in ipairs(self.app_list) do
local curser = { -- Match the filter
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 = 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 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")
self:set_widget(grid)
end
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
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
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
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
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
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, x = 1,
y = 1 y = 1
} }
local filter = "" w:get_applications_from_file()
---Executes only once to create a widget from each desktop file w:set_applications()
---@return table widgets Unsorted widget table
local function get_applications_from_file()
local list = {}
local app_info = Gio.AppInfo
local apps = app_info.get_all()
for _, app in ipairs(apps) do
if app.should_show(app) then -- check no display
local desktop_app_info = Gio.DesktopAppInfo.new(app_info.get_id(app))
local app_widget = wibox.widget {
{
{
{
{
{ -- Icon
valign = "center",
halign = "center",
image = Get_gicon_path(app_info.get_icon(app)),
resize = true,
widget = wibox.widget.imagebox
},
height = dpi(64),
width = dpi(64),
strategy = "exact",
widget = wibox.container.constraint
},
{
{ -- Name
text = app_info.get_name(app),
align = "center",
valign = "center",
widget = wibox.widget.textbox
},
strategy = "exact",
width = dpi(170),
-- Prevents widget from overflowing
height = dpi(40),
widget = wibox.container.constraint
},
layout = wibox.layout.fixed.vertical
},
halign = "center",
valign = "center",
widget = wibox.container.place
},
margins = dpi(10),
widget = wibox.container.margin
},
name = app_info.get_name(app),
comment = Gio.DesktopAppInfo.get_string(desktop_app_info, "Comment") or "",
exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"),
keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, "Keywords") or "",
categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or "",
terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, "Terminal") == "true",
actions = Gio.DesktopAppInfo.list_actions(desktop_app_info),
border_color = Theme_config.application_launcher.application.border_color,
border_width = Theme_config.application_launcher.application.border_width,
bg = Theme_config.application_launcher.application.bg,
fg = Theme_config.application_launcher.application.fg,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(8))
end,
widget = wibox.container.background
}
local context_menu = cm({ return w
entries = {
{
name = "Execute as sudo",
icon = gears.color.recolor_image(icondir .. "launch.svg", Theme_config.context_menu.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)
end
},
{
name = "Pin to dock",
icon = gears.color.recolor_image(icondir .. "pin.svg", Theme_config.context_menu.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")
if not handler then
return
end
local dock_table = json:decode(handler:read("a")) or {}
handler:close()
---@diagnostic disable-next-line: param-type-mismatch
table.insert(dock_table, {
name = app_widget.name or "",
icon = Get_gicon_path(app_info.get_icon(app)) or "",
comment = app_widget.comment or "",
exec = app_widget.exec or "",
keywords = app_widget.keywords or "",
categories = app_widget.categories or "",
terminal = app_widget.terminal or "",
actions = app_widget.actions or "",
desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or ""
})
local dock_encoded = json:encode(dock_table)
handler = io.open("/home/crylia/.config/awesome/src/config/dock.json", "w")
if not handler then
return
end
handler:write(dock_encoded)
handler:close()
capi.awesome.emit_signal("dock::changed")
end
},
{
name = "Add to desktop",
icon = gears.color.recolor_image(icondir .. "desktop.svg", Theme_config.context_menu.icon_color),
callback = function()
capi.awesome.emit_signal("application_launcher::show")
--!TODO: Add to desktop
end
}
}
})
-- Execute command on left click and hide launcher
app_widget:buttons(
gears.table.join(
awful.button({
modifiers = {},
button = 1,
on_release = function()
Gio.AppInfo.launch_uris_async(app)
capi.awesome.emit_signal("application_launcher::show")
end
}),
awful.button({
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
end
})
)
)
Hover_signal(app_widget)
table.insert(list, app_widget)
end
end
return 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()
-- Reset to first position
curser = {
x = 1,
y = 1
}
for _, application in ipairs(application_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)
-- Get the current position in the grid of the application as a table
local pos = application_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
application.border_color = Theme_config.application_launcher.application.border_color_active
else
application.border_color = Theme_config.application_launcher.application.border_color
end
end
)
capi.awesome.emit_signal("update::selected")
end
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
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
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
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
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]
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(selected_widget.exec, nil, 0))
end
)
return application_grid
end 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 dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears") local gears = require("gears")
local wibox = require("wibox") local wibox = require("wibox")
local gshape = require("gears.shape")
local gtable = require("gears.table")
local gobject = require("gears.object")
local capi = { local capi = {
awesome = awesome, awesome = awesome,
mouse = mouse, mouse = mouse,
} }
local application_grid = require("src.modules.application_launcher.application")() local application_launcher = { mt = {} }
local searchbar = require("src.modules.application_launcher.searchbar")()
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 { local applicaton_launcher = wibox.widget {
{ {
{ {
searchbar, ret.searchbar,
{ {
application_grid, ret.application_grid,
spacing = dpi(10), spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical, layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0, scrollbar_width = 0,
@@ -36,18 +80,18 @@ return function(s)
margins = dpi(20), margins = dpi(20),
widget = wibox.container.margin widget = wibox.container.margin
}, },
height = s.geometry.height / 100 * 60, height = args.screen.geometry.height / 100 * 60,
--width = s.geometry.width / 100 * 60, --width = s.geometry.width / 100 * 60,
strategy = "exact", strategy = "exact",
widget = wibox.container.constraint widget = wibox.container.constraint
} }
local application_container = awful.popup { ret.application_container = awful.popup {
widget = wibox.container.background, widget = applicaton_launcher,
ontop = true, ontop = true,
visible = false, visible = false,
stretch = false, stretch = false,
screen = s, screen = args.screen,
shape = function(cr, width, height) shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12)) gears.shape.rounded_rect(cr, width, height, dpi(12))
end, end,
@@ -57,24 +101,90 @@ return function(s)
border_width = Theme_config.application_launcher.border_width border_width = Theme_config.application_launcher.border_width
} }
application_container:setup {
applicaton_launcher,
layout = wibox.layout.fixed.vertical
}
capi.awesome.connect_signal( capi.awesome.connect_signal(
"application_launcher::show", "application_launcher::show",
function() function()
if capi.mouse.screen == s then if capi.mouse.screen == args.screen then
application_container.visible = not application_container.visible ret.application_container.visible = not ret.application_container.visible
if application_container.visible == false then
capi.awesome.emit_signal("searchbar::stop")
end
end end
if application_container.visible then if ret.application_container.visible then
capi.awesome.emit_signal("searchbar::start") ret.searchbar:focus()
else
awful.keygrabber.stop()
end end
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 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 return ret
end end
function device.mt.__call(...) function device.mt:__call(...)
return device.new(...) return device.new(...)
end end

View File

@@ -51,8 +51,12 @@ local function add_device(self, device, battery)
end end
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 end
function bluetooth.new(args) function bluetooth.new(args)
@@ -110,21 +114,15 @@ function bluetooth.new(args)
id = "connected_list", id = "connected_list",
{ {
{ {
{ step = dpi(50),
step = dpi(50), spacing = dpi(10),
spacing = dpi(10), layout = require("src.lib.overflow_widget.overflow").vertical,
layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0,
scrollbar_width = 0, id = "connected_device_list"
id = "connected_device_list"
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
}, },
id = "place", id = "margin",
height = dpi(200), margins = dpi(10),
strategy = "max", widget = wibox.container.margin
widget = wibox.container.constraint
}, },
border_color = Theme_config.bluetooth_controller.con_device_border_color, border_color = Theme_config.bluetooth_controller.con_device_border_color,
border_width = Theme_config.bluetooth_controller.con_device_border_width, border_width = Theme_config.bluetooth_controller.con_device_border_width,
@@ -180,21 +178,15 @@ function bluetooth.new(args)
id = "discovered_list", id = "discovered_list",
{ {
{ {
{ id = "discovered_device_list",
id = "discovered_device_list", spacing = dpi(10),
spacing = dpi(10), step = dpi(50),
step = dpi(50), layout = require("src.lib.overflow_widget.overflow").vertical,
layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0,
scrollbar_width = 0,
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
}, },
id = "place", id = "margin",
height = dpi(200), margins = dpi(10),
strategy = "max", widget = wibox.container.margin
widget = wibox.container.constraint
}, },
border_color = Theme_config.bluetooth_controller.con_device_border_color, border_color = Theme_config.bluetooth_controller.con_device_border_color,
border_width = Theme_config.bluetooth_controller.con_device_border_width, border_width = Theme_config.bluetooth_controller.con_device_border_width,
@@ -204,6 +196,59 @@ function bluetooth.new(args)
widget = wibox.container.background, widget = wibox.container.background,
forced_height = 0 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", id = "layout1",
layout = wibox.layout.fixed.vertical layout = wibox.layout.fixed.vertical
}, },
@@ -229,15 +274,14 @@ function bluetooth.new(args)
"bluetooth::device_changed", "bluetooth::device_changed",
function(device, battery) function(device, battery)
add_device(ret, 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("connected_device_list")[1].children = ret:get_devices().paired
bluetooth_container:get_children_by_id("discovered_device_list")[1].children = ret:get_devices().discovered bluetooth_container:get_children_by_id("discovered_device_list")[1].children = ret:get_devices().discovered
end end
) )
local connected_margin = bluetooth_container:get_children_by_id("connected_margin")[1] 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_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 local connected = bluetooth_container:get_children_by_id("connected")[1].center
connected_margin:connect_signal( connected_margin:connect_signal(
@@ -264,7 +308,7 @@ function bluetooth.new(args)
Theme_config.bluetooth_controller.connected_icon_color)) Theme_config.bluetooth_controller.connected_icon_color))
else else
rubato_timer.target = 0 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) gshape.rounded_rect(cr, width, height, 4)
end end
connected.icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg", 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 if discovered_list.forced_height == 0 then
local size = (#ret:get_devices().discovered * 60) + 1 local size = (#ret:get_devices().discovered * 60) + 1
if size < 210 then if size > 210 then
rubato_timer.target = dpi(size) size = 210
end end
rubato_timer.target = dpi(size)
discovered_margin.discovered_bg.shape = function(cr, width, height) discovered_margin.discovered_bg.shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
end 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 gcolor = require("gears.color")
local gfilesystem = require("gears").filesystem local gfilesystem = require("gears").filesystem
local wibox = require("wibox") local wibox = require("wibox")
local base = require("wibox.widget.base")
local capi = { local capi = {
awesome = awesome, awesome = awesome,
@@ -14,12 +15,13 @@ local capi = {
} }
local ical_parser = require("src.tools.ical_parser")() 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 icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
local calendar = { mt = {} } local calendar = { mt = {} }
calendar.tasks = {} calendar.tasks = {}
calendar.calendars = {}
calendar._private = {} calendar._private = {}
@@ -57,6 +59,29 @@ calendar.date = {
year = tonumber(os.date("%Y")) or 1970 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. ---Checks how many days a month has and returns the ammount. Also takes leap years into account.
---@param month number|nil ---@param month number|nil
---@param year number|nil ---@param year number|nil
@@ -147,6 +172,33 @@ end
function calendar:get_tasks() function calendar:get_tasks()
if not ical_parser or not ical_parser.VCALENDAR then return end if not ical_parser or not ical_parser.VCALENDAR then return end
local tasks = {} 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 _, cal in ipairs(ical_parser.VCALENDAR) do
for _, event in ipairs(cal.VEVENT) do for _, event in ipairs(cal.VEVENT) do
if not self:check_event_uid(event.UID) then if not self:check_event_uid(event.UID) then
@@ -158,44 +210,60 @@ function calendar:get_tasks()
if event.DTEND then if event.DTEND then
end_time = event.DTEND.DTEND end_time = event.DTEND.DTEND
end end
-- 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,
hour = start_time.hour,
min = start_time.min,
sec = start_time.sec
}
end
-- Get repeat cases -- Get repeat cases
if event.RRULE then if event.RRULE then
if event.RRULE.FREQ == "DAILY" then if event.RRULE.FREQ == "DAILY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
(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 + 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 elseif event.RRULE.FREQ == "WEEKLY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month, local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day start_time.day
end_time = event.RRULE.UNTIL while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
if not event.RRULE.UNTIL then (day_counter <= event.RRULE.UNTIL.day) do
end_time = { task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
year = start_time.year + 1000, min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
month = start_time.month, d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
day = start_time.day event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
}
end
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 + 7 day_counter = day_counter + 7
local month_length = calendar:get_last_day_in_month(month_counter, year_counter) local month_length = calendar:get_last_day_in_month(month_counter, year_counter)
if day_counter > month_length then if day_counter > month_length then
@@ -208,6 +276,20 @@ function calendar:get_tasks()
end end
end end
elseif event.RRULE.FREQ == "MONTHLY" then elseif event.RRULE.FREQ == "MONTHLY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
(day_counter <= event.RRULE.UNTIL.day) do
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
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 elseif event.RRULE.FREQ == "YEARLY" then
end_time = event.RRULE.UNTIL end_time = event.RRULE.UNTIL
if not event.RRULE.UNTIL then if not event.RRULE.UNTIL then
@@ -218,65 +300,32 @@ function calendar:get_tasks()
} }
end end
for i = start_time.year, end_time.year, 1 do for i = start_time.year, end_time.year, 1 do
table.insert(tasks, { task_factory({ y = i, m = start_time.month, d = start_time.day, hour = start_time.hour,
date_start = { min = start_time.min, sec = start_time.sec }, { y = i, m = end_time.month, d = end_time.day,
year = i, hour = end_time.hour, min = end_time.min, sec = end_time.sec }, event.SUMMARY,
month = start_time.month, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
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
})
end end
end end
-- If RRULE is empty we just add a single day event -- If RRULE is empty we just add a single day event
else else
table.insert(tasks, { task_factory({ y = start_time.year, m = start_time.month, d = start_time.day, hour = start_time.hour,
date_start = { min = start_time.min, sec = start_time.sec }, { y = end_time.year, m = end_time.month,
year = start_time.year, d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
month = start_time.month, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
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,
})
end end
if event.VALARM then 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
end end
--table.insert(calendars, tasks)
table.insert(self.tasks, tasks)
table.insert(self.calendars, {
tasks = self.tasks,
color = cal.color
})
end end
table.insert(self.tasks, tasks)
end end
---!Fix later, I have no idea how to calculate it and the internet has no clue either ---!Fix later, I have no idea how to calculate it and the internet has no clue either
@@ -360,149 +409,91 @@ function calendar:create_calendar_widget()
step = dpi(50), step = dpi(50),
spacing = dpi(2) 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 {
{
{
text = task.summary,
align = "left",
halign = "center",
font = "JetBrainsMono Nerd Font, bold 10",
widget = wibox.widget.textbox
},
margins = dpi(2),
widget = wibox.container.margin
},
fg = Theme_config.calendar.task.fg,
bg = Theme_config.calendar.task.bg,
shape = Theme_config.calendar.task.shape,
forced_height = dpi(20),
widget = wibox.container.background
}
--[[ local ti = task_info { local function task_factory(task, bg)
summary = task.summary, return wibox.widget {
description = task.description, {
location = task.location, {
url = task.url, text = task.summary,
uid = task.uid, align = "left",
date_start = task.date_start, halign = "center",
date_end = task.date_end, font = "JetBrainsMono Nerd Font, bold 10",
} ]] widget = wibox.widget.textbox
},
margins = dpi(2),
widget = wibox.container.margin
},
fg = Theme_config.calendar.task.fg,
bg = bg,
shape = Theme_config.calendar.task.shape,
forced_height = dpi(20),
widget = wibox.container.background
}
end
local task_info_widget = wibox.widget { for _, cal in ipairs(self.calendars) do
{ for _, tasks in ipairs(cal.tasks) do
{ -- Task detail for _, task in ipairs(tasks) do
{ -- Calendar color if (task.date_start.year == year) and (task.date_start.month == month) and (task.date_start.day == day) then
widget = wibox.container.background, -- Check if task if before the current date
shape = function(cr, _, height) local tw
gshape.rounded_rect(cr, dpi(10), height, dpi(8)) if task.date_start.year < self.date.year or
end, (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
{ -- Summary task.date_start.day < self.date.day) then
widget = wibox.widget.textbox, tw = task_factory(task, cal.color .. "55")
text = task.summary, else
valign = "center", tw = task_factory(task, cal.color)
align = "left", end
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,
}
local task_popup = awful.popup { local ti = task_info {
widget = task_info_widget, summary = task.summary,
ontop = true, description = task.description,
visible = true, location = task.location,
bg = "#00000000", url = task.url,
x = capi.mouse.coords().x, uid = task.uid,
y = capi.mouse.coords().y, date_start = task.date_start,
screen = self.screen start_time = task.start_time,
} date_end = task.date_end,
end_time = task.end_time,
freq = task.freq,
task = task,
color = cal.color,
}
tw:connect_signal("button::down", function() local task_popup = awful.popup {
--ti:toggle() widget = ti,
task_popup.visible = not task_popup.visible ontop = true,
end) visible = false,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = self.screen
}
Hover_signal(tw) 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)
)
)
table.insert(tasks_layout, tw) tw:connect_signal("mouse::leave", function()
task_popup.visible = false
end)
Hover_signal(tw)
table.insert(tasks_layout, tw)
end
end end
end end
end end
return tasks_layout return tasks_layout
end end
@@ -749,10 +740,11 @@ end
function calendar.new(args) function calendar.new(args)
args = args or {} 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) 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", border_strategy = "inner",
fg = Theme_config.calendar.fg, fg = Theme_config.calendar.fg,
shape = Theme_config.calendar.shape, shape = Theme_config.calendar.shape,
} })
ret:get_tasks() ret:get_tasks()
@@ -901,109 +893,81 @@ function calendar.new(args)
ret:create_weekdays_widget() ret:create_weekdays_widget()
ret:create_calendar_weeks_widget() ret:create_calendar_weeks_widget()
ret.widget = awful.popup { ret:get_widget():get_children_by_id("add_ical")[1]:buttons(gtable.join(
widget = calendar_widget, awful.button({}, 1, function()
screen = args.screen, awful.spawn.easy_async_with_shell(
ontop = true, "zenity --file-selection --title='Select an ICalendar file' --file-filter='iCalendar File | *.ics'",
bg = "#00000000", function(path_to_file)
visible = false, path_to_file = string.gsub(path_to_file, "\n", "")
placement = function(c) awful.placement.align(c, if (not path_to_file) or (path_to_file == "") then return end
{ position = "top_right", margins = { right = dpi(10), top = dpi(65) } }) ical_parser:add_calendar(path_to_file)
end ret:get_tasks()
ret:create_calendar_widget()
}
calendar_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
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(
awful.button({}, 1, function()
awful.spawn.easy_async_with_shell(
"zenity --info --text='Soon TM'",
function()
end
)
end)
)
)
calendar_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 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 end)
ret:create_calendar_weeks_widget() ))
ret:create_calendar_widget()
end) 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'",
function()
calendar_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 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 end)
ret:create_calendar_weeks_widget() ))
ret:create_calendar_widget()
end) ret:get_widget():get_children_by_id("prev_month")[1]:buttons(gtable.join(
) awful.button({}, 1, function()
) ret.date.month = ret.date.month - 1
if ret.date.month == 0 then
ret.date.month = 12
ret.date.year = ret.date.year - 1
end
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
))
ret:get_widget():get_children_by_id("next_month")[1]:buttons(gtable.join(
awful.button({}, 1, function()
ret.date.month = ret.date.month + 1
if ret.date.month == 13 then
ret.date.month = 1
ret.date.year = ret.date.year + 1
end
ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
))
--- Calendar switch year back --- Calendar switch year back
calendar_widget:get_children_by_id("prev_year")[1]:buttons( ret:get_widget():get_children_by_id("prev_year")[1]:buttons(gtable.join(
gtable.join( awful.button({}, 1, function()
awful.button({}, 1, function() ret.date.year = ret.date.year - 1
ret.date.year = ret.date.year - 1 ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
calendar_widget:get_children_by_id("year")[1].text = ret.date.year ret:create_calendar_weeks_widget()
ret:create_calendar_weeks_widget() ret:create_calendar_widget()
ret:create_calendar_widget() end)
end) ))
)
)
--- Calendar switch year forward --- Calendar switch year forward
calendar_widget:get_children_by_id("next_year")[1]:buttons( ret:get_widget():get_children_by_id("next_year")[1]:buttons(gtable.join(
gtable.join( awful.button({}, 1, function()
awful.button({}, 1, function() ret.date.year = ret.date.year + 1
ret.date.year = ret.date.year + 1 ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
calendar_widget:get_children_by_id("year")[1].text = ret.date.year ret:create_calendar_weeks_widget()
ret:create_calendar_weeks_widget() ret:create_calendar_widget()
ret:create_calendar_widget() end)
end) ))
)
)
capi.awesome.connect_signal("calendar::toggle", function() return ret
if capi.mouse.screen == args.screen then
ret.widget.visible = not ret.widget.visible
end
end)
end end
function calendar.mt:__call(...) function calendar.mt:__call(...)

View File

@@ -20,15 +20,24 @@ task_info._private = {}
function task_info.new(args) function task_info.new(args)
args = args or {} args = args or {}
if not args.task then return end if not args.task then return end
args.screen = args.screen or awful.screen.focused()
local ret = gobject {} local ret = gobject {}
gtable.crush(ret, task_info, true) 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 { local task_info_widget = wibox.widget {
{ {
{
{
{ -- Task detail { -- Task detail
{ -- Calendar color { -- Calendar color
widget = wibox.container.background, widget = wibox.container.background,
bg = args.color,
forced_width = dpi(10),
shape = function(cr, _, height) shape = function(cr, _, height)
gshape.rounded_rect(cr, dpi(10), height, dpi(8)) gshape.rounded_rect(cr, dpi(10), height, dpi(8))
end, end,
@@ -36,95 +45,109 @@ function task_info.new(args)
{ {
{ -- Summary { -- Summary
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.summary, text = args.summary:sub(1, -2) or "NO SUMMARY",
valign = "center", valign = "center",
align = "left", halign = "left",
id = "summary", id = "summary",
}, },
{ -- Date long { -- Date long
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.date_long, text = date_long_written or "01.12.1970",
valign = "center", valign = "center",
align = "right", halign = "right",
id = "date_long", id = "date_long",
}, },
{ -- From - To { -- From - To
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.from_to, text = from_to or "",
valign = "center", valign = "center",
align = "left", halign = "left",
id = "from_to", id = "from_to",
}, },
{ -- Repeat information { -- Repeat information
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.repeat_info, text = args.freq or "0",
valign = "center", valign = "center",
align = "right", halign = "left",
id = "repeat_info", 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, layout = wibox.layout.fixed.vertical,
}, },
spacing = dpi(20),
layout = wibox.layout.fixed.horizontal layout = wibox.layout.fixed.horizontal
}, },
widget = wibox.container.margin,
left = dpi(9)
},
{ -- Location { -- Location
{ {
widget = wibox.widget.imagebox, 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, resize = false,
valign = "center", valign = "center",
halign = "center", halign = "center",
}, },
{ {
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.location, text = args.location:sub(1, -2) or "F303",
valign = "center", valign = "center",
align = "left", halign = "left",
id = "location", id = "location",
}, },
spacing = dpi(10),
id = "location_container", id = "location_container",
layout = wibox.layout.fixed.horizontal layout = wibox.layout.fixed.horizontal
}, },
{ -- Alarm { -- Alarm
{ {
widget = wibox.widget.imagebox, 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, resize = false,
valign = "center", valign = "center",
halign = "center", halign = "center",
}, },
{ {
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
text = ret.alarm, text = args.alarm or "NO ALARM",
valign = "center", valign = "center",
align = "left", halign = "left",
id = "alarm", id = "alarm",
}, },
spacing = dpi(10),
id = "alarm_container", id = "alarm_container",
layout = wibox.layout.fixed.horizontal layout = wibox.layout.fixed.horizontal
}, },
id = "task_detail", id = "task_detail",
spacing = dpi(15),
layout = wibox.layout.fixed.vertical 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, bg = Theme_config.calendar.task_info.bg,
fg = Theme_config.calendar.task_info.fg, fg = Theme_config.calendar.task_info.fg,
shape = Theme_config.calendar.task_info.shape, shape = Theme_config.calendar.task_info.shape,
widget = wibox.container.background, widget = wibox.container.background,
} }
ret.widget = awful.popup { ret.widget = task_info_widget
widget = task_info_widget,
ontop = true,
visible = true,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = args.screen
}
return ret.widget
end end
function task_info.mt:__call(...) function task_info.mt:__call(...)
task_info.new(...) return task_info.new(...)
end end
return setmetatable(task_info, task_info.mt) 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) 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 function prepare_widgets(w)
local layout = { local layout = {
forced_height = dpi(50), forced_height = dpi(50),
@@ -72,55 +55,53 @@ return function(s, widgets)
return layout return layout
end end
top_center:setup { local top_center = awful.popup {
nil, screen = s,
prepare_widgets(widgets), widget = prepare_widgets(widgets),
nil, ontop = false,
layout = wibox.layout.fixed.horizontal 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( top_center:struts {
"manage", top = dpi(55)
function(c) }
if #s.selected_tag:clients() < 1 then
top_center.visible = false
else
top_center.visible = true
end
end
)
capi.client.connect_signal( capi.client.connect_signal("manage", function(c)
"unmanage", if #s.selected_tag:clients() < 1 then
function(c) top_center.visible = false
if #s.selected_tag:clients() < 1 then else
top_center.visible = false top_center.visible = true
else
top_center.visible = true
end
end end
) end)
capi.client.connect_signal( capi.client.connect_signal("unmanage", function(c)
"property::selected", if #s.selected_tag:clients() < 1 then
function(c) top_center.visible = false
if #s.selected_tag:clients() < 1 then else
top_center.visible = false top_center.visible = true
else
top_center.visible = true
end
end end
) end)
capi.awesome.connect_signal( capi.client.connect_signal("property::selected", function(c)
"refresh", if #s.selected_tag:clients() < 1 then
function(c) top_center.visible = false
if #s.selected_tag:clients() < 1 then else
top_center.visible = false top_center.visible = true
else
top_center.visible = true
end
end end
) end)
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 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) return function(screen)
@@ -76,7 +76,7 @@ return function(screen)
for _, action in ipairs(program.actions) do for _, action in ipairs(program.actions) do
table.insert(action_entries, { table.insert(action_entries, {
name = Gio.DesktopAppInfo.get_action_name(DAI, action) or "", 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() callback = function()
Gio.DesktopAppInfo.launch_action(DAI, action) Gio.DesktopAppInfo.launch_action(DAI, action)
end end
@@ -85,7 +85,7 @@ return function(screen)
table.insert(action_entries, { table.insert(action_entries, {
name = "Remove from Dock", name = "Remove from Dock",
icon = icondir .. "entry.svg", icon = gears.color.recolor_image(icondir .. "entry.svg", Theme_config.dock.cm_icon),
callback = function() callback = function()
local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r") local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r")
if not data then if not data then
@@ -111,9 +111,41 @@ return function(screen)
end end
}) })
local context_menu = cm({ local context_menu = cm {
entries = action_entries 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( dock_element:buttons(gears.table.join(
awful.button({ awful.button({
@@ -131,10 +163,7 @@ return function(screen)
return return
end end
-- add offset so mouse is above widget, this is so the mouse::leave event triggers always -- 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:toggle()
context_menu.y = capi.mouse.coords().y + 10 - context_menu.height
context_menu.visible = not context_menu.visible
cm_open = context_menu.visible
end end
}) })
)) ))

View File

@@ -25,7 +25,7 @@ return function(s)
elseif widget == "Cpu Usage" then elseif widget == "Cpu Usage" then
table.insert(widget_table, require("src.widgets.cpu_info")("usage")) table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
elseif widget == "Date" then 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 elseif widget == "Gpu Temperature" then
table.insert(widget_table, require("src.widgets.gpu_info")("temp")) table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
elseif widget == "Gpu Usage" then elseif widget == "Gpu Usage" then
@@ -52,8 +52,8 @@ return function(s)
return widget_table return widget_table
end end
if User_config.widgets then if User_config.crylia_bar then
for index, screen in ipairs(User_config.widgets) do for index, screen in ipairs(User_config.crylia_bar) do
if index == s.index then if index == s.index then
if screen.left_bar then if screen.left_bar then
require("src.modules.crylia_bar.left_bar")(s, get_widgets(screen.left_bar)) require("src.modules.crylia_bar.left_bar")(s, get_widgets(screen.left_bar))

View File

@@ -9,25 +9,6 @@ local wibox = require("wibox")
return function(s, w) 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 function prepare_widgets(widgets)
local layout = { local layout = {
forced_height = dpi(50), forced_height = dpi(50),
@@ -69,10 +50,22 @@ return function(s, w)
return layout return layout
end end
top_left:setup { local top_left = awful.popup {
prepare_widgets(w), screen = s,
nil, widget = prepare_widgets(w),
nil, ontop = false,
layout = wibox.layout.fixed.horizontal 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 end

View File

@@ -9,22 +9,6 @@ local wibox = require("wibox")
return function(s, w) 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 function prepare_widgets(widgets)
local layout = { local layout = {
forced_height = dpi(50), forced_height = dpi(50),
@@ -66,10 +50,21 @@ return function(s, w)
return layout return layout
end end
top_right:setup { local top_right = awful.popup {
nil, widget = prepare_widgets(w),
nil, ontop = false,
prepare_widgets(w), bg = Theme_config.right_bar.bg,
layout = wibox.layout.align.horizontal 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 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] User_config.layouts[1]
) )
require("src.modules.powermenu")(s) require("src.modules.desktop.context_menu") { screen = s }
require("src.modules.volume_osd")(s) require("src.modules.desktop.desktop") { screen = s }
require("src.modules.brightness_osd")(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.bluetooth.init") { screen = s }
require("src.modules.titlebar") require("src.modules.titlebar.titlebar")
require("src.modules.volume_controller")(s)
require("src.modules.crylia_bar.init")(s) require("src.modules.crylia_bar.init")(s)
--require("src.modules.crylia_wibox.init")(s)
require("src.modules.notification-center.init")(s) require("src.modules.notification-center.init")(s)
require("src.modules.window_switcher.init")(s) require("src.modules.window_switcher.init")(s)
require("src.modules.application_launcher.init")(s) require("src.modules.application_launcher.init") { screen = s }
require("src.modules.calendar.init") { screen = s } --require("src.modules.calendar.init") { screen = s }
require("src.modules.network_controller.init") { screen = s }
end 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 -- Awesome Libs
local awful = require("awful") local awful = require("awful")
local dbus_proxy = require("dbus_proxy")
local dpi = require("beautiful").xresources.apply_dpi 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 gears = require("gears")
local lgi = require("lgi")
local wibox = require("wibox") local wibox = require("wibox")
local NM = require("lgi").NM
local rubato = require("src.lib.rubato") 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/" 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 end
local network_controller = wibox.widget { 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 {
{ {
{ {
{ -- 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
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
{ -- Airplanemode/Refresh buttons
{ -- Airplane mode toggle
{ {
{ {
{ {
-- TODO: Replace with image {
text = "Airplane mode", resize = false,
widget = wibox.widgeet.textbox 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,
}, },
widget = wibox.container.margin {
{
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) shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5)) gshape.rounded_rect(cr, width, height, dpi(4))
end, end,
widget = wibox.container.background widget = wibox.container.background
}, },
id = "wifi_margin",
widget = wibox.container.margin widget = wibox.container.margin
}, },
{ -- Refresh button {
id = "wifi_list",
{ {
{ {
{ step = dpi(50),
-- TODO: Replace with image spacing = dpi(10),
text = "Refresh", layout = require("src.lib.overflow_widget.overflow").vertical,
widget = wibox.widgeet.textbox scrollbar_width = 0,
}, id = "wifi_ap_list"
widget = wibox.container.margin
}, },
shape = function(cr, width, height) id = "margin",
gears.shape.rounded_rect(cr, width, height, dpi(5)) margins = dpi(10),
end, widget = wibox.container.margin
widget = wibox.container.background
}, },
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)
gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4))
end,
widget = wibox.container.background,
forced_height = 0
}, },
layout = wibox.layout.align.horizontal {
{ -- action buttons
{ -- refresh
{
{
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,
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 = "refresh"
},
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
}, },
layout = wibox.layout.fixed.vertical id = "margin",
margins = dpi(15),
widget = wibox.container.margin
}, },
margins = dpi(10), shape = function(cr, width, height)
widget = wibox.container.margin 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), width = dpi(400),
strategy = "exact", strategy = "exact",
widget = wibox.container.constraint widget = wibox.container.constraint
} }
local network_controller_container = awful.popup { local refresh_button = network_widget:get_children_by_id("refresh")[1]
widget = wibox.container.background,
bg = Theme_config.network_controller.bg, refresh_button:buttons(
border_color = Theme_config.network_controller.border_color, gtable.join(
border_width = Theme_config.network_controller.border_width, awful.button(
screen = s, {},
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, stretch = false,
visible = false, visible = false,
ontop = true, ontop = true,
@@ -122,9 +666,22 @@ return function(s)
end end
} }
network_controller_container:setup { capi.awesome.connect_signal("NM::toggle_container", function()
network_controller, ret.widget.visible = not ret.widget.visible
layout = wibox.layout.fixed.vertical 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 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 end
) )
table.insert(nl.notification_list, notification) table.insert(nl.notification_list, 1, notification)
end end
naughty.connect_signal( 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

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

View File

@@ -45,7 +45,7 @@ User_config = {
"MEDIA_PLAYER" "MEDIA_PLAYER"
More information at: https://lazka.github.io/pgi-docs/UPowerGlib-1.0/enums.html#UPowerGlib.DeviceKind.KEYBOARD 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. If your battery is not found you can specify its path here.
@@ -98,6 +98,8 @@ User_config = {
specify = "JetBrainsMono Nerd Font" specify = "JetBrainsMono Nerd Font"
}, },
gtk_settings = "lxappearance",
--[[ --[[
The icon theme name must be exactly as the folder is called 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] The folder can be in any $XDG_DATA_DIRS/icons/[icon_theme_name]
@@ -147,6 +149,8 @@ User_config = {
]] -- ]] --
modkey = "Mod4", 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. This is the naming sheme used for the powermenu and maybe some other places in the future.
Example: Example:
@@ -168,6 +172,8 @@ User_config = {
ethernet = "eno1" ethernet = "eno1"
}, },
screen_settings = "arandr",
--[[ --[[
This is the program that will be executed when hitting the print key. This is the program that will be executed when hitting the print key.
]] -- ]] --
@@ -198,7 +204,6 @@ User_config = {
"backlight" "backlight"
}, },
--[[ --[[
If true the taskbar will shot the client name instead of the class name. If true the taskbar will shot the client name instead of the class name.
Default: false Default: false
@@ -210,6 +215,8 @@ User_config = {
]] -- ]] --
terminal = "alacritty", terminal = "alacritty",
text_editor = "code",
--[[ --[[
Add every client that should get no titlebar. Add every client that should get no titlebar.
Use xprop WM_ClASS to get the class of the window. Use xprop WM_ClASS to get the class of the window.
@@ -222,6 +229,7 @@ User_config = {
} }
]] -- ]] --
titlebar_exception = { titlebar_exception = {
"protonvpn"
}, },
--[[ --[[
@@ -235,7 +243,7 @@ User_config = {
This is the path to your wallpaper. This is the path to your wallpaper.
home is $HOME, you can also use an absolute path. 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. This is the weather widget.
@@ -246,11 +254,13 @@ User_config = {
unit = "metric" or "imperial" unit = "metric" or "imperial"
]] ]]
weather_secrets = { weather_secrets = {
key = "", key = "e71b00168ca7219563dde4514a425b14",
city_id = "", city_id = "2864118",
unit = "metric" unit = "metric"
}, },
web_browser = "brave-browser",
--[[ --[[
You can configure your bar's here, if you leave it empty the bar will not be shown. 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. 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 "Tasklist" <-- Shows all programs per tag
!The order goes from left to right! !The order goes from left to right!
]] ]]
widgets = { crylia_bar = {
[1] = { [1] = {
left_bar = { left_bar = {
"Tiling Layout", "Tiling Layout",
@@ -296,8 +306,11 @@ User_config = {
"Clock", "Clock",
"Power Button" "Power Button"
} }
}, }
[2] = { },
crylia_wibox = {
[1] = {
left_bar = { left_bar = {
"Tiling Layout", "Tiling Layout",
"Taglist" "Taglist"
@@ -306,13 +319,14 @@ User_config = {
"Tasklist" "Tasklist"
}, },
right_bar = { right_bar = {
"Ram Usage", "Systray",
"Battery",
"Bluetooth",
"Audio", "Audio",
"Keyboard Layout",
"Network", "Network",
"Keyboard Layout",
"Date", "Date",
"Clock", "Clock",
"Power Button"
} }
} }
} }

View File

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

View File

@@ -1,27 +1,42 @@
local awful = require("awful") local awful = require("awful")
local pulse = require("pulseaudio_dbus")
local capi = { local capi = {
awesome = awesome, awesome = awesome,
} }
--[[ local lgi = require("lgi") local lgi = require("lgi")
local pulseaudio = require("lua_libpulse_glib") local pulseaudio = require("lua_libpulse_glib")
local ppretty = require("pl.ppretty")
local pa = pulseaudio.new() 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 if state == 4 then
print("Connection is ready") print("Connection is ready")
ctx:get_sinks(function(sinks) ctx:get_sinks(function(sinks)
ppretty.dump(sinks) print(sinks[1])
end) end)
end 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( awful.spawn.with_line_callback(
[[bash -c "LC_ALL=C pactl subscribe"]], [[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}'"]], [[ bash -c "nvidia-smi -q -d TEMPERATURE | grep 'GPU Current Temp' | awk '{print $5}'"]],
3, 3,
function(_, stdout) function(_, stdout)
if not stdout:gsub("\n", "") then return end
capi.awesome.emit_signal("update::gpu_temp", stdout:match("%d+"):gsub("\n", "")) capi.awesome.emit_signal("update::gpu_temp", stdout:match("%d+"):gsub("\n", ""))
end end
) )

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -110,16 +110,6 @@ local list_update = function(widget, buttons, _, _, objects)
strategy = "exact", strategy = "exact",
layout = wibox.container.constraint, 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 end
Hover_signal(tag_widget) Hover_signal(tag_widget)