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,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 gears = require("gears")
local wibox = require("wibox")
local base = require("wibox.widget.base")
local gtable = require("gears.table")
local json = require("src.lib.json-lua.json-lua")
local cm = require("src.modules.context_menu.init")
local capi = {
awesome = awesome,
mouse = mouse,
}
local json = require("src.lib.json-lua.json-lua")
local cm = require("src.modules.context_menu")
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
return function(s)
local application_grid = { mt = {} }
local application_grid = wibox.widget {
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,
expand = false,
spacing = dpi(10),
@@ -34,279 +255,104 @@ return function(s)
orientation = "vertical",
layout = wibox.layout.grid
}
-- Selected application position, default is first at 1,1
-- The typo *might* be intentional
local curser = {
for _, application in ipairs(self.app_list) do
-- 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,
y = 1
}
local filter = ""
w:get_applications_from_file()
---Executes only once to create a widget from each desktop file
---@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
}
w:set_applications()
local context_menu = cm({
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
return w
end
function application_grid.mt:__call(...)
return application_grid.new(...)
end
return setmetatable(application_grid, application_grid.mt)

View File

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

View File

@@ -0,0 +1,553 @@
-----------------------------------
-- This is the volume controller --
-----------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local gobject = require("gears.object")
local capi = {
awesome = awesome,
mousegrabber = mousegrabber,
}
local rubato = require("src.lib.rubato")
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
local volume_controler = { mt = {} }
function volume_controler.get_device_widget()
local device = wibox.widget {
{
{
{
id = "icon",
resize = false,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox
},
spacing = dpi(10),
{
text = name,
id = "node",
widget = wibox.widget.textbox
},
id = "device_layout",
layout = wibox.layout.fixed.horizontal
},
id = "device_margin",
margins = dpi(9),
widget = wibox.container.margin
},
id = "background",
bg = Theme_config.volume_controller.device_bg,
border_color = Theme_config.volume_controller.device_border_color,
border_width = Theme_config.volume_controller.device_border_width,
shape = Theme_config.volume_controller.device_shape,
widget = wibox.container.background
}
if true then
device:connect_signal(
"button::press",
function(_, _, _, key)
if key == 1 then
if node then
--awful.spawn("./.config/awesome/src/scripts/vol.sh set_sink " .. node)
--capi.awesome.emit_signal("update::bg_sink", node)
end
end
end
)
--[[ capi.awesome.connect_signal(
"update::bg_sink",
function(new_node)
if node == new_node then
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
Theme_config.volume_controller.device_icon_color)
device.bg = Theme_config.volume_controller.device_headphones_selected_bg
device.fg = Theme_config.volume_controller.device_headphones_selected_fg
Hover_signal(device)
else
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
Theme_config.volume_controller.device_headphones_selected_icon_color)
device.bg = Theme_config.volume_controller.device_bg
device.fg = Theme_config.volume_controller.device_headphones_fg
Hover_signal(device)
end
end
) ]]
else
device:connect_signal(
"button::press",
function(_, _, _, key)
if key == 1 then
if node then
--awful.spawn("./.config/awesome/src/scripts/mic.sh set_source " .. node)
--capi.awesome.emit_signal("update::bg_source", node)
end
end
end
)
--[[ capi.awesome.connect_signal(
"update::bg_source",
function(new_node)
if node == new_node then
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
Theme_config.volume_controller.device_icon_color)
device.bg = Theme_config.volume_controller.device_microphone_selected_bg
device.fg = Theme_config.volume_controller.device_microphone_selected_fg
Hover_signal(device)
else
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg",
Theme_config.volume_controller.device_microphone_selected_icon_color)
device.bg = Theme_config.volume_controller.device_bg
device.fg = Theme_config.volume_controller.device_microphone_fg
Hover_signal(device)
end
end
) ]]
end
return device
end
-- Get all source devices
function volume_controler:get_source_devices()
end
-- Get all input devices
function volume_controler:get_input_devices()
end
function volume_controler:toggle()
volume_controler.popup.visible = not volume_controler.popup.visible
end
function volume_controler.run(args)
args = args or {}
local ret = gobject {}
local w = wibox.widget {
{
{
-- Audio Device selector
{
{
{
{
{
resize = false,
image = gears.color.recolor_image(icondir .. "menu-down.svg",
Theme_config.volume_controller.device_headphones_selected_icon_color),
widget = wibox.widget.imagebox,
valign = "center",
halign = "center",
id = "icon"
},
id = "center",
halign = "center",
valign = "center",
widget = wibox.container.place,
},
{
{
text = "Output Device",
widget = wibox.widget.textbox,
id = "device_name"
},
margins = dpi(5),
widget = wibox.container.margin
},
id = "audio_volume",
layout = wibox.layout.fixed.horizontal
},
id = "audio_bg",
bg = Theme_config.volume_controller.list_bg,
fg = Theme_config.volume_controller.list_headphones_fg,
shape = Theme_config.volume_controller.list_shape,
widget = wibox.container.background
},
id = "audio_selector_margin",
left = dpi(10),
right = dpi(10),
top = dpi(10),
widget = wibox.container.margin
},
{
id = "volume_list",
widget = {
{
{
{
{
spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0,
step = dpi(50),
id = "volume_device_list",
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
id = "place",
height = dpi(200),
strategy = "max",
widget = wibox.container.constraint
},
border_color = Theme_config.volume_controller.list_border_color,
border_width = Theme_config.volume_controller.list_border_width,
id = "volume_device_background",
shape = Theme_config.volume_controller.list_shape,
widget = wibox.container.background
},
left = dpi(10),
right = dpi(10),
widget = wibox.container.margin
},
forced_height = 0
},
-- Microphone selector
{
{
{
{
{
resize = false,
image = gears.color.recolor_image(icondir .. "menu-down.svg",
Theme_config.volume_controller.device_microphone_selected_icon_color),
widget = wibox.widget.imagebox,
valign = "center",
halign = "center",
id = "icon",
},
id = "center",
halign = "center",
valign = "center",
widget = wibox.container.place,
},
{
{
text = "Input Device",
widget = wibox.widget.textbox,
id = "device_name"
},
margins = dpi(5),
widget = wibox.container.margin
},
id = "mic_volume",
layout = wibox.layout.fixed.horizontal
},
id = "mic_bg",
bg = Theme_config.volume_controller.list_bg,
fg = Theme_config.volume_controller.list_microphone_fg,
shape = Theme_config.volume_controller.selector_shape,
widget = wibox.container.background
},
id = "mic_selector_margin",
left = dpi(10),
right = dpi(10),
top = dpi(10),
widget = wibox.container.margin
},
{
id = "mic_list",
widget = {
{
{
{
{
spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical,
id = "volume_device_list",
scrollbar_width = 0,
step = dpi(50),
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
id = "place",
height = dpi(200),
strategy = "max",
widget = wibox.container.constraint
},
id = "volume_device_background",
border_color = Theme_config.volume_controller.list_border_color,
border_width = Theme_config.volume_controller.list_border_width,
shape = Theme_config.volume_controller.list_shape,
widget = wibox.container.background
},
left = dpi(10),
right = dpi(10),
widget = wibox.container.margin
},
forced_height = 0
},
-- Audio volume slider
{
{
{
resize = false,
widget = wibox.widget.imagebox,
valign = "center",
halign = "center",
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_controller.volume_fg),
id = "icon",
},
{
{
bar_shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5))
end,
bar_height = dpi(5),
bar_color = Theme_config.volume_controller.border_color,
bar_active_color = Theme_config.volume_controller.volume_fg,
handle_color = Theme_config.volume_controller.volume_fg,
handle_shape = gears.shape.circle,
handle_border_color = Theme_config.volume_controller.volume_fg,
handle_width = dpi(12),
maximum = 100,
forced_height = dpi(26),
widget = wibox.widget.slider,
id = "slider"
},
left = dpi(5),
id = "slider_margin",
widget = wibox.container.margin
},
id = "audio_volume",
layout = wibox.layout.align.horizontal
},
id = "audio_volume_margin",
top = dpi(10),
left = dpi(10),
right = dpi(10),
widget = wibox.container.margin
},
-- Microphone volume slider
{
{
{
resize = false,
widget = wibox.widget.imagebox,
valign = "center",
halign = "center",
image = gears.color.recolor_image(icondir .. "microphone.svg", Theme_config.volume_controller.microphone_fg),
id = "icon"
},
{
{
bar_shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5))
end,
bar_height = dpi(5),
bar_color = Theme_config.volume_controller.device_border_color,
bar_active_color = Theme_config.volume_controller.microphone_fg,
handle_color = Theme_config.volume_controller.microphone_fg,
handle_shape = gears.shape.circle,
handle_border_color = Theme_config.volume_controller.microphone_fg,
handle_width = dpi(12),
maximum = 100,
forced_height = dpi(26),
widget = wibox.widget.slider,
id = "slider"
},
left = dpi(5),
id = "slider_margin",
widget = wibox.container.margin
},
id = "mic_volume",
layout = wibox.layout.align.horizontal
},
id = "mic_volume_margin",
left = dpi(10),
right = dpi(10),
top = dpi(10),
widget = wibox.container.margin
},
id = "controller_layout",
layout = wibox.layout.fixed.vertical
},
id = "controller_margin",
margins = dpi(10),
widget = wibox.container.margin
},
bg = Theme_config.volume_controller.bg,
border_color = Theme_config.volume_controller.border_color,
border_width = Theme_config.volume_controller.border_width,
shape = Theme_config.volume_controller.shape,
forced_width = dpi(400),
widget = wibox.container.background
}
ret.widget = w
ret.audio_dropdown = w:get_children_by_id("audio_list")[1]
ret.mic_dropdown = w:get_children_by_id("mic_list")[1]
ret.audio_slider = w:get_children_by_id("slider")[1]
ret.mic_slider = w:get_children_by_id("slider")[1]
-- Main container
ret.popup = awful.popup {
widget = w,
ontop = true,
bg = Theme_config.volume_controller.bg,
stretch = false,
visible = false,
screen = args.screen,
--! Calculate the popup position instead of hardcoding it
placement = function(c) awful.placement.align(c,
{ position = "top_right", margins = { right = dpi(305), top = dpi(60) } })
end,
shape = Theme_config.volume_controller.shape,
}
-- Set the volume and icon
capi.awesome.connect_signal(
"audio::get",
function(muted, volume)
if muted then
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
.recolor_image(icondir .. "volume-mute.svg", Theme_config.volume_controller.volume_fg))
else
volume = tonumber(volume)
if not volume then
return
end
local icon = icondir .. "volume"
if volume < 1 then
icon = icon .. "-mute"
elseif volume >= 1 and volume < 34 then
icon = icon .. "-low"
elseif volume >= 34 and volume < 67 then
icon = icon .. "-medium"
elseif volume >= 67 then
icon = icon .. "-high"
end
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.slider_margin.slider:
set_value(volume)
volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color
.recolor_image(icon
.. ".svg", Theme_config.volume_controller.volume_fg))
end
end
)
-- Get microphone volume
capi.awesome.connect_signal(
"microphone::get",
function(muted, volume)
if muted then
--volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(0))
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
else
volume = tonumber(volume)
if not volume then
return
end
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(volume))
if volume > 0 then
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
.. "microphone.svg", Theme_config.volume_controller.microphone_fg))
else
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
end
end
end
)
-- Microphone slider change event
ret.widget:connect_signal(
"property::value",
function()
end
)
-- Slide animation
ret.audio_dropdown:connect_signal(
"button::press",
function(_, _, _, key)
if key == 1 then
local rubato_timer = rubato.timed {
duration = 0.4,
intro = 0.1,
outro = 0.1,
pos = mic_list.forced_height,
easing = rubato.linear,
subscribed = function(v)
mic_list.forced_height = v
end
}
if mic_list.forced_height == 0 then
rubato_timer.target = dpi(200)
mic_selector_margin.mic_bg.shape = function(cr, width, height)
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
end
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
Theme_config.volume_controller.device_microphone_selected_icon_color))
else
rubato_timer.target = 0
mic_bg.shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end
mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
Theme_config.volume_controller.device_microphone_selected_icon_color))
end
end
end
)
-- Slide animation
ret.mic_dropdown:connect_signal(
"button::press",
function(_, _, _, key)
if key == 1 then
local rubato_timer = rubato.timed {
duration = 0.4,
intro = 0.1,
outro = 0.1,
pos = volume_list.forced_height,
easing = rubato.linear,
subscribed = function(v)
volume_list.forced_height = v
end
}
if volume_list.forced_height == 0 then
rubato_timer.target = dpi(200)
audio_bg.shape = function(cr, width, height)
gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
end
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg",
Theme_config.volume_controller.device_headphones_selected_icon_color))
else
rubato_timer.target = 0
audio_bg.shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(4))
end
audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg",
Theme_config.volume_controller.device_headphones_selected_icon_color))
end
end
end
)
return ret
end
function volume_controler.mt:__call(...)
return volume_controler.run(...)
end
return setmetatable(volume_controler, volume_controler.mt)

View File

@@ -0,0 +1,153 @@
-----------------------------------
-- This is the volume_old module --
-----------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local gobject = require("gears.object")
local capi = {
awesome = awesome,
mouse = mouse,
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/"
local osd = { mt = {} }
function osd.new(args)
args = args or {}
args.screen = args.screen or 1
local ret = gobject {}
ret.w = wibox.widget {
{
{
{ -- Volume Icon
image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_osd.icon_color),
valign = "center",
halign = "center",
resize = false,
id = "icon",
widget = wibox.widget.imagebox
},
{ -- Volume Bar
{
{
id = "progressbar1",
color = Theme_config.volume_osd.bar_bg_active,
background_color = Theme_config.volume_osd.bar_bg,
max_value = 100,
value = 50,
forced_height = dpi(6),
shape = function(cr, width, heigth)
gears.shape.rounded_bar(cr, width, heigth, dpi(6))
end,
widget = wibox.widget.progressbar
},
id = "progressbar_container2",
halign = "center",
valign = "center",
widget = wibox.container.place
},
id = "progressbar_container",
width = dpi(240),
heigth = dpi(20),
stragety = "max",
widget = wibox.container.constraint
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
forced_width = dpi(300),
forced_height = dpi(80),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
border_color = Theme_config.volume_osd.border_color,
border_width = Theme_config.volume_osd.border_width,
fg = Theme_config.volume_osd.fg,
bg = Theme_config.volume_osd.bg,
widget = wibox.container.background
}
local volume_container = awful.popup {
widget = ret.w,
ontop = true,
stretch = false,
visible = false,
screen = args.screen,
placement = function(c) awful.placement.bottom_left(c, { margins = dpi(20) }) end,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(14))
end
}
local hide_volume_osd = gears.timer {
timeout = 2,
autostart = true,
callback = function()
volume_container.visible = false
end
}
capi.awesome.connect_signal(
"audio::get",
function(muted, volume)
if muted then
ret.w:get_children_by_id("icon")[1]
:set_image(gears.color.recolor_image(
icondir .. "volume-mute" .. ".svg", Theme_config.volume_osd.icon_color))
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(0)
else
volume = tonumber(volume)
if not volume then
return
end
ret.w:get_children_by_id("progressbar1")[1].value = tonumber(volume)
local icon = icondir .. "volume"
if volume < 1 then
icon = icon .. "-mute"
elseif volume >= 1 and volume < 34 then
icon = icon .. "-low"
elseif volume >= 34 and volume < 67 then
icon = icon .. "-medium"
elseif volume >= 67 then
icon = icon .. "-high"
end
ret.w:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
Theme_config.volume_osd.icon_color))
end
end
)
capi.awesome.connect_signal(
"widget::volume_osd:rerun",
function()
if capi.mouse.screen == args.screen then
volume_container.visible = true
if hide_volume_osd.started then
hide_volume_osd:again()
else
hide_volume_osd:start()
end
end
end
)
end
function osd.mt:__call(...)
return osd.new(...)
end
return setmetatable(osd, osd.mt)

View File

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

View File

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

View File

@@ -0,0 +1,133 @@
---------------------------------------
-- This is the brightness_osd module --
---------------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local capi = {
awesome = awesome,
mouse = mouse,
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/brightness/"
return function(s)
local brightness_osd_widget = wibox.widget {
{
{
{ -- Brightness Icon
image = gears.color.recolor_image(icondir .. "brightness-high.svg", Theme_config.brightness_osd.icon_color),
valign = "center",
halign = "center",
resize = false,
id = "icon",
widget = wibox.widget.imagebox
},
{ -- Brightness Bar
{
{
id = "progressbar1",
color = Theme_config.brightness_osd.bar_bg_active,
background_color = Theme_config.brightness_osd.bar_bg,
max_value = 100,
value = 0,
forced_height = dpi(6),
shape = function(cr, width, height)
gears.shape.rounded_bar(cr, width, height, dpi(6))
end,
widget = wibox.widget.progressbar
},
id = "progressbar_container2",
halign = "center",
valign = "center",
widget = wibox.container.place
},
id = "progressbar_container",
width = dpi(240),
heigth = dpi(20),
stragety = "max",
widget = wibox.container.constraint
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
forced_width = dpi(300),
forced_height = dpi(80),
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
border_color = Theme_config.brightness_osd.border_color,
border_width = Theme_config.brightness_osd.border_width,
fg = Theme_config.brightness_osd.fg,
bg = Theme_config.brightness_osd.bg,
widget = wibox.container.background
}
capi.awesome.connect_signal(
"brightness::get",
function(brightness)
brightness_osd_widget:get_children_by_id("progressbar1")[1].value = brightness
local icon = icondir .. "brightness"
if brightness >= 0 and brightness < 34 then
icon = icon .. "-low"
elseif brightness >= 34 and brightness < 67 then
icon = icon .. "-medium"
elseif brightness >= 67 then
icon = icon .. "-high"
end
brightness_osd_widget:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg",
Theme_config.brightness_osd.icon_color))
end
)
local brightness_container = awful.popup {
widget = {},
ontop = true,
stretch = false,
visible = false,
screen = s,
placement = function(c) awful.placement.bottom_left(c, { margins = dpi(20) }) end,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(14))
end
}
local hide_brightness_osd = gears.timer {
timeout = 2,
autostart = true,
callback = function()
brightness_container.visible = false
end
}
brightness_container:setup {
brightness_osd_widget,
layout = wibox.layout.fixed.horizontal
}
capi.awesome.connect_signal(
"brightness::rerun",
function()
if capi.mouse.screen == s then
brightness_container.visible = true
if hide_brightness_osd.started then
hide_brightness_osd:again()
else
hide_brightness_osd:start()
end
end
end
)
end

View File

@@ -7,6 +7,7 @@ local gshape = require("gears.shape")
local gcolor = require("gears.color")
local gfilesystem = require("gears").filesystem
local wibox = require("wibox")
local base = require("wibox.widget.base")
local capi = {
awesome = awesome,
@@ -14,12 +15,13 @@ local capi = {
}
local ical_parser = require("src.tools.ical_parser")()
--local task_info = require("src.modules.calendar.task_info")
local task_info = require("src.modules.calendar.task_info")
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/"
local calendar = { mt = {} }
calendar.tasks = {}
calendar.calendars = {}
calendar._private = {}
@@ -57,6 +59,29 @@ calendar.date = {
year = tonumber(os.date("%Y")) or 1970
}
--#region base widget functions
function calendar:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
function calendar:fit(context, width, height)
local w, h = 0, 0
if self._private.widget then
w, h = base.fit_widget(self, context, self._private.widget, width, height)
end
return w, h
end
calendar.set_widget = base.set_widget_common
function calendar:get_widget()
return self._private.widget
end
--#endregion
---Checks how many days a month has and returns the ammount. Also takes leap years into account.
---@param month number|nil
---@param year number|nil
@@ -147,6 +172,33 @@ end
function calendar:get_tasks()
if not ical_parser or not ical_parser.VCALENDAR then return end
local tasks = {}
local function task_factory(start_date, end_date, sum, loc, des, uid, freq)
table.insert(tasks, {
date_start = {
year = start_date.y,
month = start_date.m,
day = start_date.d,
hour = start_date.hour or 0,
min = start_date.min or 0,
sec = start_date.sec or 0
},
date_end = {
year = end_date.y,
month = end_date.m,
day = end_date.d,
hour = end_date.hour or 0,
min = end_date.min or 0,
sec = end_date.sec or 0
},
summary = sum,
location = loc,
description = des,
uid = uid,
freq = freq,
})
end
for _, cal in ipairs(ical_parser.VCALENDAR) do
for _, event in ipairs(cal.VEVENT) do
if not self:check_event_uid(event.UID) then
@@ -158,44 +210,60 @@ function calendar:get_tasks()
if event.DTEND then
end_time = event.DTEND.DTEND
end
-- 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
if event.RRULE then
if event.RRULE.FREQ == "DAILY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
(day_counter <= event.RRULE.UNTIL.day) do
task_factory({
y = year_counter,
m = month_counter,
d = day_counter,
hour = start_time.hour,
min = start_time.min,
sec = start_time.sec
}, {
y = year_counter,
m = month_counter,
d = day_counter,
hour = end_time.hour,
min = end_time.min,
sec = end_time.sec
}, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
day_counter = day_counter + 1
if day_counter > calendar:get_last_day_in_month(month_counter, year_counter) then
day_counter = 1
month_counter = month_counter + 1
if month_counter > 12 then
month_counter = 1
year_counter = year_counter + 1
end
end
end
elseif event.RRULE.FREQ == "WEEKLY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
end_time = event.RRULE.UNTIL
if not event.RRULE.UNTIL then
end_time = {
year = start_time.year + 1000,
month = start_time.month,
day = start_time.day
}
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
})
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
(day_counter <= event.RRULE.UNTIL.day) do
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
day_counter = day_counter + 7
local month_length = calendar:get_last_day_in_month(month_counter, year_counter)
if day_counter > month_length then
@@ -208,6 +276,20 @@ function calendar:get_tasks()
end
end
elseif event.RRULE.FREQ == "MONTHLY" then
local year_counter, month_counter, day_counter = start_time.year, start_time.month,
start_time.day
while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or
(day_counter <= event.RRULE.UNTIL.day) do
task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour,
min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter,
d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
month_counter = month_counter + 1
if month_counter > 12 then
month_counter = 1
year_counter = year_counter + 1
end
end
elseif event.RRULE.FREQ == "YEARLY" then
end_time = event.RRULE.UNTIL
if not event.RRULE.UNTIL then
@@ -218,65 +300,32 @@ function calendar:get_tasks()
}
end
for i = start_time.year, end_time.year, 1 do
table.insert(tasks, {
date_start = {
year = i,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
date_end = {
year = i,
month = end_time.month,
day = end_time.day,
hour = end_time.hour or 0,
minute = end_time.min or 0,
second = end_time.sec or 0
},
summary = event.SUMMARY,
location = event.LOCATION,
description = event.DESCRIPTION,
url = event.URL.URL,
uid = event.UID
})
task_factory({ y = i, m = start_time.month, d = start_time.day, hour = start_time.hour,
min = start_time.min, sec = start_time.sec }, { y = i, m = end_time.month, d = end_time.day,
hour = end_time.hour, min = end_time.min, sec = end_time.sec }, event.SUMMARY,
event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
end
end
-- If RRULE is empty we just add a single day event
else
table.insert(tasks, {
date_start = {
year = start_time.year,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
date_end = {
year = start_time.year,
month = start_time.month,
day = start_time.day,
hour = start_time.hour or 0,
minute = start_time.min or 0,
second = start_time.sec or 0
},
summary = event.SUMMARY,
description = event.DESCRIPTION,
location = event.LOCATION,
url = event.URL,
uid = event.UID,
})
task_factory({ y = start_time.year, m = start_time.month, d = start_time.day, hour = start_time.hour,
min = start_time.min, sec = start_time.sec }, { y = end_time.year, m = end_time.month,
d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec },
event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ)
end
if event.VALARM then
-- send a notification 15 minutes before an event starts
-- send a notification X minutes before an event starts
end
end
end
--table.insert(calendars, tasks)
table.insert(self.tasks, tasks)
table.insert(self.calendars, {
tasks = self.tasks,
color = cal.color
})
end
table.insert(self.tasks, tasks)
end
---!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),
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 {
summary = task.summary,
description = task.description,
location = task.location,
url = task.url,
uid = task.uid,
date_start = task.date_start,
date_end = task.date_end,
} ]]
local function task_factory(task, bg)
return 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 = bg,
shape = Theme_config.calendar.task.shape,
forced_height = dpi(20),
widget = wibox.container.background
}
end
local task_info_widget = wibox.widget {
{
{ -- Task detail
{ -- Calendar color
widget = wibox.container.background,
shape = function(cr, _, height)
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
end,
},
{
{ -- Summary
widget = wibox.widget.textbox,
text = task.summary,
valign = "center",
align = "left",
id = "summary",
},
{ -- Date long
widget = wibox.widget.textbox,
text = task.date_long,
valign = "center",
align = "right",
id = "date_long",
},
{ -- From - To
widget = wibox.widget.textbox,
text = task.from_to,
valign = "center",
align = "left",
id = "from_to",
},
{ -- Repeat information
widget = wibox.widget.textbox,
text = task.repeat_info,
valign = "center",
align = "right",
id = "repeat_info",
},
layout = wibox.layout.fixed.vertical,
},
layout = wibox.layout.fixed.horizontal
},
{ -- Location
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "location.svg",
Theme_config.calendar.border_color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = task.location,
valign = "center",
align = "left",
id = "location",
},
id = "location_container",
layout = wibox.layout.fixed.horizontal
},
{ -- Alarm
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "alarm.svg", Theme_config.calendar.fg),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = task.alarm,
valign = "center",
align = "left",
id = "alarm",
},
id = "alarm_container",
layout = wibox.layout.fixed.horizontal
},
id = "task_detail",
layout = wibox.layout.fixed.vertical
},
bg = Theme_config.calendar.bg,
fg = Theme_config.calendar.fg,
shape = function(cr, _, height)
gshape.rounded_rect(cr, height, height, dpi(8))
end,
widget = wibox.container.background,
}
for _, cal in ipairs(self.calendars) do
for _, tasks in ipairs(cal.tasks) do
for _, task in ipairs(tasks) do
if (task.date_start.year == year) and (task.date_start.month == month) and (task.date_start.day == day) then
-- Check if task if before the current date
local tw
if task.date_start.year < self.date.year or
(task.date_start.year == self.date.year and task.date_start.month < self.date.month) or
(
task.date_start.year == self.date.year and task.date_start.month == self.date.month and
task.date_start.day < self.date.day) then
tw = task_factory(task, cal.color .. "55")
else
tw = task_factory(task, cal.color)
end
local task_popup = awful.popup {
widget = task_info_widget,
ontop = true,
visible = true,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = self.screen
}
local ti = task_info {
summary = task.summary,
description = task.description,
location = task.location,
url = task.url,
uid = task.uid,
date_start = task.date_start,
start_time = task.start_time,
date_end = task.date_end,
end_time = task.end_time,
freq = task.freq,
task = task,
color = cal.color,
}
tw:connect_signal("button::down", function()
--ti:toggle()
task_popup.visible = not task_popup.visible
end)
local task_popup = awful.popup {
widget = ti,
ontop = true,
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
return tasks_layout
end
@@ -749,10 +740,11 @@ end
function calendar.new(args)
args = args or {}
local ret = gobject { enable_properties = true, enable_auto_signals = true }
local ret = base.make_widget(nil, nil, { enable_properties = true })
gtable.crush(ret, calendar, true)
local calendar_widget = wibox.widget {
ret:set_widget(wibox.widget {
{
{
{
@@ -892,7 +884,7 @@ function calendar.new(args)
border_strategy = "inner",
fg = Theme_config.calendar.fg,
shape = Theme_config.calendar.shape,
}
})
ret:get_tasks()
@@ -901,109 +893,81 @@ function calendar.new(args)
ret:create_weekdays_widget()
ret:create_calendar_weeks_widget()
ret.widget = awful.popup {
widget = calendar_widget,
screen = args.screen,
ontop = true,
bg = "#00000000",
visible = false,
placement = function(c) awful.placement.align(c,
{ position = "top_right", margins = { right = dpi(10), top = dpi(65) } })
end
}
calendar_widget:get_children_by_id("add_ical")[1]:buttons(
gtable.join(
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
ret:get_widget():get_children_by_id("add_ical")[1]:buttons(gtable.join(
awful.button({}, 1, function()
awful.spawn.easy_async_with_shell(
"zenity --file-selection --title='Select an ICalendar file' --file-filter='iCalendar File | *.ics'",
function(path_to_file)
path_to_file = string.gsub(path_to_file, "\n", "")
if (not path_to_file) or (path_to_file == "") then return end
ical_parser:add_calendar(path_to_file)
ret:get_tasks()
ret:create_calendar_widget()
end
calendar_widget:get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
calendar_widget:get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
)
)
)
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
calendar_widget:get_children_by_id("month")[1].text = ret._private.months[ret.date.month]
calendar_widget:get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
)
)
)
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_widget:get_children_by_id("prev_year")[1]:buttons(
gtable.join(
awful.button({}, 1, function()
ret.date.year = ret.date.year - 1
calendar_widget:get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
)
)
ret:get_widget():get_children_by_id("prev_year")[1]:buttons(gtable.join(
awful.button({}, 1, function()
ret.date.year = ret.date.year - 1
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
))
--- Calendar switch year forward
calendar_widget:get_children_by_id("next_year")[1]:buttons(
gtable.join(
awful.button({}, 1, function()
ret.date.year = ret.date.year + 1
calendar_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_year")[1]:buttons(gtable.join(
awful.button({}, 1, function()
ret.date.year = ret.date.year + 1
ret:get_widget():get_children_by_id("year")[1].text = ret.date.year
ret:create_calendar_weeks_widget()
ret:create_calendar_widget()
end)
))
capi.awesome.connect_signal("calendar::toggle", function()
if capi.mouse.screen == args.screen then
ret.widget.visible = not ret.widget.visible
end
end)
return ret
end
function calendar.mt:__call(...)

View File

@@ -20,15 +20,24 @@ task_info._private = {}
function task_info.new(args)
args = args or {}
if not args.task then return end
args.screen = args.screen or awful.screen.focused()
local ret = gobject {}
gtable.crush(ret, task_info, true)
args.color = args.color or "#ffffff"
local date_long_written = os.date("%A, %d. %B %Y", os.time(args.date_start))
local from_to = os.date("%H:%M", os.time(args.date_start)) .. " - " .. os.date("%H:%M", os.time(args.date_end))
local task_info_widget = wibox.widget {
{
{
{
{ -- Task detail
{ -- Calendar color
widget = wibox.container.background,
bg = args.color,
forced_width = dpi(10),
shape = function(cr, _, height)
gshape.rounded_rect(cr, dpi(10), height, dpi(8))
end,
@@ -36,95 +45,109 @@ function task_info.new(args)
{
{ -- Summary
widget = wibox.widget.textbox,
text = ret.summary,
text = args.summary:sub(1, -2) or "NO SUMMARY",
valign = "center",
align = "left",
halign = "left",
id = "summary",
},
{ -- Date long
widget = wibox.widget.textbox,
text = ret.date_long,
text = date_long_written or "01.12.1970",
valign = "center",
align = "right",
halign = "right",
id = "date_long",
},
{ -- From - To
widget = wibox.widget.textbox,
text = ret.from_to,
text = from_to or "",
valign = "center",
align = "left",
halign = "left",
id = "from_to",
},
{ -- Repeat information
widget = wibox.widget.textbox,
text = ret.repeat_info,
text = args.freq or "0",
valign = "center",
align = "right",
halign = "left",
id = "repeat_info",
}, -- Year
{
widget = wibox.widget.textbox,
text = args.date_start.year or "1970",
valign = "center",
halign = "left",
id = "year",
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
},
spacing = dpi(20),
layout = wibox.layout.fixed.horizontal
},
widget = wibox.container.margin,
left = dpi(9)
},
{ -- Location
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "location.svg", Theme_config.calendar.task_info.location_icon_color),
image = gcolor.recolor_image(icondir .. "location.svg", args.color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = ret.location,
text = args.location:sub(1, -2) or "F303",
valign = "center",
align = "left",
halign = "left",
id = "location",
},
spacing = dpi(10),
id = "location_container",
layout = wibox.layout.fixed.horizontal
},
{ -- Alarm
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. "alarm.svg", Theme_config.calendar.task_info.alarm_icon_color),
image = gcolor.recolor_image(icondir .. "alarm.svg", args.color),
resize = false,
valign = "center",
halign = "center",
},
{
widget = wibox.widget.textbox,
text = ret.alarm,
text = args.alarm or "NO ALARM",
valign = "center",
align = "left",
halign = "left",
id = "alarm",
},
spacing = dpi(10),
id = "alarm_container",
layout = wibox.layout.fixed.horizontal
},
id = "task_detail",
spacing = dpi(15),
layout = wibox.layout.fixed.vertical
},
widget = wibox.container.margin,
left = dpi(6),
right = dpi(15),
top = dpi(15),
bottom = dpi(15),
},
bg = Theme_config.calendar.task_info.bg,
fg = Theme_config.calendar.task_info.fg,
shape = Theme_config.calendar.task_info.shape,
widget = wibox.container.background,
}
ret.widget = awful.popup {
widget = task_info_widget,
ontop = true,
visible = true,
bg = "#00000000",
x = capi.mouse.coords().x,
y = capi.mouse.coords().y,
screen = args.screen
}
ret.widget = task_info_widget
return ret.widget
end
function task_info.mt:__call(...)
task_info.new(...)
return task_info.new(...)
end
return setmetatable(task_info, task_info.mt)

View File

@@ -0,0 +1,214 @@
---------------------------------------
-- This is the brightness_osd module --
---------------------------------------
-- Awesome Libs
local awful = require("awful")
local abutton = awful.button
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears.table")
local base = require("wibox.widget.base")
local wibox = require("wibox")
local gfilesystem = require("gears.filesystem")
local gobject = require("gears.object")
local gcolor = require("gears.color")
local gtimer = require("gears.timer")
local capi = {
awesome = awesome,
mouse = mouse
}
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/"
local context_menu = {
mt = {}
}
function context_menu:layout(_, width, height)
if self._private.widget then
return {
base.place_widget_at(self._private.widget, 0, 0, width, height)
}
end
end
function context_menu:fit(context, width, height)
local w, h = 0, 0
if self._private.widget then
w, h = base.fit_widget(self, context, self._private.widget, width, height)
end
return w, h
end
context_menu.set_widget = base.set_widget_common
function context_menu:make_entries(wtemplate, entries, spacing)
local menu_entries = {
layout = wibox.layout.fixed.vertical,
spacing = spacing
}
if not wtemplate then
return
end
for _, entry in ipairs(entries) do
-- TODO: Figure out how to make a new widget from etemplate
local menu_entry = wibox.widget {
{
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role"
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal
},
nil,
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "arrow_role"
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
layout = wibox.layout.align.horizontal
},
margins = dpi(5),
widget = wibox.container.margin
},
bg = Theme_config.desktop.context_menu.entry_bg,
fg = Theme_config.desktop.context_menu.entry_fg,
widget = wibox.container.background
}
Hover_signal(menu_entry)
menu_entry:get_children_by_id("icon_role")[1].image = entry.icon
menu_entry:get_children_by_id("text_role")[1].text = entry.name
if entry.submenu then
menu_entry:get_children_by_id("arrow_role")[1].image =
gcolor.recolor_image(icondir .. "entry.svg", Theme_config.desktop.context_menu.entry_fg)
end
gtable.crush(menu_entry, entry, true)
menu_entry:buttons(gtable.join {
abutton({
modifiers = {},
button = 1,
on_release = function()
if not entry.submenu then
entry.callback()
end
self.visible = false
end
})
})
if entry.submenu then
menu_entry.popup = awful.popup {
widget = self:make_entries(wtemplate, entry.submenu, spacing),
bg = Theme_config.desktop.context_menu.bg,
ontop = true,
fg = Theme_config.desktop.context_menu.fg,
border_width = Theme_config.desktop.context_menu.border_width,
border_color = Theme_config.desktop.context_menu.border_color,
shape = Theme_config.desktop.context_menu.shape,
visible = false
}
local hide_timer = gtimer {
timeout = 0.1,
autostart = false,
single_shot = true,
callback = function()
menu_entry.popup.visible = false
end
}
menu_entry:connect_signal("mouse::enter", function()
-- place widget right of parent
menu_entry.popup:move_next_to(capi.mouse.current_widget_geometry)
hide_timer:stop()
menu_entry.popup.visible = true
end)
menu_entry.popup:connect_signal("mouse::leave", function()
hide_timer:again()
end)
menu_entry.popup:connect_signal("mouse::enter", function()
hide_timer:stop()
end)
menu_entry:connect_signal("mouse::leave", function()
hide_timer:again()
end)
capi.awesome.connect_signal("submenu::close", function()
menu_entry.popup.visible = false
end)
end
table.insert(menu_entries, menu_entry)
end
return menu_entries
end
function context_menu:toggle()
self.x = capi.mouse.coords().x
self.y = capi.mouse.coords().y
self.visible = not self.visible
end
function context_menu.new(args)
args = args or {}
local ret = {}
gtable.crush(ret, context_menu, true)
ret = awful.popup {
widget = ret:make_entries(args.widget_template, args.entries, args.spacing),
bg = Theme_config.desktop.context_menu.bg,
fg = Theme_config.desktop.context_menu.fg,
ontop = true,
border_width = Theme_config.desktop.context_menu.border_width,
border_color = Theme_config.desktop.context_menu.border_color,
shape = Theme_config.desktop.context_menu.shape,
visible = false,
x = capi.mouse.coords().x + 10,
y = capi.mouse.coords().y - 10
}
gtable.crush(ret, context_menu, true)
return ret
end
function context_menu.mt:__call(...)
return context_menu.new(...)
end
return setmetatable(context_menu, context_menu.mt)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,129 @@
--------------------------------------------------------------------------------------------------------------
-- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen --
--------------------------------------------------------------------------------------------------------------
local wibox = require("wibox")
local dpi = require("beautiful").xresources.apply_dpi
local gshape = require("gears.shape")
return function(s)
---Lookup function to return the widget from its easy name string
---@param widgets table
---@return widget
local function get_widgets(widgets)
local widget_table = {}
if widgets then
for _, widget in ipairs(widgets) do
if widget == "Audio" then
table.insert(widget_table, require("src.widgets.audio")(s))
elseif widget == "Battery" then
table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind))
elseif widget == "Bluetooth" then
table.insert(widget_table, require("src.widgets.bluetooth")())
elseif widget == "Clock" then
table.insert(widget_table, require("src.widgets.clock")())
elseif widget == "Cpu Frequency" then
table.insert(widget_table, require("src.widgets.cpu_info")("freq", User_config.cpu_frequency))
elseif widget == "Cpu Temperature" then
table.insert(widget_table, require("src.widgets.cpu_info")("temp"))
elseif widget == "Cpu Usage" then
table.insert(widget_table, require("src.widgets.cpu_info")("usage"))
elseif widget == "Date" then
table.insert(widget_table, require("src.widgets.date")())
elseif widget == "Gpu Temperature" then
table.insert(widget_table, require("src.widgets.gpu_info")("temp"))
elseif widget == "Gpu Usage" then
table.insert(widget_table, require("src.widgets.gpu_info")("usage"))
elseif widget == "Keyboard Layout" then
table.insert(widget_table, require("src.widgets.kblayout")(s))
elseif widget == "Tiling Layout" then
table.insert(widget_table, require("src.widgets.layout_list")())
elseif widget == "Network" then
table.insert(widget_table, require("src.widgets.network")())
elseif widget == "Power Button" then
table.insert(widget_table, require("src.widgets.power")())
elseif widget == "Ram Usage" then
table.insert(widget_table, require("src.widgets.ram_info")())
elseif widget == "Systray" then
table.insert(widget_table, require("src.widgets.systray")(s))
elseif widget == "Taglist" then
table.insert(widget_table, require("src.widgets.taglist")(s))
elseif widget == "Tasklist" then
table.insert(widget_table, require("src.widgets.tasklist")(s))
end
end
end
return widget_table
end
if User_config.crylia_wibox then
for index, screen in ipairs(User_config.crylia_wibox) do
if index == s.index then
local function prepare_widgets(widgets)
local layout = {
forced_height = dpi(50),
layout = wibox.layout.fixed.horizontal
}
for i, widget in pairs(widgets) do
if i == 1 then
table.insert(layout,
{
widget,
left = dpi(6),
right = dpi(3),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
elseif i == #widgets then
table.insert(layout,
{
widget,
left = dpi(3),
right = dpi(6),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
else
table.insert(layout,
{
widget,
left = dpi(3),
right = dpi(3),
top = dpi(6),
bottom = dpi(6),
widget = wibox.container.margin
})
end
end
return layout
end
local w = wibox {
widget = {
prepare_widgets(get_widgets(screen.left_bar)),
prepare_widgets(get_widgets(screen.center_bar)),
prepare_widgets(get_widgets(screen.right_bar)),
layout = wibox.layout.align.horizontal,
},
visible = true,
x = 0,
y = 1035,
type = "desktop",
height = dpi(55),
width = 1920,
bg = "#212121",
shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, 8)
end,
}
w:struts {
bottom = dpi(55)
}
Global_config.bottom_struts = dpi(55)
end
end
end
end

View File

@@ -0,0 +1,54 @@
local base = require("wibox.widget.base")
local awful = require("awful")
local gtable = require("gears.table")
local gfilesystem = require("gears.filesystem")
local gcolor = require("gears.color")
local wibox = require("wibox")
local dpi = require("beautiful").xresources.apply_dpi
local gobject = require("gears.object")
local cm = require("src.modules.context_menu.init")
local capi = {
awesome = awesome
}
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
local context_menu = { mt = {} }
context_menu._private = {}
function context_menu:toggle()
self._private.popup.x = mouse.coords().x - 10
self._private.popup.y = mouse.coords().y - 10
self._private.popup.visible = not self._private.popup.visible
end
function context_menu.new(args)
args = args or {}
local ret = gobject {}
gtable.crush(ret, context_menu, true)
capi.awesome.connect_signal("context_menu:show", function()
ret:toggle()
mousegrabber.run(function()
if mouse.current_wibox ~= ret._private.popup then
ret:toggle()
return false
end
return true
end, nil)
end)
return w
end
function context_menu.mt:__call(...)
return context_menu.new(...)
end
return setmetatable(context_menu, context_menu.mt)

View File

@@ -0,0 +1,605 @@
local base = require("wibox.widget.base")
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears.table")
local gshape = require("gears.shape")
local grid = require("wibox.layout.grid")
local wibox = require("wibox")
local abutton = require("awful.button")
local awful = require("awful")
local gcolor = require("gears.color")
local json = require("src.lib.json-lua.json-lua")
local gfilesystem = require("gears.filesystem")
local Gio = require("lgi").Gio
local element = require("src.modules.desktop.element")
local cm = require("src.modules.context_menu.init")
local capi = {
mouse = mouse,
awesome = awesome
}
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
local desktop = { mt = {} }
function desktop:save_layout()
local layout = {}
local dir = gfilesystem.get_configuration_dir() .. "src/config/files/desktop/icons/"
if not gfilesystem.dir_readable(dir) then
gfilesystem.make_directories(dir)
end
for i, widget in ipairs(self.widget.mrgn.grid.children) do
local pos = self.widget.mrgn.grid:get_widget_position(widget)
layout[i] = {
row = pos.row,
col = pos.col,
widget = {
icon = widget.icon,
label = widget:get_children_by_id("text_role")[1].text,
exec = widget.exec,
icon_size = widget.icon_size
}
}
end
local dir = gfilesystem.get_configuration_dir() .. "src/config"
gfilesystem.make_directories(dir)
if not gfilesystem.file_readable(dir .. "/desktop.json") then
os.execute("touch " .. dir .. "/desktop.json")
end
local handler = io.open(dir .. "/desktop.json", "w")
if not handler then return end
handler:write(json:encode(layout))
handler:close()
end
function desktop:load_layout()
local dir = gfilesystem.get_configuration_dir() .. "src/config"
if not gfilesystem.file_readable(dir .. "/desktop.json") then
return
end
local handler = io.open(dir .. "/desktop.json", "r")
if not handler then return end
local layout = json:decode(handler:read("*all"))
handler:close()
if not layout then return end
for i, value in pairs(layout) do
self:add_element(value.widget, { x = value.row, y = value.col })
end
end
function desktop:get_element_at(x, y)
return self.widget.mrgn.grid:get_widgets_at(x, y)[1]
end
function desktop:add_desktop_file(app_info)
self:add_element({
icon = app_info.icon,
label = app_info.label,
exec = app_info.exec,
icon_size = dpi(96),
desktop_file = app_info.desktop_file,
parent = self.widget.mrgn.grid,
})
end
--[[
Removes a given widget and returns it
]]
function desktop:remove_element(e)
return (self.widget.mrgn.grid:remove(e) and e) or nil
end
function desktop:get_grid_index_at(y, x)
local col, row = 1, 1
local width = dpi(96) * 1.75 * (4 / 3)
local height = dpi(96) * 1.75
local spacing = dpi(10)
while width * col + spacing * (col - 1) < x do
col = col + 1
end
while height * row + spacing * (row - 1) < y do
row = row + 1
end
return col, row
end
---Main function to add an element to the desktop
---it will automatically place it on an empty spot and save it
---@param args table widget arguments
---@param pos table|nil {x = , y = }
function desktop:add_element(args, pos)
-- add into next available position
local x, y = self.widget.mrgn.grid:get_next_empty()
if pos then
x = pos.x
y = pos.y
end
local e = element {
icon = args.icon,
label = args.label,
exec = args.exec,
icon_size = args.icon_size,
desktop_file = args.desktop_file,
parent = args.parent
}
local cm_popup = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
layout = wibox.layout.fixed.horizontal
},
widget = wibox.container.margin
},
widget = wibox.container.background,
},
spacing = dpi(10),
entries = {
{
name = "Open with",
icon = gcolor.recolor_image(icondir .. "launch.svg", Theme_config.desktop.context_menu.icon_color),
submenu = {
--!TODO: Fetch programs and add them as entries
}
},
{
name = "Copy",
icon = gcolor.recolor_image(icondir .. "copy.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
name = "Cut",
icon = gcolor.recolor_image(icondir .. "cut.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
name = "Rename",
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
name = "Remove",
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
self:remove_element(e)
self:save_layout()
end
},
{
name = "Actions",
icon = gcolor.recolor_image(icondir .. "dots-vertical.svg", Theme_config.desktop.context_menu.icon_color),
submenu = {
-- TODO: fetch actions from desktop file
}
},
}
}
cm_popup:connect_signal("mouse::leave", function()
cm_popup.visible = false
end)
-- While the mouse is down, remove the element from the grid and add it to manual then move it
-- until the mouse is released and then add it back to the grid.
e:connect_signal("button::press", function(_, _, _, b)
local start_pos = mouse.coords()
if not mousegrabber.isrunning() then
local width = args.icon_size * 1.75 * (4 / 3)
local height = args.icon_size * 1.75
local dnd_widget = element {
icon = args.icon,
label = args.label,
on_click = args.on_click,
icon_size = args.icon_size,
parent = args.parent,
width = width,
height = height,
}
dnd_widget.visible = false
dnd_widget:get_children_by_id("icon_role")[1].opacity = 0.6
local xp, yp = capi.mouse.coords()
dnd_widget.point = { x = xp, y = yp }
local old_pos = self.widget.mrgn.grid:get_widget_position(e)
self.widget.manual:add(dnd_widget)
mousegrabber.run(function(m)
if (math.abs(m.x - start_pos.x) > 10 or
math.abs(m.x - start_pos.x) < -10 or
math.abs(m.y - start_pos.y) > 10 or
math.abs(m.y - start_pos.y) < -10) and
m.buttons[1] then
self:remove_element(e)
dnd_widget.visible = true
dnd_widget.bg = gcolor("#0ffff088")
dnd_widget.border_color = gcolor("#0ffff0")
self.widget.manual:move_widget(dnd_widget, { x = m.x - dnd_widget.width / 2, y = m.y - dnd_widget.height / 2 })
end
if not m.buttons[1] then
if b == 1 then
dnd_widget.bg = gcolor("#0ffff088")
dnd_widget.border_color = gcolor("#0ffff0")
if dnd_widget.visible then
dnd_widget.visible = false
local np_x, np_y = self:get_grid_index_at(m.y, m.x)
if not self.widget.mrgn.grid:get_widgets_at(np_y, np_x) then
self.widget.mrgn.grid:add_widget_at(e, np_y, np_x)
self:save_layout()
else
self.widget.mrgn.grid:add_widget_at(e, old_pos.row, old_pos.col)
end
else
Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(e.exec, nil, 0))
self.widget.manual:reset()
end
mousegrabber.stop()
elseif b == 3 then
cm_popup:toggle()
mousegrabber.stop()
end
end
return m.buttons[1]
end, "left_ptr")
end
end)
self.widget.mrgn.grid:add_widget_at(e, x, y)
self:save_layout()
end
function desktop:draw_selector()
local start_pos = mouse.coords()
if not mousegrabber.isrunning() then
local selector = wibox.widget {
widget = wibox.container.background,
bg = gcolor("#0ffff088"),
border_color = gcolor("#0ffff0"),
border_width = dpi(2),
width = 100,
height = 100,
visible = true,
shape = function(cr, w, h)
gshape.rounded_rect(cr, w, h, dpi(10))
end
}
local coords = capi.mouse.coords()
selector.point = { x = coords.x, y = coords.y }
self.widget.manual:add(selector)
mousegrabber.run(function(m)
if m.buttons[1] then
selector.visible = true
end
if not m.buttons[1] then
mousegrabber.stop()
selector.visible = false
self.widget.manual:reset()
end
end, "left_ptr")
end
end
function desktop:add_xdg()
self:add_element({
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg",
label = "Papierkorb",
exec = "nautilus trash:/",
icon_size = 96,
})
self:add_element({
icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg",
label = "Persönlicher Ordner",
exec = "nautilus file:/home/crylia",
icon_size = 96,
})
end
function desktop.new(args)
args = args or {}
args.screen = args.screen or awful.screen.focused()
local icon_size = args.icon_size or dpi(96)
-- calculate the row and column count based on the screen size and icon size and aspect ratio of 16:9
local screen_width = awful.screen.focused().geometry.width
local screen_height = awful.screen.focused().geometry.height
local aspect_ratio = 4 / 3
local cols = math.floor(screen_width / (icon_size * 1.75 * aspect_ratio))
local rows = math.floor((screen_height - (dpi(75 + 95))) / (icon_size * 1.75))
--[[
The wibox has a stacked layout with a manual layout over a grid.
stacked
manual
grid
manual: For positioning the dragged element since this layout allows for arbitrary positioning.
grid: For positioning the elements in a grid.
]]
local w = wibox {
ontop = false,
visible = true,
type = "desktop",
input_passthrough = false,
x = 0,
y = 0,
bg = gcolor.transparent,
width = 1920,
height = 1080,
screen = args.screen,
widget = wibox.widget {
{
{
layout = grid,
homogeneous = true,
spacing = dpi(10),
expand = true,
orientation = "horizontal",
forced_num_cols = cols,
forced_num_rows = rows,
id = "grid",
},
widget = wibox.container.margin,
left = dpi(10),
right = dpi(10),
top = dpi(75),
bottom = dpi(95),
id = "mrgn"
},
{
layout = wibox.layout.manual,
id = "manual",
},
layout = wibox.layout.stack,
}
}
local cm_popup = cm {
widget_template = wibox.widget {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
valign = "center",
halign = "center",
id = "icon_role",
},
widget = wibox.container.constraint,
stragety = "exact",
width = dpi(24),
height = dpi(24),
id = "const"
},
{
widget = wibox.widget.textbox,
valign = "center",
halign = "left",
id = "text_role"
},
layout = wibox.layout.fixed.horizontal
},
widget = wibox.container.margin
},
widget = wibox.container.background,
},
spacing = dpi(10),
entries = {
{
name = "Create new",
icon = gcolor.recolor_image(icondir .. "file_add.svg", Theme_config.desktop.context_menu.icon_color),
submenu = {
{
name = "Folder",
icon = gcolor.recolor_image(icondir .. "folder.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
--create a new folder and if it exists add a number to the end
local folder_name = "New folder"
local folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
local i = 1
while gfilesystem.dir_readable(folder_path) do
folder_name = "New folder " .. "(" .. i .. ")"
folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name
i = i + 1
end
gfilesystem.make_directories(folder_path)
w:add_element({
icon = "/usr/share/icons/Papirus-Dark/24x24/places/folder.svg",
label = folder_name,
exec = "nautilus file:\"" .. folder_path .. "\"",
icon_size = icon_size,
})
end
},
{
name = "File",
icon = gcolor.recolor_image(icondir .. "file.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
--create new text file and if it exists add a number to the end
local file_name = "New file.txt"
local file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
local i = 1
while gfilesystem.file_readable(file_path) do
file_name = "New file " .. "(" .. i .. ")"
file_path = os.getenv("HOME") .. "/Desktop/" .. file_name
i = i + 1
end
awful.spawn.with_shell("touch " .. file_path)
w:add_element({
icon = "/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg",
label = file_name,
exec = "xdg-open " .. file_path,
icon_size = icon_size,
})
end
}
}
},
{
name = "Terminal",
icon = gcolor.recolor_image(icondir .. "terminal.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.terminal)
end
},
{
name = "Web Browser",
icon = gcolor.recolor_image(icondir .. "web_browser.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.web_browser)
end
},
{
name = "File Manager",
icon = gcolor.recolor_image(icondir .. "file_manager.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.file_manager)
end
},
{
name = "Text Editor",
icon = gcolor.recolor_image(icondir .. "text_editor.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.text_editor)
end
},
{
name = "Music Player",
icon = gcolor.recolor_image(icondir .. "music_player.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.music_player)
end
},
{
name = "Applications",
icon = gcolor.recolor_image(icondir .. "application.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
end
},
{
name = "GTK Settings",
icon = gcolor.recolor_image(icondir .. "gtk_settings.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.gtk_settings)
end
},
{
name = "Energy Settings",
icon = gcolor.recolor_image(icondir .. "energy_settings.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.energy_manager)
end
},
{
name = "Screen Settings",
icon = gcolor.recolor_image(icondir .. "screen_settings.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
awful.spawn(User_config.screen_settings)
end
},
{
name = "Reload Awesome",
icon = gcolor.recolor_image(icondir .. "refresh.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
capi.awesome.restart()
end
},
{
name = "Quit",
icon = gcolor.recolor_image(icondir .. "quit.svg", Theme_config.desktop.context_menu.icon_color),
callback = function()
capi.awesome.quit()
end
},
--cm_awesome
}
}
w.widget.manual:buttons(
gtable.join(
awful.button(
{},
1,
function()
cm_popup.visible = false
if capi.mouse.current_widgets[4] == w.widget.manual then
--w:draw_selector()
end
end
),
awful.button(
{},
3,
function()
if capi.mouse.current_widgets[4] == w.widget.manual then
cm_popup:toggle()
end
end
)
)
)
gtable.crush(w, desktop, true)
w:load_layout()
capi.awesome.connect_signal("desktop::add_to_desktop", function(args2)
w:add_desktop_file(args2)
end)
return w
end
function desktop.mt:__call(...)
return desktop.new(...)
end
return setmetatable(desktop, desktop.mt)

View File

@@ -0,0 +1,119 @@
local base = require("wibox.widget.base")
local wibox = require("wibox")
local gtable = require("gears.table")
local dpi = require("beautiful").xresources.apply_dpi
local gshape = require("gears.shape")
local gfilesystem = require("gears.filesystem")
local gcolor = require("gears.color")
local abutton = require("awful.button")
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/"
local capi = {
mouse = mouse
}
local element = { mt = {} }
function element:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
function element:fit(context, width, height)
local w, h = 0, 0
if self._private.widget then
w, h = base.fit_widget(self, context, self._private.widget, width, height)
end
return w, h
end
function element:get_widget()
return self._private.widget
end
function element:on_hover()
self:connect_signal("mouse::enter", function()
self.bg = "#0ffff033"
self.border_color = "#0ffff099"
end)
self:connect_signal("mouse::leave", function()
self.bg = gcolor.transparent
self.border_color = gcolor.transparent
end)
self:connect_signal("button::press", function()
self.bg = "#0ffff088"
self.border_color = "#0ffff0dd"
end)
self:connect_signal("button::release", function()
self.bg = "#0ffff033"
self.border_color = "#0ffff099"
end)
end
function element.new(args)
args = args or {}
local w = base.make_widget_from_value(wibox.widget {
{
{
{
{
image = args.icon,
resize = true,
clip_shape = gshape.rounded_rect,
valign = "center",
halign = "center",
id = "icon_role",
widget = wibox.widget.imagebox
},
strategy = "exact",
height = args.icon_size,
width = args.icon_size,
widget = wibox.container.constraint
},
{
text = args.label,
id = "text_role",
valign = "center",
halign = "center",
widget = wibox.widget.textbox
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
widget = wibox.container.place,
valign = "center",
halign = "center"
},
fg = "#ffffff",
bg = gcolor.transparent,
border_color = gcolor.transparent,
border_width = dpi(2),
shape = gshape.rounded_rect,
forced_width = args.width,
forced_height = args.height,
width = args.width,
height = args.height,
exec = args.exec,
icon_size = args.icon_size,
icon = args.icon,
widget = wibox.container.background
})
gtable.crush(w, element, true)
w:on_hover()
return w
end
function element.mt:__call(...)
return element.new(...)
end
return setmetatable(element, element.mt)

View File

@@ -17,16 +17,20 @@ awful.screen.connect_for_each_screen(
User_config.layouts[1]
)
require("src.modules.powermenu")(s)
require("src.modules.volume_osd")(s)
require("src.modules.brightness_osd")(s)
require("src.modules.desktop.context_menu") { screen = s }
require("src.modules.desktop.desktop") { screen = s }
require("src.modules.powermenu.powermenu")(s)
require("src.modules.audio.volume_osd") { screen = s }
--require("src.modules.audio.volume_controller") { screen = s }
require("src.modules.brightness.brightness_osd")(s)
require("src.modules.bluetooth.init") { screen = s }
require("src.modules.titlebar")
require("src.modules.volume_controller")(s)
require("src.modules.titlebar.titlebar")
require("src.modules.crylia_bar.init")(s)
--require("src.modules.crylia_wibox.init")(s)
require("src.modules.notification-center.init")(s)
require("src.modules.window_switcher.init")(s)
require("src.modules.application_launcher.init")(s)
require("src.modules.calendar.init") { screen = s }
require("src.modules.application_launcher.init") { screen = s }
--require("src.modules.calendar.init") { screen = s }
require("src.modules.network_controller.init") { screen = s }
end
)

View File

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

View File

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

View File

@@ -4,113 +4,657 @@
-- Awesome Libs
local awful = require("awful")
local dbus_proxy = require("dbus_proxy")
local dpi = require("beautiful").xresources.apply_dpi
local gtable = require("gears").table
local gtimer = require("gears").timer
local gshape = require("gears").shape
local gobject = require("gears").object
local gcolor = require("gears").color
local gears = require("gears")
local lgi = require("lgi")
local wibox = require("wibox")
local NM = require("lgi").NM
local rubato = require("src.lib.rubato")
local access_point = require("src.modules.network_controller.access_point")
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/network/"
return function(s)
local capi = {
awesome = awesome,
}
local function get_connected_network()
local network = { mt = {} }
network.access_points = { layout = wibox.layout.fixed.vertical }
network.NMState = {
UNKNOWN = 0,
ASLEEP = 10,
DISCONNECTED = 20,
DISCONNECTING = 30,
CONNECTING = 40,
CONNECTED_LOCAL = 50,
CONNECTED_SITE = 60,
CONNECTED_GLOBAL = 70,
}
network.DeviceType = {
ETHERNET = 1,
WIFI = 2
}
network.DeviceState = {
UNKNOWN = 0,
UNMANAGED = 10,
UNAVAILABLE = 20,
DISCONNECTED = 30,
PREPARE = 40,
CONFIG = 50,
NEED_AUTH = 60,
IP_CONFIG = 70,
IP_CHECK = 80,
SECONDARIES = 90,
ACTIVATED = 100,
DEACTIVATING = 110,
FAILED = 120
}
local function flags_to_security(flags, wpa_flags, rsn_flags)
local str = ""
if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then
str = str .. " WEP"
end
if wpa_flags ~= 0 then
str = str .. " WPA1"
end
if not rsn_flags ~= 0 then
str = str .. " WPA2"
end
if wpa_flags == 512 or rsn_flags == 512 then
str = str .. " 802.1X"
end
local network_controller = wibox.widget {
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",
widget = wibox.widgeet.textbox
{
resize = false,
image = gcolor.recolor_image(icondir .. "menu-down.svg",
Theme_config.network_manager.wifi_icon_color),
widget = wibox.widget.imagebox,
valign = "center",
halign = "center",
id = "icon"
},
id = "center",
halign = "center",
valign = "center",
widget = wibox.container.place,
},
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)
gears.shape.rounded_rect(cr, width, height, dpi(5))
gshape.rounded_rect(cr, width, height, dpi(4))
end,
widget = wibox.container.background
},
id = "wifi_margin",
widget = wibox.container.margin
},
{ -- Refresh button
{
id = "wifi_list",
{
{
{
-- TODO: Replace with image
text = "Refresh",
widget = wibox.widgeet.textbox
},
widget = wibox.container.margin
step = dpi(50),
spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0,
id = "wifi_ap_list"
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(5))
end,
widget = wibox.container.background
id = "margin",
margins = dpi(10),
widget = wibox.container.margin
},
widget = wibox.container.margin
border_color = Theme_config.network_manager.ap_border_color,
border_width = Theme_config.network_manager.ap_border_width,
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),
widget = wibox.container.margin
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(8))
end,
border_color = Theme_config.network_manager.border_color,
border_width = Theme_config.network_manager.border_width,
bg = Theme_config.network_manager.bg,
id = "background",
widget = wibox.container.background
},
width = dpi(400),
strategy = "exact",
widget = wibox.container.constraint
}
local network_controller_container = awful.popup {
widget = wibox.container.background,
bg = Theme_config.network_controller.bg,
border_color = Theme_config.network_controller.border_color,
border_width = Theme_config.network_controller.border_width,
screen = s,
local refresh_button = network_widget:get_children_by_id("refresh")[1]
refresh_button:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
ret:scan_access_points()
end
)
)
)
Hover_signal(refresh_button)
local airplane_button = network_widget:get_children_by_id("airplane")[1]
airplane_button:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
if ret:toggle_wireless() then
airplane_button.center.icon.image = gcolor.recolor_image(icondir
.. "airplane-off.svg",
Theme_config.network_manager.airplane_icon_color)
else
airplane_button.center.icon.image = gcolor.recolor_image(icondir
.. "airplane-on.svg",
Theme_config.network_manager.airplane_icon_color)
end
ret:scan_access_points()
end
)
)
)
Hover_signal(airplane_button)
local wifi_margin = network_widget:get_children_by_id("wifi_margin")[1]
local wifi_list = network_widget:get_children_by_id("wifi_list")[1]
local wifi = network_widget:get_children_by_id("wifi")[1].center
local rubato_timer = rubato.timed {
duration = 0.2,
pos = wifi_list.forced_height,
easing = rubato.linear,
subscribed = function(v)
wifi_list.forced_height = v
end
}
wifi_margin:buttons(
gtable.join(
awful.button(
{},
1,
nil,
function()
if wifi_list.forced_height == 0 then
local size = (#ret.access_points * 49) + 1
size = size > 210 and 210 or size
rubato_timer.target = dpi(size)
wifi_margin.wifi_bg.shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
end
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg",
Theme_config.network_manager.wifi_icon_color))
else
rubato_timer.target = 0
wifi_margin.wifi_bg.shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4))
end
wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg",
Theme_config.network_manager.wifi_icon_color))
end
end
)
)
)
ret.widget = awful.popup {
widget = network_widget,
bg = Theme_config.network_manager.bg,
screen = args.screen,
stretch = false,
visible = false,
ontop = true,
@@ -122,9 +666,22 @@ return function(s)
end
}
network_controller_container:setup {
network_controller,
layout = wibox.layout.fixed.vertical
}
capi.awesome.connect_signal("NM::toggle_container", function()
ret.widget.visible = not ret.widget.visible
ret:scan_access_points()
end)
capi.awesome.connect_signal("NM::toggle_wifi", function()
ret:toggle_wireless()
end)
ret:connect_signal("NM::AccessPointsFound", function(tab)
network_widget:get_children_by_id("wifi_ap_list")[1].children = ret.access_points
end)
end
function network.mt:__call(...)
return network.new(...)
end
return setmetatable(network, network.mt)

View File

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

View File

@@ -0,0 +1,249 @@
--------------------------------
-- This is the network widget --
--------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local capi = {
awesome = awesome,
mouse = mouse,
}
-- Icon directory path
local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/powermenu/"
return function(s)
-- Profile picture imagebox
local profile_picture = wibox.widget {
image = icondir .. "defaultpfp.svg",
resize = true,
forced_height = dpi(200),
clip_shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(30))
end,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox
}
-- Username textbox
local profile_name = wibox.widget {
align = 'center',
valign = 'center',
text = " ",
font = "JetBrains Mono Bold 30",
widget = wibox.widget.textbox
}
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
-- and copy it to the assets folder
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
local update_profile_picture = function()
awful.spawn.easy_async_with_shell(
"./.config/awesome/src/scripts/pfp.sh 'userPfp'",
function(stdout)
if stdout then
profile_picture:set_image(stdout:gsub("\n", ""))
else
profile_picture:set_image(icondir .. "defaultpfp.svg")
end
end
)
end
update_profile_picture()
-- Get the full username(if set) and the username + hostname
local update_user_name = function()
awful.spawn.easy_async_with_shell(
"./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'",
function(stdout)
if stdout:gsub("\n", "") == "Rick Astley" then
profile_picture:set_image(gears.filesystem.get_configuration_dir() .. "src/assets/userpfp/" .. "rickastley.jpg")
end
profile_name:set_text(stdout)
end
)
end
update_user_name()
-- Universal Button widget
local button = function(name, icon, bg_color, callback)
local item = wibox.widget {
{
{
{
{
-- TODO: using gears.color to recolor a SVG will make it look super low res
-- currently I recolor it in the .svg file directly, but later implement
-- a better way to recolor a SVG
image = icon,
resize = true,
forced_height = dpi(30),
valign = "center",
halign = "center",
widget = wibox.widget.imagebox
},
{
text = name,
font = "JetBrains Mono Bold 30",
widget = wibox.widget.textbox
},
widget = wibox.layout.fixed.horizontal
},
margins = dpi(10),
widget = wibox.container.margin
},
fg = Theme_config.powermenu.button_fg,
bg = bg_color,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(10))
end,
widget = wibox.container.background,
id = 'background'
},
layout = wibox.layout.align.vertical
}
item:connect_signal(
"button::release",
function()
callback()
end
)
return item
end
-- Create the power menu actions
local suspend_command = function()
awful.spawn("systemctl suspend")
capi.awesome.emit_signal("module::powermenu:hide")
end
local logout_command = function()
capi.awesome.quit()
end
local lock_command = function()
awful.spawn("dm-tool lock")
capi.awesome.emit_signal("module::powermenu:hide")
end
local shutdown_command = function()
awful.spawn("shutdown now")
capi.awesome.emit_signal("module::powermenu:hide")
end
local reboot_command = function()
awful.spawn("reboot")
capi.awesome.emit_signal("module::powermenu:hide")
end
-- Create the buttons with their command and name etc
local shutdown_button = button("Shutdown", icondir .. "shutdown.svg", Theme_config.powermenu.shutdown_button_bg,
shutdown_command)
local reboot_button = button("Reboot", icondir .. "reboot.svg", Theme_config.powermenu.reboot_button_bg, reboot_command)
local suspend_button = button("Suspend", icondir .. "suspend.svg", Theme_config.powermenu.suspend_button_bg,
suspend_command)
local logout_button = button("Logout", icondir .. "logout.svg", Theme_config.powermenu.logout_button_bg, logout_command)
local lock_button = button("Lock", icondir .. "lock.svg", Theme_config.powermenu.lock_button_bg, lock_command)
-- Signals to change color on hover
Hover_signal(shutdown_button.background)
Hover_signal(reboot_button.background)
Hover_signal(suspend_button.background)
Hover_signal(logout_button.background)
Hover_signal(lock_button.background)
-- The powermenu widget
local powermenu = wibox.widget {
{
{
profile_picture,
profile_name,
spacing = dpi(50),
layout = wibox.layout.fixed.vertical
},
{
{
shutdown_button,
reboot_button,
logout_button,
lock_button,
suspend_button,
spacing = dpi(30),
layout = wibox.layout.fixed.horizontal
},
halign = "center",
valign = "center",
widget = wibox.container.place
},
layout = wibox.layout.fixed.vertical
},
halign = "center",
valign = "center",
widget = wibox.container.place
}
-- Container for the widget, covers the entire screen
local powermenu_container = wibox {
widget = powermenu,
screen = s,
type = "splash",
visible = false,
ontop = true,
bg = Theme_config.powermenu.container_bg,
height = s.geometry.height,
width = s.geometry.width,
x = s.geometry.x,
y = s.geometry.y
}
-- Close on rightclick
powermenu_container:buttons(
gears.table.join(
awful.button(
{},
3,
function()
capi.awesome.emit_signal("module::powermenu:hide")
end
)
)
)
-- Close on Escape
local powermenu_keygrabber = awful.keygrabber {
autostart = false,
stop_event = 'release',
keypressed_callback = function(self, mod, key, command)
if key == 'Escape' then
capi.awesome.emit_signal("module::powermenu:hide")
end
end
}
-- Signals
capi.awesome.connect_signal(
"module::powermenu:show",
function()
if s == capi.mouse.screen then
powermenu_container.visible = true
powermenu_keygrabber:start()
end
end
)
capi.awesome.connect_signal(
"module::powermenu:hide",
function()
powermenu_keygrabber:stop()
powermenu_container.visible = false
end
)
end

View File

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