Compare commits

...

10 Commits

Author SHA1 Message Date
Rene Kievits
294b15e9ea worked on some stuff and finally the new install script (no idea if it works yet) 2023-10-25 15:01:31 +02:00
Rene Kievits
bf8520ed9d update network widget to (hopefully) show ethernet/wifi accordingly 2023-05-15 13:27:04 +02:00
Rene Kievits
c023714060 add rubato animation to overflow widget for smoother scrolling, can lagg for big lists 2023-05-15 13:03:42 +02:00
Rene Kievits
2d68ee71da rewritten network module, not finished yet 2023-05-15 13:02:59 +02:00
Rene Kievits
1c7d2be751 new network daemon(not finished) 2023-05-13 21:58:38 +02:00
Rene Kievits
3bae4f4403 some fixes 2023-04-28 02:29:47 +02:00
8171f1c97e why was it deleted?? 2023-04-28 01:24:36 +02:00
2bf4ff9f13 fix applauncher for duoscreen 2023-04-28 01:23:13 +02:00
0e2cd5099c update submodules 2023-04-27 17:47:59 +02:00
Rene Kievits
0e3aafcff5 Some fixes 2023-04-26 00:28:06 +02:00
56 changed files with 4041 additions and 3594 deletions

7
.gitmodules vendored
View File

@@ -4,9 +4,6 @@
[submodule "awesome/src/lib/color"] [submodule "awesome/src/lib/color"]
path = awesome/src/lib/color path = awesome/src/lib/color
url = https://github.com/andOrlando/color url = https://github.com/andOrlando/color
[submodule "awesome/src/lib/nice"] [submodule "awesome/src/lib/lua-dbus_proxy"]
path = awesome/src/lib/nice path = awesome/src/lib/lua-dbus_proxy
url = git@github.com:Crylia/awesome-wm-nice.git
[submodule "awesome/src/lib/dbus_proxy"]
path = awesome/src/lib/dbus_proxy
url = git@github.com:Crylia/lua-dbus_proxy.git url = git@github.com:Crylia/lua-dbus_proxy.git

18
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"Lua.diagnostics.disable": [
"undefined-field",
"undefined-doc-name",
"deprecated"
],
"Lua.diagnostics.globals": [
"awesome",
"mouse",
"mousegrabber",
"client",
"screen",
"selection",
"tag",
"root",
"vim"
]
}

View File

@@ -11,7 +11,7 @@
╰─────────────────────────────────────────────────────────────────╯ ╰─────────────────────────────────────────────────────────────────╯
]] ]]
--#region prints --#region s
io.stdout:write([[ io.stdout:write([[
]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮ ]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮
]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│ ]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│
@@ -35,16 +35,15 @@ io.stderr:write([[
]] .. '\27[0m\n') ]] .. '\27[0m\n')
--#endregion --#endregion
require('src.core.error_handling') require('src.core.error_handling') {}
require('src.theme') require('src.theme') {}
require('src.core.signals') require('src.core.signals') {}
require('src.core.notifications') require('src.core.notifications') {}
require('src.core.rules') require('src.core.rules') {}
require('src.bindings.global_buttons') require('src.bindings.global_buttons')
require('src.bindings.bind_to_tags') require('src.bindings.bind_to_tags')
require('src.modules')() require('src.modules') {}
require('src.tools.auto_starter') {} require('src.tools.auto_starter') {}
--require('src.core.setup')() --require('src.core.setup')()
--require('src.tools.helpers.pulseaudio')() require('src.tools.network')()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 229 KiB

View File

@@ -1,22 +1,26 @@
local ipairs = ipairs
local table = table
-- Awesome libs -- Awesome libs
local akeygrabber = require('awful.keygrabber')
local akey = require('awful.key')
local gtable = require('gears.table')
local atag = require('awful.tag')
local aclient = require('awful.client') local aclient = require('awful.client')
local aspawn = require('awful.spawn') local akey = require('awful.key')
local akeygrabber = require('awful.keygrabber')
local alayout = require('awful.layout') local alayout = require('awful.layout')
local ascreen = require('awful.screen') local ascreen = require('awful.screen')
local aspawn = require('awful.spawn')
local atag = require('awful.tag')
local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table')
local hotkeys_popup = require('awful.hotkeys_popup') local hotkeys_popup = require('awful.hotkeys_popup')
local ruled = require('ruled') local ruled = require('ruled')
-- Local libs -- Local libs
local config = require('src.tools.config')
local audio_helper = require('src.tools.helpers.audio') local audio_helper = require('src.tools.helpers.audio')
local backlight_helper = require('src.tools.helpers.backlight') local backlight_helper = require('src.tools.helpers.backlight')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local powermenu = require('src.modules.powermenu') local config = require('src.tools.config')
local kb_helper = require('src.tools.helpers.kb_helper') local kb_helper = require('src.tools.helpers.kb_helper')
local window_switcher = require('src.modules.window_switcher')
local capi = { local capi = {
awesome = awesome, awesome = awesome,
@@ -26,13 +30,26 @@ local capi = {
local modkey = beautiful.user_config['modkey'] local modkey = beautiful.user_config['modkey']
local awful = require('awful')
local f = 1
akeygrabber { akeygrabber {
keybindings = { keybindings = {
akey { akey {
modifiers = { 'Mod1' }, modifiers = { 'Mod1' },
key = 'Tab', key = 'Tab',
on_press = function() on_press = function()
capi.awesome.emit_signal('window_switcher::select_next') local clients = awful.screen.focused():get_all_clients()
if f == #clients then
f = 1
end
f = f + 1
clients[f].minimized = false
if not clients[f]:isvisible() and clients[f].first_tag then
clients[f].first_tag:view_only()
end
clients[f]:emit_signal('request::activate')
clients[f]:raise()
end, end,
}, },
}, },
@@ -47,11 +64,13 @@ akeygrabber {
stop_key = 'Mod1', stop_key = 'Mod1',
stop_event = 'release', stop_event = 'release',
start_callback = function() start_callback = function()
capi.awesome.emit_signal('toggle_window_switcher') aclient.focus.history.disable_tracking()
window_switcher.popup.visible = true
end, end,
stop_callback = function() stop_callback = function()
capi.awesome.emit_signal('window_switcher::raise') aclient.focus.history.enable_tracking()
capi.awesome.emit_signal('toggle_window_switcher') window_switcher.popup.visible = false
collectgarbage('collect')
end, end,
export_keybindings = true, export_keybindings = true,
} }
@@ -63,18 +82,6 @@ return gtable.join(
hotkeys_popup.show_help, hotkeys_popup.show_help,
{ description = 'Cheat sheet', group = 'Awesome' } { description = 'Cheat sheet', group = 'Awesome' }
), ),
--[[ akey(
{ modkey },
'#113',
atag.viewprev,
{ description = 'View previous tag', group = 'Tag' }
),
akey(
{ modkey },
'#114',
atag.viewnext,
{ description = 'View next tag', group = 'Tag' }
), ]]
akey( akey(
{ modkey }, { modkey },
'#66', '#66',
@@ -201,7 +208,7 @@ return gtable.join(
{ modkey }, { modkey },
'#40', '#40',
function() function()
capi.awesome.emit_signal('application_launcher::show') require('src.modules.app_launcher'):toggle(capi.mouse.screen)
end, end,
{ descripton = 'Application launcher', group = 'Application' } { descripton = 'Application launcher', group = 'Application' }
), ),
@@ -217,7 +224,7 @@ return gtable.join(
{ modkey, 'Shift' }, { modkey, 'Shift' },
'#26', '#26',
function() function()
powermenu:toggle() require('src.modules.powermenu'):toggle()
end, end,
{ descripton = 'Session options', group = 'System' } { descripton = 'Session options', group = 'System' }
), ),
@@ -233,7 +240,9 @@ return gtable.join(
{}, {},
'XF86AudioLowerVolume', 'XF86AudioLowerVolume',
function(c) function(c)
audio_helper.sink_volume_down() -- When changing the volume it makes sense to unmute
audio_helper:sink_volume_down()
audio_helper:sink_unmute()
end, end,
{ description = 'Lower volume', group = 'System' } { description = 'Lower volume', group = 'System' }
), ),
@@ -241,7 +250,9 @@ return gtable.join(
{}, {},
'XF86AudioRaiseVolume', 'XF86AudioRaiseVolume',
function(c) function(c)
audio_helper.sink_volume_up() -- When changing the volume it makes sense to unmute
audio_helper:sink_volume_up()
audio_helper:sink_unmute()
end, end,
{ description = 'Increase volume', group = 'System' } { description = 'Increase volume', group = 'System' }
), ),
@@ -249,7 +260,7 @@ return gtable.join(
{}, {},
'XF86AudioMute', 'XF86AudioMute',
function(c) function(c)
audio_helper.sink_toggle_mute() audio_helper:sink_toggle_mute()
end, end,
{ description = 'Mute volume', group = 'System' } { description = 'Mute volume', group = 'System' }
), ),
@@ -308,7 +319,7 @@ return gtable.join(
capi.mousegrabber.run( capi.mousegrabber.run(
function(m) function(m)
if m.buttons[1] then if m.buttons[1] then
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json') local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/floating.json')
if type(data) ~= 'table' then return end if type(data) ~= 'table' then return end
local c = capi.mouse.current_client local c = capi.mouse.current_client
@@ -323,8 +334,8 @@ return gtable.join(
-- Check if data already had the client then return -- Check if data already had the client then return
for _, v in ipairs(data) do for _, v in ipairs(data) do
if v.WM_NAME == client_data.WM_NAME and if v.WM_NAME == client_data.WM_NAME and
v.WM_CLASS == client_data.WM_CLASS and v.WM_CLASS == client_data.WM_CLASS and
v.WM_INSTANCE == client_data.WM_INSTANCE then v.WM_INSTANCE == client_data.WM_INSTANCE then
return return
end end
end end
@@ -339,7 +350,7 @@ return gtable.join(
} }
c.floating = true c.floating = true
config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data) config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/floating.json', data)
capi.mousegrabber.stop() capi.mousegrabber.stop()
end end
return true return true
@@ -355,7 +366,7 @@ return gtable.join(
capi.mousegrabber.run( capi.mousegrabber.run(
function(m) function(m)
if m.buttons[1] then if m.buttons[1] then
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json') local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/floating.json')
local c = capi.mouse.current_client local c = capi.mouse.current_client
if not c then return end if not c then return end
@@ -368,7 +379,7 @@ return gtable.join(
-- Remove client_data from data_table -- Remove client_data from data_table
for k, v in ipairs(data) do for k, v in ipairs(data) do
if v.WM_CLASS == client_data.WM_CLASS and if v.WM_CLASS == client_data.WM_CLASS and
v.WM_INSTANCE == client_data.WM_INSTANCE then v.WM_INSTANCE == client_data.WM_INSTANCE then
table.remove(data, k) table.remove(data, k)
ruled.client.remove_rule { ruled.client.remove_rule {
rule = { class = c.class, instance = c.instance }, rule = { class = c.class, instance = c.instance },
@@ -381,7 +392,7 @@ return gtable.join(
end end
end end
config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data) config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/floating.json', data)
capi.mousegrabber.stop() capi.mousegrabber.stop()
end end
return true return true

View File

@@ -1,40 +1,53 @@
---------------------------------------------------------------- local setmetatable = setmetatable
-- This class is to output an error if you fuck up the config -- local tostring = tostring
----------------------------------------------------------------
-- Awesome Libs -- Awesome Libs
local naughty = require('naughty')
local gfilesystem = require('gears.filesystem') local gfilesystem = require('gears.filesystem')
local gtimer = require('gears.timer')
local naughty = require('naughty')
local capi = { local capi = {
awesome = awesome, awesome = awesome,
} }
if capi.awesome.startup_errors then local instance = nil
naughty.notify { preset = naughty.config.presets.critical, if not instance then
title = 'Oops, there were errors during startup!', instance = setmetatable({}, {
text = capi.awesome.startup_errors, __call = function()
gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg', if capi.awesome.startup_errors then
} naughty.notification {
end preset = naughty.config.presets.critical,
title = 'ERROR!',
do app_name = 'System Notification',
local in_error = false message = capi.awesome.startup_errors,
capi.awesome.connect_signal( icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg',
'debug::error', }
function(err)
if in_error then
return
end end
in_error = true
naughty.notification { local in_error = false
preset = naughty.config.presets.critical, capi.awesome.connect_signal('debug::error', function(err)
title = 'ERROR', if in_error then return end
app_name = 'System Notification', in_error = true
message = tostring(err),
icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg', naughty.notification {
} preset = naughty.config.presets.critical,
in_error = false title = 'ERROR',
end app_name = 'System Notification',
) message = tostring(err),
icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg',
}
-- Make sure an error is only put every 3 seconds to prevent spam
gtimer {
timeout = 3,
autostart = true,
single_shot = true,
callback = function()
in_error = false
end,
}
end)
end,
})
end end
return instance

View File

@@ -1,19 +1,20 @@
------------------------------- local setmetatable = setmetatable
-- The Notification defaults --
-------------------------------
-- Awesome Libs
-- Awesome Libs
local abutton = require('awful.button')
local aspawn = require('awful.spawn') local aspawn = require('awful.spawn')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color') local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem') local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table')
local naughty = require('naughty') local naughty = require('naughty')
local wibox = require('wibox') local wibox = require('wibox')
local abutton = require('awful.button')
local gtable = require('gears.table')
-- Third party libs
local rubato = require('src.lib.rubato') local rubato = require('src.lib.rubato')
-- Local Libs
local hover = require('src.tools.hover') local hover = require('src.tools.hover')
local capi = { local capi = {
@@ -21,382 +22,366 @@ local capi = {
screen = screen, screen = screen,
} }
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/' local instance = nil
if not instance then
instance = setmetatable({}, {
__call = function()
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
naughty.config.defaults.ontop = true naughty.config.defaults.border_color = beautiful.colorscheme.border_color
naughty.config.defaults.icon_size = dpi(80) naughty.config.defaults.border_width = dpi(2)
naughty.config.defaults.timeout = 5 naughty.config.defaults.icon_size = dpi(64)
naughty.config.defaults.title = 'System Notification' naughty.config.defaults.margin = dpi(10)
naughty.config.defaults.margin = dpi(10) naughty.config.defaults.ontop = true
naughty.config.defaults.position = 'bottom_right' naughty.config.defaults.position = 'bottom_right'
naughty.config.defaults.border_width = dpi(2) naughty.config.defaults.spacing = dpi(10)
naughty.config.defaults.border_color = beautiful.colorscheme.border_color naughty.config.defaults.timeout = 5
naughty.config.defaults.spacing = dpi(10) naughty.config.defaults.title = 'System Notification'
naughty.connect_signal('request::display', function(n) naughty.connect_signal('request::display', function(n)
if beautiful.user_config.dnd then if beautiful.user_config.dnd then
n:destroy() n:destroy()
else else
if not n.icon then n.icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg' end n.app_name = n.app_name or 'System'
if not n.app_name then n.app_name = 'System' end n.icon = n.icon or gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg'
if not n.title then n.title = 'System Notification' end n.message = n.message or 'No message provided'
if not n.message then n.message = 'No message provided' end n.title = n.title or 'System Notification'
local color = beautiful.colorscheme.bg_blue local color = beautiful.colorscheme.bg_blue
if n.urgency == 'critical' then if n.urgency == 'critical' then
color = beautiful.colorscheme.bg_red color = beautiful.colorscheme.bg_red
end end
if n.app_name == 'Spotify' then if n.app_name == 'Spotify' then
n.actions = { n.actions = {
naughty.action { naughty.action {
program = 'Spotify', program = 'Spotify',
id = 'skip-prev', id = 'skip-prev',
name = 'Previous', name = 'Previous',
position = 1, position = 1,
}, naughty.action { }, naughty.action {
program = 'Spotify', program = 'Spotify',
id = 'play-pause', id = 'play-pause',
name = 'Play/Pause', name = 'Play/Pause',
position = 2, position = 2,
}, naughty.action { }, naughty.action {
program = 'Spotify', program = 'Spotify',
id = 'skip-next', id = 'skip-next',
name = 'Next', name = 'Next',
position = 3, position = 3,
}, },
} }
n.resident = true n.resident = true
end end
if n.category == 'device.added' or n.category == 'network.connected' then if n.category == 'device.added' or n.category == 'network.connected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-added.oga') aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-added.oga')
elseif n.category == 'device.removed' or n.category == 'network.disconnected' then elseif n.category == 'device.removed' or n.category == 'network.disconnected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-removed.oga') aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-removed.oga')
elseif n.category == 'device.error' or n.category == 'im.error' or n.category == 'network.error' or n.category == elseif n.category == 'device.error' or n.category == 'im.error' or n.category == 'network.error' or n.category ==
'transfer.error' then 'transfer.error' then
aspawn('ogg123 ogg123 /usr/share/sounds/Pop/stereo/alert/battery-low.oga') aspawn('ogg123 ogg123 /usr/share/sounds/Pop/stereo/alert/battery-low.oga')
elseif n.category == 'email.arrived' then elseif n.category == 'email.arrived' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/message-new-email.oga') aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/message-new-email.oga')
end end
local action_template = wibox.widget { local action_template = wibox.widget {
notification = n, notification = n,
base_layout = wibox.widget { base_layout = wibox.widget {
spacing = dpi(90), spacing = dpi(90),
layout = wibox.layout.flex.horizontal, layout = wibox.layout.flex.horizontal,
}, },
widget_template = { widget_template = {
{ {
{ {
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
id = 'text_role', id = 'text_role',
valign = 'center', valign = 'center',
halign = 'center', halign = 'center',
font = 'JetBrainsMono Nerd Font, Bold 16', font = beautiful.user_config.font .. ' bold 16',
}, },
widget = wibox.container.constraint, widget = wibox.container.constraint,
height = dpi(35), height = dpi(35),
strategy = 'exact', strategy = 'exact',
}, },
id = 'background_role', id = 'background_role',
widget = wibox.container.background, widget = wibox.container.background,
bg = color, bg = color,
fg = beautiful.colorscheme.bg, fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8], shape = beautiful.shape[8],
}, },
style = { style = {
underline_normal = false, underline_normal = false,
underline_selected = false, underline_selected = false,
shape_normal = beautiful.shape[8], shape_normal = beautiful.shape[8],
--Don't remove or it will break --Don't remove or it will break
bg_normal = color, bg_normal = color,
bg_selected = color, bg_selected = color,
fg_normal = beautiful.colorscheme.bg, fg_normal = beautiful.colorscheme.bg,
fg_selected = beautiful.colorscheme.bg, fg_selected = beautiful.colorscheme.bg,
}, },
widget = naughty.list.actions, widget = naughty.list.actions,
} }
-- Hack to get the action buttons to work even after update -- Hack to get the action buttons to work even after update
for i = 1, #action_template._private.layout.children, 1 do for i = 1, #action_template._private.layout.children, 1 do
hover.bg_hover { widget = action_template._private.layout.children[i].children[1], overlay = 12, press_overlay = 24 } hover.bg_hover { widget = action_template._private.layout.children[i].children[1], overlay = 12, press_overlay = 24 }
end end
if (#action_template._private.layout.children > 0) and action_template._private.notification[1].actions[1].program == 'Spotify' then if (#action_template._private.layout.children > 0) and action_template._private.notification[1].actions[1].program == 'Spotify' then
action_template._private.layout.children[1].children[1]:connect_signal('button::press', function() action_template._private.layout.children[1].children[1]:connect_signal('button::press', function()
aspawn('playerctl previous') aspawn('playerctl previous')
end) end)
action_template._private.layout.children[2].children[1]:connect_signal('button::press', function() action_template._private.layout.children[2].children[1]:connect_signal('button::press', function()
aspawn('playerctl play-pause') aspawn('playerctl play-pause')
end) end)
action_template._private.layout.children[3].children[1]:connect_signal('button::press', function() action_template._private.layout.children[3].children[1]:connect_signal('button::press', function()
aspawn('playerctl next') aspawn('playerctl next')
end) end)
end end
local start_timer = n.timeout local start_timer = n.timeout
if n.timeout == 0 then if n.timeout == 0 then
start_timer = 5 start_timer = 5
end end
local notification = wibox.template { local notification = wibox.template {
widget = wibox.widget { widget = wibox.widget {
{ {
{
{
{ -- Title
{ {
{ {
{ -- Icon { -- Title
{ {
{ {
{ { -- Icon
{ {
notification = n, {
widget = naughty.widget.icon, {
image = n.icon, {
resize = true, notification = n,
widget = naughty.widget.icon,
image = n.icon,
resize = true,
},
widget = wibox.container.background,
shape = beautiful.shape[4],
},
widget = wibox.container.place,
},
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(20),
height = dpi(20),
}, },
widget = wibox.container.background, { -- Title
shape = beautiful.shape[4], {
notification = n,
widget = naughty.widget.title,
markup = [[<span foreground="]] ..
beautiful.colorscheme.bg .. [[" font="]] .. beautiful.user_config.font .. ' bold 16' .. [[">]] .. (n.app_name or
'Unknown App') .. [[</span> | <span font="]] .. beautiful.user_config.font .. ' regular 16' .. [[">]] .. (n.title or 'System Notification') .. [[</span>]],
halign = 'left',
valign = 'center',
},
widget = wibox.container.constraint,
width = dpi(430),
height = dpi(35),
strategy = 'max',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
}, },
widget = wibox.container.place, widget = wibox.container.margin,
left = dpi(10),
},
nil,
{
{
{ -- Clock
widget = wibox.widget.textclock,
format = '%H:%M',
font = beautiful.user_config.font .. ' bold 16',
fg = beautiful.colorscheme.bg,
halign = 'right',
valign = 'center',
},
{ -- Close button
{
{
{
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. 'close.svg', beautiful.colorscheme.bg),
resize = true,
halign = 'center',
valign = 'center',
},
start_angle = 4.71239,
thickness = dpi(2),
min_value = 0,
max_value = start_timer,
value = start_timer,
widget = wibox.container.arcchart,
id = 'arc',
},
fg = beautiful.colorscheme.bg,
bg = color,
widget = wibox.container.background,
id = 'arc_bg',
},
strategy = 'exact',
width = dpi(18),
height = dpi(18),
widget = wibox.container.constraint,
},
left = dpi(5),
widget = wibox.container.margin,
},
layout = wibox.layout.fixed.horizontal,
},
right = dpi(5),
widget = wibox.container.margin,
},
layout = wibox.layout.align.horizontal,
},
widget = wibox.container.background,
bg = color,
fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8],
},
{ -- Main body
{ -- Image
{
{
notification = n,
image = n.icon,
valign = 'center',
halign = 'center',
upscale = true,
resize_strategy = 'scale',
widget = naughty.widget.icon,
},
widget = wibox.container.background,
shape = beautiful.shape[10],
}, },
widget = wibox.container.constraint, widget = wibox.container.constraint,
strategy = 'exact', strategy = 'exact',
width = dpi(20), height = dpi(128),
height = dpi(20), width = dpi(128),
}, },
{ -- Title {
{ {
notification = n, notification = n,
widget = naughty.widget.title, widget = naughty.widget.message,
markup = [[<span foreground="]] .. font = beautiful.user_config.font .. ' bold 10',
beautiful.colorscheme.bg .. [[" font="JetBrainsMono Nerd Font, Bold 16">]] .. (n.app_name or
'Unknown App') .. [[</span> | <span font="JetBrainsMono Nerd Font, Regular 16">]] .. (n.title or 'System Notification') .. [[</span>]],
halign = 'left', halign = 'left',
valign = 'center', valign = 'center',
}, },
widget = wibox.container.constraint, widget = wibox.container.constraint,
width = dpi(430), strategy = 'exact',
height = dpi(35), height = dpi(128),
strategy = 'max',
}, },
spacing = dpi(10), spacing = dpi(15),
layout = wibox.layout.fixed.horizontal, layout = wibox.layout.fixed.horizontal,
}, },
widget = wibox.container.margin, { -- Spacer
left = dpi(10), {
}, widget = wibox.container.background,
nil, bg = beautiful.colorscheme.bg,
{
{
{ -- Clock
widget = wibox.widget.textclock,
format = '%H:%M',
font = 'JetBrainsMono Nerd Font, Bold 16',
fg = beautiful.colorscheme.bg,
halign = 'right',
valign = 'center',
}, },
{ -- Close button widget = wibox.container.constraint,
{ strategy = 'exact',
{ height = dpi(2),
{
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. 'close.svg', beautiful.colorscheme.bg),
resize = true,
halign = 'center',
valign = 'center',
},
start_angle = 4.71239,
thickness = dpi(2),
min_value = 0,
max_value = start_timer,
value = start_timer,
widget = wibox.container.arcchart,
id = 'arc',
},
fg = beautiful.colorscheme.bg,
bg = color,
widget = wibox.container.background,
id = 'arc_bg',
},
strategy = 'exact',
width = dpi(18),
height = dpi(18),
widget = wibox.container.constraint,
},
left = dpi(5),
widget = wibox.container.margin,
},
layout = wibox.layout.fixed.horizontal,
}, },
right = dpi(5), action_template,
widget = wibox.container.margin, spacing = dpi(15),
id = 'main_layout',
layout = wibox.layout.fixed.vertical,
}, },
layout = wibox.layout.align.horizontal, widget = wibox.container.margin,
margins = dpi(15),
}, },
widget = wibox.container.background, bg = beautiful.colorscheme.bg,
bg = color, border_color = beautiful.colorscheme.border_color,
fg = beautiful.colorscheme.bg, border_width = dpi(2),
shape = beautiful.shape[8], shape = beautiful.shape[8],
widget = wibox.container.background,
}, },
{ -- Main body widget = wibox.container.constraint,
{ -- Image strategy = 'exact',
{ width = dpi(600),
{
notification = n,
image = n.icon,
valign = 'center',
halign = 'center',
upscale = true,
resize_strategy = 'scale',
widget = naughty.widget.icon,
},
widget = wibox.container.background,
shape = beautiful.shape[10],
},
widget = wibox.container.constraint,
strategy = 'exact',
height = dpi(128),
width = dpi(128),
},
{
{
notification = n,
widget = naughty.widget.message,
font = 'JetBrainsMono Nerd Font, Regular 10',
halign = 'left',
valign = 'center',
},
widget = wibox.container.constraint,
strategy = 'exact',
height = dpi(128),
},
spacing = dpi(15),
layout = wibox.layout.fixed.horizontal,
},
{ -- Spacer
{
widget = wibox.container.background,
bg = beautiful.colorscheme.bg,
},
widget = wibox.container.constraint,
strategy = 'exact',
height = dpi(2),
},
action_template,
spacing = dpi(15),
id = 'main_layout',
layout = wibox.layout.fixed.vertical,
}, },
widget = wibox.container.margin, }
margins = dpi(15),
},
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
shape = beautiful.shape[8],
widget = wibox.container.background,
},
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(600),
},
}
if #action_template._private.layout.children < 1 then if #action_template._private.layout.children < 1 then
notification:get_widget().children[1].children[1].children[1].children[3] = nil notification:get_widget().children[1].children[1].children[1].children[3] = nil
end
local arc_bg = notification:get_widget().children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1]
local arc = arc_bg.children[1]
local timeout = n.timeout
if timeout ~= 0 then
local rubato_timer = rubato.timed {
duration = n.timeout,
pos = n.timeout,
easing = rubato.linear,
clamp_position = true,
subscribed = function(value)
arc.value = value
end,
}
rubato_timer.target = 0
notification:get_widget():connect_signal('mouse::enter', function()
n.timeout = 99999
rubato_timer.pause = true
end)
notification:get_widget():connect_signal('mouse::leave', function()
n.timeout = rubato_timer.pos
rubato_timer.pause = false
rubato_timer.target = 0
end)
end
hover.bg_hover { widget = arc_bg }
arc_bg:connect_signal('button::press', function()
n:destroy()
end)
notification:get_widget():buttons { gtable.join(
abutton({}, 1, function()
for _, client in ipairs(capi.client.get()) do
if client.class:lower():match(n.app_name:lower()) then
if not client:isvisible() and client.first_tag then
client.first_tag:view_only()
end
client:emit_signal('request::activate')
client:raise()
end end
end
end),
abutton({}, 3, function()
n:destroy()
end)
), }
local box = naughty.layout.box { local arc_bg = notification:get_widget().children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1]
notification = n, local arc = arc_bg.children[1]
timeout = 5,
type = 'notification', local timeout = n.timeout
screen = capi.screen.primary,
widget_template = notification, if timeout ~= 0 then
}
box.buttons = {} local rubato_timer = rubato.timed {
n.buttons = {} duration = n.timeout,
end pos = n.timeout,
end) easing = rubato.linear,
--[[ clamp_position = true,
naughty.notification { subscribed = function(value)
app_name = 'Spotify', arc.value = value
title = 'The Beatles - Here Comes The Sun', end,
message = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', }
icon = '/home/crylia/Bilder/57384097.jpg',
timeout = 30, rubato_timer.target = 0
actions = {
naughty.action { notification:get_widget():connect_signal('mouse::enter', function()
name = 'amet', n.timeout = 99999
position = 1, rubato_timer.pause = true
text = 'Test', end)
},
naughty.action { notification:get_widget():connect_signal('mouse::leave', function()
name = 'Lorem ipsum dolor sit amet', n.timeout = rubato_timer.pos
position = 2, rubato_timer.pause = false
}, rubato_timer.target = 0
naughty.action { end)
name = 'Lorem', end
position = 3,
}, hover.bg_hover { widget = arc_bg }
},
} arc_bg:connect_signal('button::press', function()
]] n:destroy()
end)
notification:get_widget():buttons { gtable.join(
abutton({}, 1, function()
for _, client in ipairs(capi.client.get()) do
if client.class:lower():match(n.app_name:lower()) then
if not client:isvisible() and client.first_tag then
client.first_tag:view_only()
end
client:emit_signal('request::activate')
client:raise()
end
end
end),
abutton({}, 3, function()
n:destroy()
end)
), }
local box = naughty.layout.box {
notification = n,
timeout = 5,
type = 'notification',
screen = capi.screen.primary,
widget_template = notification,
}
box.buttons = {}
n.buttons = {}
end
end)
end,
})
end
return instance

View File

@@ -1,102 +1,101 @@
------------------------------------------------------------------------------------------------- local ipairs = ipairs
-- This class contains rules for float exceptions or special themeing for certain applications -- local setmetatable = setmetatable
-------------------------------------------------------------------------------------------------
-- Awesome Libs -- Awesome Libs
local aclient = require('awful.client') local aclient = require('awful.client')
local aplacement = require('awful.placement') local aplacement = require('awful.placement')
local ascreen = require('awful.screen') local ascreen = require('awful.screen')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local gfilesystem = require('gears.filesystem')
local ruled = require('ruled') local ruled = require('ruled')
local config = require('src.tools.config') local config = require('src.tools.config')
awesome.register_xproperty('_NET_WM_BYPASS_COMPOSITOR', 'boolean') local capi = {
awesome = awesome,
}
ruled.client.connect_signal('request::rules', function() local instance = nil
ruled.client.append_rule { if not instance then
rule = {}, instance = setmetatable({}, {
properties = { __call = function()
border_width = dpi(2), capi.awesome.register_xproperty('_NET_WM_BYPASS_COMPOSITOR', 'boolean')
border_color = beautiful.colorscheme.border_color,
maximized = false,
maximized_horizontal = false,
maximized_vertical = false,
focus = aclient.focus.filter,
raise = true,
keys = require('src.bindings.client_keys'),
buttons = require('src.bindings.client_buttons'),
screen = ascreen.preferred,
placement = aplacement.under_mouse + aplacement.no_overlap + aplacement.no_offscreen + aplacement.centered,
},
}
ruled.client.append_rule { ruled.client.connect_signal('request::rules', function()
rule_any = { ruled.client.append_rule {
type = { rule = {},
'normal', properties = {
'dialog', border_width = dpi(2),
}, border_color = beautiful.colorscheme.border_color,
}, maximized = false,
properties = { maximized_horizontal = false,
titlebars_enabled = true, maximized_vertical = false,
}, focus = aclient.focus.filter,
} raise = true,
keys = require('src.bindings.client_keys'),
buttons = require('src.bindings.client_buttons'),
screen = ascreen.preferred,
placement = aplacement.under_mouse + aplacement.no_overlap + aplacement.no_offscreen + aplacement.centered,
},
}
ruled.client.append_rule { ruled.client.append_rule {
rule_any = { rule_any = {
class = { type = {
'proton-bridge', 'normal',
'1password', 'dialog',
'protonvpn', },
'Steam', },
}, properties = {
}, titlebars_enabled = true,
properties = { },
minimized = true, }
},
} ruled.client.append_rule {
ruled.client.append_rule { rule_any = {
rule_any = { class = {
class = { 'proton-bridge',
'discord', '1password',
'spotify', 'protonvpn',
}, 'Steam',
}, },
properties = { },
tag = '1', properties = {
screen = 2, minimized = true,
}, },
} }
ruled.client.append_rule {
rule_any = {
class = {
'steam_app_990080',
},
},
callback = function(c)
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
c:connect_signal('focus', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end)
c:connect_signal('raised', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end)
end,
}
ruled.client.append_rule {
rule_any = {
class = {
'steam_app_990080',
},
},
callback = function(c)
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
c:connect_signal('focus', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end)
c:connect_signal('raised', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end) end)
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/floating.json')
for _, c in ipairs(data) do
ruled.client.append_rule {
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
properties = {
floating = true,
},
}
end
end, end,
} })
end)
do
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
for _, c in ipairs(data) do
ruled.client.append_rule {
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
properties = {
floating = true,
},
}
end
end end
return instance

View File

@@ -1,5 +1,8 @@
--- A module to manage the first installation and setup the config without having to edit local ipairs = ipairs
--- the config files manually. local math = math
local pairs = pairs
local setmetatable = setmetatable
local table = table
--Awesome Libs --Awesome Libs
local abutton = require('awful.button') local abutton = require('awful.button')
@@ -8,22 +11,22 @@ local apopup = require('awful.popup')
local aspawn = require('awful.spawn') local aspawn = require('awful.spawn')
local atooltip = require('awful.tooltip') local atooltip = require('awful.tooltip')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color') local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local gtable = require('gears.table') local gtable = require('gears.table')
local wibox = require('wibox') local wibox = require('wibox')
local gfilesystem = require('gears.filesystem')
local inputwidget = require('src.modules.inputbox')
--Own Libs --Own Libs
local toggle_button = require('awful.widget.toggle_widget') local toggle_button = require('awful.widget.toggle_widget')
local inputwidget = require('src.modules.inputbox')
local capi = { local capi = {
screen = screen, screen = screen,
} }
local assets_dir = os.getenv('HOME') .. '/.config/awesome/src/assets/' local assets_dir = os.getenv('HOME') .. '/.config/awesome/src/assets/'
local font_dir = os.getenv('HOME') .. '/.config/awesome/src/assets/fonts/'
local icon_dir = os.getenv('HOME') .. '/.config/awesome/src/assets/icons/setup/' local icon_dir = os.getenv('HOME') .. '/.config/awesome/src/assets/icons/setup/'
local setup = { mt = {} } local setup = { mt = {} }

View File

@@ -1,11 +1,10 @@
---@diagnostic disable: undefined-field local setmetatable = setmetatable
-- Awesome Libs -- Awesome Libs
local aplacement = require('awful.placement') local aplacement = require('awful.placement')
local gtimer = require('gears.timer')
local ascreen = require('awful.screen') local ascreen = require('awful.screen')
local ruled = require('ruled') local beautiful = require('beautiful')
local gtimer = require('gears.timer')
local config = require('src.tools.config')
local capi = { local capi = {
awesome = awesome, awesome = awesome,
@@ -15,60 +14,61 @@ local capi = {
tag = tag, tag = tag,
} }
capi.screen.connect_signal('added', function() local instance = nil
capi.awesome.restart() if not instance then
end) instance = setmetatable({}, {
__call = function()
capi.screen.connect_signal('added', function()
capi.awesome.restart()
end)
capi.screen.connect_signal('removed', function() capi.screen.connect_signal('removed', function()
capi.awesome.restart() capi.awesome.restart()
end) end)
capi.client.connect_signal('manage', function(c) capi.client.connect_signal('manage', function(c)
if capi.awesome.startup and not c.size_hints.user_porition and not c.size_hints.program_position then if capi.awesome.startup and not c.size_hints.user_porition and not c.size_hints.program_position then
aplacement.no_offscreen(c) aplacement.no_offscreen(c)
end end
if c.transient_for then if c.transient_for then
c.floating = true c.floating = true
end end
if c.fullscreen then if c.fullscreen then
gtimer.delayed_call(function() gtimer.delayed_call(function()
if c.valid then if c.valid then
c:geometry(c.screen.geometry) c:geometry(c.screen.geometry)
end
end)
end
end)
capi.client.connect_signal('unmanage', function(c)
if #ascreen.focused().clients > 0 then
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
raise = true,
})
end
end)
capi.tag.connect_signal('property::selected', function(c)
if #ascreen.focused().clients > 0 then
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
raise = true,
})
end
end)
-- Sloppy focus
if beautiful.user_config.sloppy_focus then
client.connect_signal('mouse::enter', function(c)
c:emit_signal(
'request::activate',
'mouse_enter', {
raise = true,
})
end)
end end
end) end,
end
local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json')
for _, c in ipairs(data) do
ruled.client.append_rule {
rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE },
properties = {
floating = true,
},
}
end
end)
capi.client.connect_signal('unmanage', function(c)
if #ascreen.focused().clients > 0 then
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
raise = true,
})
end
end)
capi.tag.connect_signal('property::selected', function(c)
if #ascreen.focused().clients > 0 then
ascreen.focused().clients[1]:emit_signal('request::activate', 'mouse_enter', {
raise = true,
})
end
end)
-- Sloppy focus
--[[ client.connect_signal('mouse::enter', function(c)
c:emit_signal(
'request::activate',
'mouse_enter', {
raise = true,
}) })
end) ]] end
return instance

View File

@@ -8,7 +8,7 @@ local beautiful = require('beautiful')
local cairo = require('lgi').cairo local cairo = require('lgi').cairo
local dpi = require('beautiful').xresources.apply_dpi local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color') local gcolor = require('gears.color')
local gdk = require('lgi').Gdk local gdk = require('lgi').require('Gdk', '3.0')
local gfilesystem = require('gears.filesystem') local gfilesystem = require('gears.filesystem')
local gsurface = require('gears.surface') local gsurface = require('gears.surface')
local gtimer = require('gears.timer') local gtimer = require('gears.timer')
@@ -497,8 +497,6 @@ local function create_titlebar_items(c, group)
return layout return layout
end end
---Adds the titlebar to the left of a client
---@param c client
function add_titlebar(c) function add_titlebar(c)
if titlebar_position == 'top' then if titlebar_position == 'top' then
atitlebar(c, { atitlebar(c, {

View File

@@ -18,6 +18,8 @@ local gshape = require('gears.shape')
local gobject = require('gears.object') local gobject = require('gears.object')
local mousegrabber = mousegrabber local mousegrabber = mousegrabber
local rubato = require('src.lib.rubato')
local overflow = { mt = {} } local overflow = { mt = {} }
-- Determine the required space to draw the layout's children and, if necessary, -- Determine the required space to draw the layout's children and, if necessary,
@@ -33,7 +35,7 @@ function overflow:fit(context, orig_width, orig_height)
local scrollbar_width = self._private.scrollbar_width local scrollbar_width = self._private.scrollbar_width
local scrollbar_enabled = self._private.scrollbar_enabled local scrollbar_enabled = self._private.scrollbar_enabled
local used_in_dir, used_max = 0, 0 local used_in_dir, used_max = 0, 0
local is_y = self._private.dir == "y" local is_y = self._private.dir == 'y'
local avail_in_dir = is_y and orig_height or orig_width local avail_in_dir = is_y and orig_height or orig_width
-- Set the direction covered by scrolling to the maximum value -- Set the direction covered by scrolling to the maximum value
@@ -81,7 +83,7 @@ end
-- Only those widgets that are currently visible will be placed. -- Only those widgets that are currently visible will be placed.
function overflow:layout(context, orig_width, orig_height) function overflow:layout(context, orig_width, orig_height)
local result = {} local result = {}
local is_y = self._private.dir == "y" local is_y = self._private.dir == 'y'
local widgets = self._private.widgets local widgets = self._private.widgets
local avail_in_dir = is_y and orig_height or orig_width local avail_in_dir = is_y and orig_height or orig_width
local scrollbar_width = self._private.scrollbar_width local scrollbar_width = self._private.scrollbar_width
@@ -140,9 +142,9 @@ function overflow:layout(context, orig_width, orig_height)
bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, scrollbar_width, bar_length) bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, scrollbar_width, bar_length)
bar_y = bar_pos bar_y = bar_pos
if scrollbar_position == "left" then if scrollbar_position == 'left' then
widget_x = widget_x + bar_w widget_x = widget_x + bar_w
elseif scrollbar_position == "right" then elseif scrollbar_position == 'right' then
bar_x = orig_width - bar_w bar_x = orig_width - bar_w
end end
@@ -153,9 +155,9 @@ function overflow:layout(context, orig_width, orig_height)
bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, bar_length, scrollbar_width) bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, bar_length, scrollbar_width)
bar_x = bar_pos bar_x = bar_pos
if scrollbar_position == "top" then if scrollbar_position == 'top' then
widget_y = widget_y + bar_h widget_y = widget_y + bar_h
elseif scrollbar_position == "bottom" then elseif scrollbar_position == 'bottom' then
bar_y = orig_height - bar_h bar_y = orig_height - bar_h
end end
@@ -305,6 +307,13 @@ end
-- @tparam number scroll_factor The scroll factor. -- @tparam number scroll_factor The scroll factor.
-- @propemits true false -- @propemits true false
overflow.rubato_timed = rubato.timed {
duration = 0.5,
rate = 24,
clamp_position = true,
}
local first_call = true
function overflow:set_scroll_factor(factor) function overflow:set_scroll_factor(factor)
local current = self._private.scroll_factor local current = self._private.scroll_factor
local interval = self._private.used_in_dir - self._private.avail_in_dir local interval = self._private.used_in_dir - self._private.avail_in_dir
@@ -318,10 +327,21 @@ function overflow:set_scroll_factor(factor)
return return
end end
self._private.scroll_factor = math.min(1, math.max(factor, 0)) local function update_scroll()
self._private.scroll_factor = self.rubato_timed.pos
self:emit_signal('widget::layout_changed')
self:emit_signal('property::scroll_factor', factor)
end
self:emit_signal("widget::layout_changed") if first_call then
self:emit_signal("property::scroll_factor", factor) self.rubato_timed:subscribe(update_scroll)
end
self.rubato_timed.target = math.min(1, math.max(factor + (self.rubato_timed.target - self.rubato_timed.pos), 0))
--self._private.scroll_factor = math.min(1, math.max(factor, 0))
--self:emit_signal('widget::layout_changed')
--self:emit_signal('property::scroll_factor', factor)
end end
function overflow:get_scroll_factor() function overflow:get_scroll_factor()
@@ -347,8 +367,8 @@ function overflow:set_scrollbar_width(width)
self._private.scrollbar_width = width self._private.scrollbar_width = width
self:emit_signal("widget::layout_changed") self:emit_signal('widget::layout_changed')
self:emit_signal("property::scrollbar_width", width) self:emit_signal('property::scrollbar_width', width)
end end
--- The scrollbar position. --- The scrollbar position.
@@ -370,8 +390,8 @@ function overflow:set_scrollbar_position(position)
self._private.scrollbar_position = position self._private.scrollbar_position = position
self:emit_signal("widget::layout_changed") self:emit_signal('widget::layout_changed')
self:emit_signal("property::scrollbar_position", position) self:emit_signal('property::scrollbar_position', position)
end end
function overflow:get_scrollbar_position() function overflow:get_scrollbar_position()
@@ -396,8 +416,8 @@ function overflow:set_scrollbar_enabled(enabled)
self._private.scrollbar_enabled = enabled self._private.scrollbar_enabled = enabled
self:emit_signal("widget::layout_changed") self:emit_signal('widget::layout_changed')
self:emit_signal("property::scrollbar_enabled", enabled) self:emit_signal('property::scrollbar_enabled', enabled)
end end
function overflow:get_scrollbar_enabled() function overflow:get_scrollbar_enabled()
@@ -407,7 +427,7 @@ end
-- Wraps a callback function for `mousegrabber` that is capable of -- Wraps a callback function for `mousegrabber` that is capable of
-- updating the scroll factor. -- updating the scroll factor.
local function build_grabber(container, initial_x, initial_y, geo) local function build_grabber(container, initial_x, initial_y, geo)
local is_y = container._private.dir == "y" local is_y = container._private.dir == 'y'
local bar_interval = container._private.avail_in_dir - container._private.bar_length local bar_interval = container._private.avail_in_dir - container._private.bar_length
local start_pos = container._private.scroll_factor * bar_interval local start_pos = container._private.scroll_factor * bar_interval
local start = is_y and initial_y or initial_x local start = is_y and initial_y or initial_x
@@ -439,7 +459,7 @@ local function apply_scrollbar_mouse_signal(container, w)
if button_id ~= 1 then if button_id ~= 1 then
return return
end end
mousegrabber.run(build_grabber(container, x, y, geo), "fleur") mousegrabber.run(build_grabber(container, x, y, geo), 'fleur')
end) end)
end end
@@ -461,8 +481,8 @@ function overflow:set_scrollbar_widget(widget)
self._private.scrollbar_widget = w self._private.scrollbar_widget = w
self:emit_signal("widget::layout_changed") self:emit_signal('widget::layout_changed')
self:emit_signal("property::scrollbar_widget", widget) self:emit_signal('property::scrollbar_widget', widget)
end end
function overflow:get_scrollbar_widget() function overflow:get_scrollbar_widget()
@@ -473,13 +493,13 @@ function overflow:reset()
self._private.widgets = {} self._private.widgets = {}
self._private.scroll_factor = 0 self._private.scroll_factor = 0
local scrollbar_widget = separator({ shape = gshape.rectangle }) local scrollbar_widget = separator { shape = gshape.rectangle }
apply_scrollbar_mouse_signal(self, scrollbar_widget) apply_scrollbar_mouse_signal(self, scrollbar_widget)
self._private.scrollbar_widget = scrollbar_widget self._private.scrollbar_widget = scrollbar_widget
self:emit_signal("widget::layout_changed") self:emit_signal('widget::layout_changed')
self:emit_signal("widget::reset") self:emit_signal('widget::reset')
self:emit_signal("widget::reseted") self:emit_signal('widget::reseted')
end end
local function new(dir, ...) local function new(dir, ...)
@@ -500,9 +520,9 @@ local function new(dir, ...)
ret._private.fill_space = true ret._private.fill_space = true
ret._private.scrollbar_width = 5 ret._private.scrollbar_width = 5
ret._private.scrollbar_enabled = true ret._private.scrollbar_enabled = true
ret._private.scrollbar_position = dir == "vertical" and "right" or "bottom" ret._private.scrollbar_position = dir == 'vertical' and 'right' or 'bottom'
local scrollbar_widget = separator({ shape = gshape.rectangle }) local scrollbar_widget = separator { shape = gshape.rectangle }
apply_scrollbar_mouse_signal(ret, scrollbar_widget) apply_scrollbar_mouse_signal(ret, scrollbar_widget)
ret._private.scrollbar_widget = scrollbar_widget ret._private.scrollbar_widget = scrollbar_widget
@@ -525,7 +545,7 @@ end
-- @tparam widget ... Widgets that should be added to the layout. -- @tparam widget ... Widgets that should be added to the layout.
-- @constructorfct wibox.layout.overflow.horizontal -- @constructorfct wibox.layout.overflow.horizontal
function overflow.horizontal(...) function overflow.horizontal(...)
return new("horizontal", ...) return new('horizontal', ...)
end end
--- Returns a new vertical overflow layout. --- Returns a new vertical overflow layout.
@@ -536,7 +556,7 @@ end
-- @tparam widget ... Widgets that should be added to the layout. -- @tparam widget ... Widgets that should be added to the layout.
-- @constructorfct wibox.layout.overflow.vertical -- @constructorfct wibox.layout.overflow.vertical
function overflow.vertical(...) function overflow.vertical(...)
return new("vertical", ...) return new('vertical', ...)
end end
return setmetatable(overflow, overflow.mt) return setmetatable(overflow, overflow.mt)

View File

@@ -1,3 +1,11 @@
local ipairs = ipairs
local math = math
local pairs = pairs
local setmetatable = setmetatable
local table = table
-- Awesome Libs
local Gio = require('lgi').Gio
local abutton = require('awful.button') local abutton = require('awful.button')
local akey = require('awful.key') local akey = require('awful.key')
local akeygrabber = require('awful.keygrabber') local akeygrabber = require('awful.keygrabber')
@@ -5,22 +13,22 @@ local aplacement = require('awful.placement')
local apopup = require('awful.popup') local apopup = require('awful.popup')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gobject = require('gears.object')
local gtable = require('gears.table') local gtable = require('gears.table')
local gtimer = require('gears.timer') local gtimer = require('gears.timer')
local wibox = require('wibox') local wibox = require('wibox')
local gobject = require('gears.object')
local Gio = require('lgi').Gio
local gfilesystem = require('gears.filesystem')
local gcolor = require('gears.color')
-- Third Party Libs
local fzy = require('fzy') local fzy = require('fzy')
local hover = require('src.tools.hover') -- Local Libs
local inputbox = require('src.modules.inputbox')
local context_menu = require('src.modules.context_menu') local context_menu = require('src.modules.context_menu')
local config = require('src.tools.config')
local icon_lookup = require('src.tools.gio_icon_lookup')
local dock = require('src.modules.crylia_bar.dock') local dock = require('src.modules.crylia_bar.dock')
local hover = require('src.tools.hover')
local icon_lookup = require('src.tools.gio_icon_lookup')
local inputbox = require('src.modules.inputbox')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/' local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/'
@@ -31,6 +39,10 @@ local capi = {
local launcher = gobject {} local launcher = gobject {}
--- Fetches all applications and their information from Gio.AppInfo.get_all()
--- and generates a wibox widget for each application, containing the application's icon, name and launch command.
--- The generated wibox widget also includes a context menu that allows the user to launch,
--- add to desktop, or pin the application to the dock.
function launcher:fetch_apps() function launcher:fetch_apps()
for _, app in ipairs(Gio.AppInfo.get_all()) do for _, app in ipairs(Gio.AppInfo.get_all()) do
local app_id = app:get_id() local app_id = app:get_id()
@@ -190,54 +202,15 @@ function launcher:fetch_apps()
end end
end end
local function levenshtein_distance(str1, str2) ---Reset the grid and add all apps that match to a filter using fzy scoring
local len1 = string.len(str1) ---@param filter string Filter for the name, category and keywords
local len2 = string.len(str2)
local matrix = {}
local cost = 0
if (len1 == 0) then
return len2
elseif (len2 == 0) then
return len1
elseif (str1 == str2) then
return 0
end
for i = 0, len1, 1 do
matrix[i] = {}
matrix[i][0] = i
end
for j = 0, len2, 1 do
matrix[0][j] = j
end
for i = 1, len1, 1 do
for j = 1, len2, 1 do
if str1:byte(i) == str2:byte(j) then
cost = 0
else
cost = 1
end
matrix[i][j] = math.min(
matrix[i - 1][j] + 1,
matrix[i][j - 1] + 1,
matrix[i - 1][j - 1] + cost
)
end
end
return matrix[len1][len2]
end
function launcher:filter_apps(filter) function launcher:filter_apps(filter)
filter = filter or '' filter = filter or ''
self.grid:reset() self.grid:reset()
local app_list = {} local app_list = {}
for _, app in pairs(self.app_table) do for _, app in pairs(self.app_table) do
if filter == '' if filter == ''
or fzy.has_match(filter, app.name) or fzy.has_match(filter, app.name or '')
or fzy.has_match(filter, app.category or '') or fzy.has_match(filter, app.category or '')
or fzy.has_match(filter, app.keywords or '') or fzy.has_match(filter, app.keywords or '')
then then
@@ -245,17 +218,22 @@ function launcher:filter_apps(filter)
end end
end end
table.sort(app_list, function(a, b) table.sort(app_list, function(a, b)
return a.name < b.name local score_a = fzy.score(filter, a.name)
end) local score_b = fzy.score(filter, b.name)
--sort by lowest levenshtein distance
table.sort(app_list, function(a, b) if score_a ~= score_b then
return levenshtein_distance(filter, a.name) < levenshtein_distance(filter, b.name) return score_a > score_b
else
return a.name < b.name
end
end) end)
for _, app in ipairs(app_list) do for _, app in ipairs(app_list) do
self.grid:add(app) self.grid:add(app)
end end
end end
--- Toggle the visibility of the application launcher popup window.
--- @param screen number The screen where the launcher will be displayed.
function launcher:toggle(screen) function launcher:toggle(screen)
if not self.popup.visible then if not self.popup.visible then
self.popup.screen = screen self.popup.screen = screen
@@ -268,13 +246,20 @@ function launcher:toggle(screen)
x = 1, y = 1, x = 1, y = 1,
} }
self.popup.visible = false self.popup.visible = false
collectgarbage('collect')
end end
end end
---Reset the border color of a widget at x,y
---@param x number Grid column
---@param y number Grid row
function launcher:selection_remove(x, y) function launcher:selection_remove(x, y)
self.grid:get_widgets_at(y, x)[1].border_color = beautiful.colorscheme.border_color self.grid:get_widgets_at(y, x)[1].border_color = beautiful.colorscheme.border_color
end end
---Update the border color of a widget at x,y
---@param x number Grid column
---@param y number Grid row
function launcher:selection_update(x, y) function launcher:selection_update(x, y)
local w_old = self.grid:get_widgets_at(y, x)[1] local w_old = self.grid:get_widgets_at(y, x)[1]
local w_new = self.grid:get_widgets_at(self.cursor.y, self.cursor.x)[1] local w_new = self.grid:get_widgets_at(self.cursor.y, self.cursor.x)[1]
@@ -282,7 +267,10 @@ function launcher:selection_update(x, y)
w_new.border_color = beautiful.colorscheme.bg_teal w_new.border_color = beautiful.colorscheme.bg_teal
end end
-- Offset to know when to scroll up/down
local up_offset = 0 local up_offset = 0
--- Move the cursor down
function launcher:move_down() function launcher:move_down()
local row, _ = self.grid:get_dimension() local row, _ = self.grid:get_dimension()
if self.cursor.y < row then if self.cursor.y < row then
@@ -303,6 +291,7 @@ function launcher:move_down()
end end
end end
--- Move the cursor up
function launcher:move_up() function launcher:move_up()
local row, _ = self.grid:get_dimension() local row, _ = self.grid:get_dimension()
if self.cursor.y > 1 then if self.cursor.y > 1 then
@@ -320,6 +309,7 @@ function launcher:move_up()
end end
end end
--- Move the cursor left
function launcher:move_left() function launcher:move_left()
if self.cursor.x > 1 then if self.cursor.x > 1 then
self.cursor.x = self.cursor.x - 1 self.cursor.x = self.cursor.x - 1
@@ -327,6 +317,7 @@ function launcher:move_left()
end end
end end
--- Move the cursor right
function launcher:move_right() function launcher:move_right()
local _, col = self.grid:get_dimension() local _, col = self.grid:get_dimension()
if self.cursor.x < col then if self.cursor.x < col then
@@ -336,11 +327,13 @@ function launcher:move_right()
end end
end end
--- Wrapper to focus the searchbar
function launcher:focus_searchbar() function launcher:focus_searchbar()
self.searchbar:focus() self.searchbar:focus()
self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.bg_teal self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.bg_teal
end end
--- Wrapper to unfocus the searchbar
function launcher:unfocus_searchbar() function launcher:unfocus_searchbar()
self.searchbar:unfocus() self.searchbar:unfocus()
self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.border_color self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.border_color
@@ -349,7 +342,7 @@ end
local instance = nil local instance = nil
if not instance then if not instance then
instance = setmetatable(launcher, { instance = setmetatable(launcher, {
__call = function(self, screen) __call = function(self)
self.app_table = {} self.app_table = {}
self.cursor = { self.cursor = {
x = 1, x = 1,
@@ -450,6 +443,7 @@ if not instance then
self:toggle(capi.mouse.screen) self:toggle(capi.mouse.screen)
self.grid:get_widgets_at(self.cursor.x, self.cursor.y)[1].execute() self.grid:get_widgets_at(self.cursor.x, self.cursor.y)[1].execute()
self:filter_apps('') self:filter_apps('')
self.searchbar:set_text('')
elseif key == 'Down' then elseif key == 'Down' then
if not (self.keygrabber.running == akeygrabber.current_instance) then if not (self.keygrabber.running == akeygrabber.current_instance) then
self:selection_update(1, 1) self:selection_update(1, 1)
@@ -535,7 +529,6 @@ if not instance then
ontop = true, ontop = true,
visible = true, visible = true,
stretch = false, stretch = false,
screen = screen,
placement = aplacement.centered, placement = aplacement.centered,
bg = beautiful.colorscheme.bg, bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color, border_color = beautiful.colorscheme.border_color,

View File

@@ -0,0 +1,153 @@
-----------------------------------
-- This is the volume_old module --
-----------------------------------
-- Awesome Libs
local aplacement = require('awful.placement')
local apopup = require('awful.popup')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local gtable = require('gears.table')
local gtimer = require('gears.timer')
local wibox = require('wibox')
local audio_helper = require('src.tools.helpers.audio')
-- Icon directory path
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
local capi = {
awesome = awesome,
}
local osd = {}
function osd:display()
self.popup.visible = true
if self.timer.started then
self.timer:again()
else
self.timer:start()
end
end
local instance = nil
if not instance then
instance = setmetatable(osd, {
__call = function(self, ...)
local args = ... or {}
self.popup = apopup {
widget = {
{
{
{ -- Volume Icon
{
image = gcolor.recolor_image(icondir .. 'volume-off.svg',
beautiful.colorscheme.bg_yellow),
resize = true,
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(36),
height = dpi(36),
strategy = 'exact',
},
{
widget = wibox.container.constraint,
width = dpi(24),
strategy = 'exact',
},
{ -- Volume Bar
{
{
id = 'progressbar',
value = 0,
max_value = 100,
color = beautiful.colorscheme.bg_yellow,
background_color = beautiful.colorscheme.bg1,
shape = gshape.rounded_rect,
widget = wibox.widget.progressbar,
},
widget = wibox.container.constraint,
width = dpi(250),
height = dpi(12),
},
widget = wibox.container.place,
},
{ -- Value text
{
widget = wibox.widget.textbox,
halign = 'right',
id = 'text_role',
text = 'NAN%',
},
widget = wibox.container.constraint,
width = dpi(60),
strategy = 'min',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
margins = dpi(20),
widget = wibox.container.margin,
},
shape = beautiful.shape[12],
widget = wibox.container.background,
},
ontop = true,
stretch = false,
visible = true,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
fg = beautiful.colorscheme.fg,
bg = beautiful.colorscheme.bg,
screen = 1,
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
}
self.popup.visible = false
self.timer = gtimer {
timeout = args.display_time or 3,
autostart = true,
callback = function()
self.popup.visible = false
end,
}
local volume_icon = self.popup.widget:get_children_by_id('icon_role')[1]
local volume_text = self.popup.widget:get_children_by_id('text_role')[1]
local volume_progressbar = self.popup.widget:get_children_by_id('progressbar')[1]
audio_helper:connect_signal('sink::get', function(_, muted, volume)
volume = tonumber(volume or 0)
local icon = 'volume-mute.svg'
if muted then
volume_progressbar.value = 0
else
volume_progressbar.value = volume
icon = icondir .. 'volume'
if volume < 1 then
icon = icon .. '-mute'
elseif volume >= 1 and volume < 34 then
icon = icon .. '-low'
elseif volume >= 34 and volume < 67 then
icon = icon .. '-medium'
elseif volume >= 67 then
icon = icon .. '-high'
end
end
volume_icon:set_image(gcolor.recolor_image(icon .. '.svg', beautiful.colorscheme.bg_yellow))
volume_text.text = volume .. '%'
self:display()
end)
end,
})
end
return instance

View File

@@ -1,139 +0,0 @@
-----------------------------------
-- This is the volume_old module --
-----------------------------------
-- Awesome Libs
local aplacement = require('awful.placement')
local apopup = require('awful.popup')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local gtable = require('gears.table')
local gtimer = require('gears.timer')
local wibox = require('wibox')
local audio_helper = require('src.tools.helpers.audio')
-- Icon directory path
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/'
local osd = {}
function osd:run()
self.visible = true
if self.timer.started then
self.timer:again()
else
self.timer:start()
end
end
function osd.new(args)
args = args or {}
args.screen = args.screen or 1
local w = apopup {
widget = {
{
{
{ -- Volume Icon
{
image = gcolor.recolor_image(icondir .. 'volume-off.svg', beautiful.colorscheme.bg_purple),
valign = 'center',
halign = 'center',
resize = true,
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(25),
height = dpi(25),
strategy = 'exact',
},
{ -- Volume Bar
{
{
id = 'progressbar',
color = beautiful.colorscheme.bg_purple,
background_color = beautiful.colorscheme.bg1,
max_value = 100,
value = 0,
shape = gshape.rounded_rect,
widget = wibox.widget.progressbar,
},
widget = wibox.container.constraint,
width = dpi(250),
height = dpi(5),
},
widget = wibox.container.place,
},
{ -- Volume text
widget = wibox.widget.textbox,
id = 'text_role',
text = '0',
valign = 'center',
halign = 'center',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
left = dpi(10),
right = dpi(10),
top = dpi(20),
bottom = dpi(20),
widget = wibox.container.margin,
},
shape = beautiful.shape[12],
widget = wibox.container.background,
},
ontop = true,
stretch = false,
visible = false,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
fg = beautiful.colorscheme.bg_purple,
bg = beautiful.colorscheme.bg,
screen = 1,
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
}
gtable.crush(w, osd)
w.timer = gtimer {
timeout = 2,
autostart = true,
callback = function()
w.visible = false
end,
}
audio_helper:connect_signal('output::get', function(_, muted, volume)
volume = tonumber(volume or 0)
if muted then
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icondir .. 'volume-mute' .. '.svg', beautiful.colorscheme.bg_purple))
w.widget:get_children_by_id('progressbar')[1].value = 0
else
w.widget:get_children_by_id('progressbar')[1].value = volume
local icon = icondir .. 'volume'
if volume < 1 then
icon = icon .. '-mute'
elseif volume >= 1 and volume < 34 then
icon = icon .. '-low'
elseif volume >= 34 and volume < 67 then
icon = icon .. '-medium'
elseif volume >= 67 then
icon = icon .. '-high'
end
w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icon .. '.svg', beautiful.colorscheme.bg_purple))
w.widget:get_children_by_id('text_role')[1].text = volume
end
w:run()
end)
return w
end
return setmetatable(osd, { __call = function(_, ...) return osd.new(...) end })

View File

@@ -15,7 +15,7 @@ local lgi = require('lgi')
local wibox = require('wibox') local wibox = require('wibox')
-- Own libs -- Own libs
local context_menu = require('src.modules.context_menu.init') local context_menu = require('src.modules.context_menu')
local hover = require('src.tools.hover') local hover = require('src.tools.hover')
local input = require('src.modules.inputbox') local input = require('src.modules.inputbox')
@@ -227,7 +227,8 @@ function device.new(args)
widget = wibox.container.margin, widget = wibox.container.margin,
}, },
widget = wibox.container.background, widget = wibox.container.background,
}, spacing = dpi(10), },
spacing = dpi(10),
entries = { entries = {
{ -- Connect/Disconnect a device { -- Connect/Disconnect a device
name = ret.device.Connected and 'Disconnect' or 'Connect', name = ret.device.Connected and 'Disconnect' or 'Connect',

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +0,0 @@
---------------------------------------
-- This is the brightness_osd module --
---------------------------------------
-- Awesome Libs
local aplacement = require('awful.placement')
local apopup = require('awful.popup')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local gtable = require('gears.table')
local gtimer = require('gears.timer')
local wibox = require('wibox')
local backlight_helper = require('src.tools.helpers.backlight')
local capi = {
awesome = awesome,
mouse = mouse,
}
-- Icon directory path
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/brightness/'
local brightness_osd = { mt = {} }
-- Hide the brightness_osd after 3 seconds
function brightness_osd:run()
self.visible = true
if self.timer.started then
self.timer:again()
else
self.timer:start()
end
end
function brightness_osd.new(args)
args = args or {}
local w = apopup {
widget = {
{
{
{ -- Brightness Icon
{
image = gcolor.recolor_image(icondir .. 'volume-off.svg', beautiful.colorscheme.bg_blue),
valign = 'center',
halign = 'center',
resize = true,
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(25),
height = dpi(25),
strategy = 'exact',
},
{ -- Brightness Bar
{
{
id = 'progressbar',
color = beautiful.colorscheme.bg_blue,
background_color = beautiful.colorscheme.bg,
max_value = 100,
value = 0,
shape = gshape.rounded_rect,
widget = wibox.widget.progressbar,
},
widget = wibox.container.constraint,
width = dpi(250),
height = dpi(5),
},
widget = wibox.container.place,
},
{ -- Brightness text
widget = wibox.widget.textbox,
id = 'text_role',
text = '0',
valign = 'center',
halign = 'center',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
left = dpi(10),
right = dpi(10),
top = dpi(20),
bottom = dpi(20),
widget = wibox.container.margin,
},
shape = beautiful.shape[4],
widget = wibox.container.background,
},
ontop = true,
stretch = false,
visible = false,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
fg = beautiful.colorscheme.bg_blue,
bg = beautiful.colorscheme.bg,
screen = 1,
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
}
gtable.crush(w, brightness_osd, true)
w.timer = gtimer {
timeout = 2,
autostart = true,
callback = function()
w.visible = false
end,
}
backlight_helper:connect_signal('brightness_changed', function()
backlight_helper:brightness_get_async(function(brightness)
brightness = brightness / (backlight_helper.brightness_max or 24000) * 100
w.widget:get_children_by_id('progressbar')[1].value = brightness
local icon = icondir .. 'brightness'
if brightness >= 0 and brightness < 34 then
icon = icon .. '-low.svg'
elseif brightness >= 34 and brightness < 67 then
icon = icon .. '-medium.svg'
elseif brightness >= 67 then
icon = icon .. '-high.svg'
end
w.widget:get_children_by_id('icon')[1]:set_image(gcolor.recolor_image(icon, beautiful.colorscheme.bg_blue))
w.widget:get_children_by_id('text_role')[1].text = brightness
w:run()
end)
end)
return w
end
function brightness_osd.mt:__call(...)
return brightness_osd.new(...)
end
return setmetatable(brightness_osd, brightness_osd.mt)

View File

@@ -0,0 +1,154 @@
local setmetatable = setmetatable
local apopup = require('awful.popup')
local aplacement = require('awful.placement')
local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color')
local gobject = require('gears.object')
local gtable = require('gears.table')
local gtimer = require('gears.timer')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local wibox = require('wibox')
local backlight_helper = require('src.tools.helpers.backlight')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/brightness/'
local capi = {
awesome = awesome,
}
local osd = gobject {}
-- Show the popup for x seconds, default is 3
function osd:display()
self.popup.visible = true
if self.timer.started then
self.timer:again()
else
self.timer:start()
end
end
local instance = nil
if not instance then
instance = setmetatable(osd, {
---Create a backlight osd that shows when the backlight is changed
---@param ... table[display_time]
__call = function(self, ...)
local args = ... or {}
-- Set to visible on creation so the popup is cached on startup
self.popup = apopup {
widget = {
{
{
{ -- Icon
{
image = gcolor.recolor_image(icondir .. 'brightness-high.svg',
beautiful.colorscheme.bg_blue),
resize = true,
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(36),
height = dpi(36),
strategy = 'exact',
},
{
widget = wibox.container.constraint,
width = dpi(24),
strategy = 'exact',
},
{ -- Progressbar
{
{
id = 'progressbar',
value = 0,
max_value = 100,
color = beautiful.colorscheme.bg_blue,
background_color = beautiful.colorscheme.bg1,
shape = gshape.rounded_rect,
widget = wibox.widget.progressbar,
},
widget = wibox.container.constraint,
width = dpi(250),
height = dpi(12),
},
widget = wibox.container.place,
},
{ -- Value text
{
widget = wibox.widget.textbox,
halign = 'right',
id = 'text_role',
text = 'NAN%',
},
widget = wibox.container.constraint,
width = dpi(60),
strategy = 'min',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
widget = wibox.container.margin,
margins = dpi(20),
},
widget = wibox.container.background,
shape = beautiful.shape[12],
},
ontop = true,
stretch = false,
visible = true,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
fg = beautiful.colorscheme.fg,
bg = beautiful.colorscheme.bg,
screen = 1,
placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end,
}
self.popup.visible = false
self.timer = gtimer {
timeout = args.display_time or 3,
autostart = true,
callback = function()
self.popup.visible = false
end,
}
local progressbar = self.popup.widget:get_children_by_id('progressbar')[1]
local brightness_text = self.popup.widget:get_children_by_id('text_role')[1]
local brightness_icon = self.popup.widget:get_children_by_id('icon_role')[1]
backlight_helper:connect_signal('brightness_changed', function()
backlight_helper.brightness_get_async(function(brightness)
if not brightness then return end
brightness = math.floor((tonumber(brightness) / (backlight_helper.brightness_max or 24000) * 100) + 0.5)
local icon = icondir .. 'brightness'
if brightness >= 0 and brightness < 34 then
icon = icon .. '-low.svg'
elseif brightness >= 34 and brightness < 67 then
icon = icon .. '-medium.svg'
elseif brightness >= 67 then
icon = icon .. '-high.svg'
end
brightness_icon.image = gcolor.recolor_image(icon,
beautiful.colorscheme.bg_blue)
progressbar.value = brightness
brightness_text.text = brightness .. '%'
self:display()
end)
end)
return self
end,
})
end
return instance

View File

@@ -478,12 +478,14 @@ function calendar:create_calendar_widget()
task_popup.x = capi.mouse.coords().x task_popup.x = capi.mouse.coords().x
task_popup.y = capi.mouse.coords().y task_popup.y = capi.mouse.coords().y
task_popup.visible = not task_popup.visible task_popup.visible = not task_popup.visible
collectgarbage('collect')
end) end)
) )
) )
tw:connect_signal('mouse::leave', function() tw:connect_signal('mouse::leave', function()
task_popup.visible = false task_popup.visible = false
collectgarbage('collect')
end) end)
hover.bg_hover { widget = tw } hover.bg_hover { widget = tw }
@@ -754,7 +756,7 @@ function calendar.new(args)
{ {
widget = wibox.widget.imagebox, widget = wibox.widget.imagebox,
resize = false, resize = false,
image = gcolor.recolor_image(icondir .. 'add_ical.svg', beautiful.colorscheme.bg_red), image = gcolor.recolor_image(icondir .. 'add_ical.svg', beautiful.colorscheme.bg),
halign = 'center', halign = 'center',
valign = 'center', valign = 'center',
}, },
@@ -883,7 +885,7 @@ function calendar.new(args)
border_width = dpi(2), border_width = dpi(2),
border_strategy = 'inner', border_strategy = 'inner',
fg = beautiful.colorscheme.fg, fg = beautiful.colorscheme.fg,
shape = beautiful.shape, shape = beautiful.shape[12],
}) })
ret:get_tasks() ret:get_tasks()

View File

@@ -104,7 +104,7 @@ function context_menu:make_entries(wtemplate, entries, spacing)
widget = wibox.container.margin, widget = wibox.container.margin,
}, },
bg = beautiful.colorscheme.bg, bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.bg_red, fg = beautiful.colorscheme.fg,
widget = wibox.container.background, widget = wibox.container.background,
} }

View File

@@ -74,27 +74,24 @@ function dock:toggle()
self.popup.visible = not self.popup.visible self.popup.visible = not self.popup.visible
end end
function dock:write_elements_to_file_async(callback) function dock:write_elements_to_file_async()
--create a local copy of the elements["pinned"] table and only set the desktop_file key from its children --create a local copy of the elements["pinned"] table and only set the desktop_file key from its children
local elements_copy = { pinned = {} } local elements_copy = { pinned = {} }
for _, element in ipairs(elements['pinned']) do for _, element in ipairs(elements['pinned']) do
table.insert(elements_copy['pinned'], { desktop_file = element.desktop_file }) table.insert(elements_copy['pinned'], { desktop_file = element.desktop_file })
end end
config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json', elements_copy['pinned'], callback)
config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json', elements_copy['pinned'])
end end
---Read the content of dock.json and get the content as a table ---Read the content of dock.json and get the content as a table
---@param callback function Called after the elements have been set, no values are passed function dock:read_elements_from_file_async()
function dock:read_elements_from_file_async(callback)
local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json') local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json')
-- Make sure to not set the running key to nil on accident -- Make sure to not set the running key to nil on accident
for _, v in ipairs(data) do for _, v in ipairs(data) do
local w = self:get_element_widget(v.desktop_file) local w = self:get_element_widget(v.desktop_file)
table.insert(elements['pinned'], w) table.insert(elements['pinned'], w)
end end
if callback then
callback()
end
end end
---Creates a pinned widget for the dock and adds it into the elements table ---Creates a pinned widget for the dock and adds it into the elements table
@@ -104,7 +101,9 @@ function dock:get_element_widget(desktop_file)
if not desktop_file then return end if not desktop_file then return end
local GDesktopAppInfo = Gio.DesktopAppInfo.new_from_filename(desktop_file) local GDesktopAppInfo = Gio.DesktopAppInfo.new_from_filename(desktop_file)
if not GDesktopAppInfo then
return
end
local icon = icon_lookup:get_gicon_path(nil, GDesktopAppInfo.get_string(GDesktopAppInfo, 'Icon')) or local icon = icon_lookup:get_gicon_path(nil, GDesktopAppInfo.get_string(GDesktopAppInfo, 'Icon')) or
icon_lookup:get_gicon_path(nil, Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'X-AppImage-Old-Icon')) or '' icon_lookup:get_gicon_path(nil, Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'X-AppImage-Old-Icon')) or ''
@@ -135,6 +134,7 @@ function dock:get_element_widget(desktop_file)
bg = beautiful.colorscheme.bg1, bg = beautiful.colorscheme.bg1,
shape = beautiful.shape[8], shape = beautiful.shape[8],
widget = wibox.container.background, widget = wibox.container.background,
desktop_file = desktop_file,
} }
local action_entries = {} local action_entries = {}

View File

@@ -11,7 +11,7 @@ local wibox = require('wibox')
local config = require('src.tools.config') local config = require('src.tools.config')
local element = require('src.modules.desktop.element') local element = require('src.modules.desktop.element')
local cm = require('src.modules.context_menu.init') local cm = require('src.modules.context_menu')
local capi = { local capi = {
mouse = mouse, mouse = mouse,

View File

@@ -1,6 +1,6 @@
local tinsert = table.insert
local load = load
local ipairs = ipairs local ipairs = ipairs
local load = load
local tinsert = table.insert
-- Awesome Libs -- Awesome Libs
local awful = require('awful') local awful = require('awful')
@@ -20,12 +20,18 @@ if not instance then
awful.tag({ '1', '2', '3', '4', '5', '6', '7', '8', '9' }, s, layouts[1]) awful.tag({ '1', '2', '3', '4', '5', '6', '7', '8', '9' }, s, layouts[1])
require('src.modules.desktop.desktop') { screen = s } require('src.modules.desktop.desktop') { screen = s }
require('src.modules.crylia_bar')(s) if beautiful.user_config.crylia_bar then
--require('src.modules.crylia_wibox.init')(s) require('src.modules.crylia_bar')(s)
else
require('src.modules.crylia_wibox.init')(s)
end
require('src.modules.notification-center') { screen = s } require('src.modules.notification-center') { screen = s }
--require('src.modules.window_switcher.init') { screen = s } require('src.modules.window_switcher')(s)
require('src.modules.application_launcher') { screen = s }
end) end)
require('src.modules.app_launcher')()
require('src.modules.powermenu')()
require('src.modules.brightness')()
require('src.modules.audio')()
end, end,
}) })
end end

View File

@@ -454,9 +454,9 @@ end
local button_signal = function(self, x, y, button) local button_signal = function(self, x, y, button)
if button == 1 then if button == 1 then
self:set_cursor_pos_from_mouse(x, y) --self:set_cursor_pos_from_mouse(x, y)
self:start_mousegrabber(x, y) --self:start_mousegrabber(x, y)
self:start_keygrabber() --self:start_keygrabber()
end end
end end

View File

@@ -0,0 +1,805 @@
local setmetatable = setmetatable
local table = table
local pairs = pairs
local ipairs = ipairs
local base = require('wibox.widget.base')
local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local wibox = require('wibox')
local gtable = require('gears.table')
local abutton = require('awful.button')
local apopup = require('awful.popup')
local aplacement = require('awful.placement')
local rubato = require('src.lib.rubato')
local dnd_widget = require('awful.widget.toggle_widget')
local networkManager = require('src.tools.network')()
local inputbox = require('src.modules.inputbox')
local context_menu = require('src.modules.context_menu')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
local capi = {
mouse = mouse,
}
local network = {}
--- Called when a connection does not exist yet and the user needs to ender a password
--- And Autoconnect or not.
---@param ap AccessPoint The access point to connect to
---@param callback function The callback to call when the conenct button is pressed
function network:open_connection_form(ap, callback)
if self.form_popup then
self.form_popup.visible = false
end
--Password inputbox
local password = inputbox {
mouse_focus = true,
text = 'testtext',
}
--New form widget
local w = base.make_widget_from_value {
{
{
{
{ -- Header
{
nil,
{ -- SSID
{
widget = wibox.widget.textbox,
text = ap.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', beautiful.colorscheme.bg),
resize = true,
valign = 'center',
halign = 'center',
},
widget = wibox.container.margin,
margins = dpi(5),
},
widget = wibox.container.background,
id = 'close_button',
bg = beautiful.colorscheme.bg_red,
shape = beautiful.shape[8],
},
widget = wibox.container.constraint,
width = dpi(30),
height = dpi(30),
strategy = 'exact',
},
layout = wibox.layout.align.horizontal,
},
widget = wibox.container.background,
fg = beautiful.colorscheme.bg_red,
},
{ -- Form
{ -- Password text
widget = wibox.widget.textbox,
text = 'Password',
halign = 'center',
valign = 'center',
},
{ -- Spacing
widget = wibox.container.margin,
left = dpi(20),
right = dpi(20),
},
{ -- Passwort inputbox
{
{
{
{
password.widget,
step = dpi(50),
scrollbar_width = 0,
id = 'scroll',
layout = require('src.lib.overflow_widget.overflow').horizontal,
},
widget = wibox.container.margin,
left = dpi(5),
right = dpi(5),
},
widget = wibox.container.place,
halign = 'left',
},
widget = wibox.container.background,
bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.fg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
shape = beautiful.shape[8],
id = 'password_container',
},
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(300),
height = dpi(50),
},
layout = wibox.layout.align.horizontal,
},
{ -- Actions
{ -- Auto Connect
{
{
{
checked = false,
shape = beautiful.shape[4],
color = beautiful.colorscheme.bg,
paddings = dpi(3),
check_color = beautiful.colorscheme.bg_red,
border_color = beautiful.colorscheme.bg_red,
border_width = dpi(2),
id = 'checkbox',
widget = wibox.widget.checkbox,
},
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(30),
height = dpi(30),
},
widget = wibox.container.place,
},
{
widget = wibox.widget.textbox,
text = 'Auto connect',
halign = 'center',
valign = 'center',
},
layout = wibox.layout.fixed.horizontal,
spacing = dpi(10),
},
nil,
{ -- Connect
{
{
{
widget = wibox.widget.textbox,
text = 'Connect',
valign = 'center',
halign = 'center',
},
widget = wibox.container.margin,
margins = dpi(10),
},
widget = wibox.container.background,
bg = beautiful.colorscheme.bg_blue,
fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8],
id = 'connect_button',
},
widget = wibox.container.margin,
margins = dpi(10),
},
layout = wibox.layout.align.horizontal,
},
layout = wibox.layout.fixed.vertical,
spacing = dpi(20),
},
widget = wibox.container.margin,
margins = dpi(10),
},
bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.fg,
widget = wibox.container.background,
},
widget = wibox.container.constraint,
strategy = 'max',
height = dpi(400),
width = dpi(600),
buttons = gtable.join {
abutton({}, 1, function()
password:unfocus()
end),
},
}
-- Popup for the form
self.form_popup = apopup {
widget = w,
visible = true,
type = 'dialog',
screen = capi.mouse.screen,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
ontop = true,
placement = aplacement.centered,
}
-- Automatically scroll to the right when typing to keep the password visible
local scroll_layout = w:get_children_by_id('scroll')[1]
password:connect_signal('inputbox::keypressed', function(_, m, k)
scroll_layout:set_scroll_factor(1)
end)
-- Connect button pressed when the user is done typing and ready to connect
--TODO: Don't just close the form, try to connect first and check if the password is correct or not
local connect_button = w:get_children_by_id('connect_button')[1]
connect_button:buttons(gtable.join {
abutton({}, 1, function()
local res = {
autoconnect = w:get_children_by_id('checkbox')[1].checked,
passwd = password:get_text(),
ssid = ap.SSID,
security = ap.Security,
}
password:unfocus()
networkManager:ConnectToAccessPointAsync(ap, self.device, networkManager.NetworkManagerSettings:NewConnectionProfile(res), function(succ)
if succ then
w = nil
self.form_popup.visible = false
else
--TODO: Add a little text under/above the password box and make it visible here telling the user that the password was
--TODO: wrong
end
end)
end),
})
-- Autoconnect true/false
local checkbox = w:get_children_by_id('checkbox')[1]
checkbox:buttons(gtable.join {
abutton({}, 1, function()
checkbox.checked = not checkbox.checked
end),
})
-- Close the form and do nothing
local close_button = w:get_children_by_id('close_button')[1]
close_button:buttons(gtable.join {
abutton({}, 1, function()
password:unfocus()
w = nil
self.form_popup.visible = false
end),
})
-- Focus the inputbox when clicked
--TODO: Add some keys to the inputbox to make it possible to lose focus on enter/escape etc
local password_container = w:get_children_by_id('password_container')[1]
password_container:buttons(gtable.join {
abutton({}, 1, function()
password:focus()
end),
})
end
---Sort the wifi list by active access point first, then by strength descending
function network:resort_wifi_list()
local wifi_list = self:get_children_by_id('wifi_list')[1]
--Make sure that the active AP is always on top, there is only one active AP
table.sort(wifi_list.children, function(a, b)
if self.device:IsApActive(a) then
return true
elseif self.device:IsApActive(b) then
return false
end
return a.Strength > b.Strength
end)
end
---If an Access Point is lost then remove it from the list
---@param ap AccessPoint Lost AP
---@return boolean deleted
function network:delete_ap_from_list(ap)
local wifi_list = self:get_children_by_id('wifi_list')[1]
for i, w in ipairs(wifi_list.children) do
if w.object_path == ap then
table.remove(wifi_list.children, i)
return true
end
end
return false
end
---If an access point needs to be added to the list
---@param ap AccessPoint
function network:add_ap_to_list(ap)
if not ap then return end
local wifi_list = self:get_children_by_id('wifi_list')[1]
local fg, bg
if self.device:IsApActive(ap) then
fg = beautiful.colorscheme.bg
bg = beautiful.colorscheme.bg_red
else
fg = beautiful.colorscheme.bg_red
bg = beautiful.colorscheme.bg
end
-- New AP widget
local w = base.make_widget_from_value {
{
{
{
{
{
id = 'icon_role',
image = gcolor.recolor_image(icondir .. 'wifi-strength-1.svg', fg),
resize = true,
valign = 'center',
halign = 'center',
widget = wibox.widget.imagebox,
},
strategy = 'max',
width = dpi(24),
height = dpi(24),
widget = wibox.container.constraint,
},
{
{
{
text = ap.SSID,
widget = wibox.widget.textbox,
},
strategy = 'exact',
width = dpi(300),
widget = wibox.container.constraint,
},
width = dpi(260),
height = dpi(40),
strategy = 'max',
widget = wibox.container.constraint,
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
{ -- Spacing
width = dpi(10),
widget = wibox.container.constraint,
},
{
{
{
resize = false,
id = 'con_icon',
image = gcolor.recolor_image(icondir .. 'link-off.svg', fg),
valign = 'center',
halign = 'center',
widget = wibox.widget.imagebox,
},
strategy = 'exact',
height = dpi(24),
width = dpi(24),
widget = wibox.container.constraint,
},
margins = dpi(5),
widget = wibox.container.margin,
},
layout = wibox.layout.align.horizontal,
},
margins = dpi(5),
widget = wibox.container.margin,
},
shape = beautiful.shape[4],
bg = bg,
fg = fg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
widget = wibox.container.background,
Strength = ap.Strength,
object_path = ap.object_path,
}
local icon = w:get_children_by_id('icon_role')[1]
local con_icon = w:get_children_by_id('con_icon')[1]
-- Update the strength icon and resort the list afterwards
ap:connect_signal('NetworkManagerAccessPoint::Strength', function(_, strength)
local s
if strength >= 80 then
s = 5
elseif strength >= 60 and strength < 80 then
s = 4
elseif strength >= 40 and strength < 60 then
s = 3
elseif strength >= 20 and strength < 40 then
s = 2
else
s = 1
end
w.Strength = strength
icon.image = gcolor.recolor_image(icondir .. 'wifi-strength-' .. s .. '.svg', fg)
self:resort_wifi_list()
end)
-- Manually fire once to set the icon, as some AP's need a few seconds to update
ap:emit_signal('NetworkManagerAccessPoint::Strength', ap.Strength)
-- Update the active connection, and the old one (color and icon change)
self.device:connect_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', function(_, old_ap, new_ap)
local function active_ap_signal(_, strength)
self:emit_signal('ActiveAccessPointStrength', strength)
--!Why does the above signal not work outside of this module?
--This is a workaournd until I foundout why it doesn't work
awesome.emit_signal('ActiveAccessPointStrength', strength)
end
if old_ap == ap.object_path then
w.bg = beautiful.colorscheme.bg
w.fg = beautiful.colorscheme.bg_red
bg = beautiful.colorscheme.bg
fg = beautiful.colorscheme.bg_red
con_icon.image = gcolor.recolor_image(icondir .. 'link-off.svg', fg)
icon.image = gcolor.recolor_image(icondir .. 'wifi-strength-1.svg', fg)
ap:disconnect_signal('NetworkManagerAccessPoint::Strength', active_ap_signal)
end
if new_ap == ap.object_path then
w.bg = beautiful.colorscheme.bg_red
w.fg = beautiful.colorscheme.bg
fg = beautiful.colorscheme.bg
bg = beautiful.colorscheme.bg_red
con_icon.image = gcolor.recolor_image(icondir .. 'link.svg', fg)
icon.image = gcolor.recolor_image(icondir .. 'wifi-strength-1.svg', fg)
ap:connect_signal('NetworkManagerAccessPoint::Strength', active_ap_signal)
end
end)
-- Again manually update
self.device:emit_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', nil, self.device.NetworkManagerDeviceWireless.ActiveAccessPoint)
-- Context menu for connecting, disconnecting, etc.
--TODO: Needs to update its entries when the active AP changes to it has a disconnect button
local cm = context_menu {
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 = self.device:IsApActive(ap) and 'Disconnect' or 'Connect',
icon = self.device:IsApActive(ap) and gcolor.recolor_image(icondir .. 'link-off.svg', bg) or gcolor.recolor_image(icondir .. 'link.svg', fg),
callback = function()
if self.device:IsApActive(ap) then
networkManager:DisconnectFromAP();
else
networkManager:ConnectToAccessPointAsync(ap, self.device, nil, function(res)
if not res then
self:open_connection_form(ap, function(res)
end)
end
end)
end
end,
},
{
name = 'Remove connection',
icon = gcolor.recolor_image(icondir .. 'delete.svg', bg),
callback = function()
for path, value in pairs(networkManager.NetworkManagerSettings.ConnectionList or {}) do
if ap.SSID == value:GetSettings().connection.id then
networkManager.NetworkManagerSettings:RemoveConnection(value)
end
end
end,
},
},
}
-- Hide context menu on leave
cm:connect_signal('mouse::leave', function()
cm.visible = false
end)
-- Left click should try to connect/disconnect to AP
--TODO: Check if active ap is clicked and try to disconnect, instead of trying to reconnect to the same AP
-- Right click toggles the context menu
w:buttons(gtable.join {
abutton({}, 1, function()
networkManager:ConnectToAccessPointAsync(ap, self.device, nil, function(res)
if not res then
self:open_connection_form(ap, function(res)
end)
end
end)
end),
abutton({}, 3, function()
cm:toggle()
end),
})
-- Add ap into table
table.insert(wifi_list.children, w)
-- Resort after adding the new AP
self:resort_wifi_list()
end
---Check if an AP is already in the list by comparing its object path
---@param ap AccessPoint
---@return boolean inlist Is in list or not
function network:is_ap_in_list(ap)
if not ap then return false end
local wifi_list = self:get_children_by_id('wifi_list')[1]
for _, w in ipairs(wifi_list.children) do
if w.object_path == ap.object_path then
return true
end
end
return false
end
---Add the list to the widget hierarchy, and clears the previous entries
---Usually used when the user requests a new scan
---@param ap_list table<ap_list>
function network:set_wifi_list(ap_list)
if not ap_list or #ap_list < 1 then return end
local wifi_list = self:get_children_by_id('wifi_list')[1]
wifi_list:reset()
for _, ap in ipairs(ap_list) do
self:add_ap_to_list(ap)
end
end
return setmetatable(network, {
__call = function(self)
local dnd = dnd_widget {
color = beautiful.colorscheme.bg_red,
size = dpi(40),
}
local w = base.make_widget_from_value {
{
{
{
{
{
{
{
widget = wibox.widget.imagebox,
resize = false,
id = 'wifi_icon',
image = gcolor.recolor_image(icondir .. 'menu-down.svg', beautiful.colorscheme.bg_red),
},
widget = wibox.container.place,
},
{
{
text = 'Wifi Networks',
widget = wibox.widget.textbox,
},
margins = dpi(5),
widget = wibox.container.margin,
},
layout = wibox.layout.fixed.horizontal,
},
id = 'wifi_list_bar',
bg = beautiful.colorscheme.bg1,
fg = beautiful.colorscheme.bg_red,
shape = beautiful.shape[4],
widget = wibox.container.background,
},
{
{
{
{
step = dpi(50),
spacing = dpi(10),
scrollbar_width = 0,
id = 'wifi_list',
layout = require('src.lib.overflow_widget.overflow').vertical,
},
margins = dpi(10),
widget = wibox.container.margin,
},
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4))
end,
widget = wibox.container.background,
},
id = 'wifi_list_height',
strategy = 'exact',
height = 0,
widget = wibox.container.constraint,
},
{
{
{
dnd,
widget = wibox.container.place,
},
nil,
{
{
{
image = gcolor.recolor_image(icondir .. 'refresh.svg', beautiful.colorscheme.bg_red),
resize = false,
valign = 'center',
halign = 'center',
widget = wibox.widget.imagebox,
},
widget = wibox.container.margin,
margins = dpi(5),
},
id = 'refresh_button',
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
bg = beautiful.colorscheme.bg,
shape = beautiful.shape[4],
widget = wibox.container.background,
},
layout = wibox.layout.align.horizontal,
},
top = dpi(10),
widget = wibox.container.margin,
},
layout = wibox.layout.fixed.vertical,
},
margins = dpi(15),
widget = wibox.container.margin,
},
shape = beautiful.shape[8],
border_color = beautiful.colorscheme.border_color,
bg = beautiful.colorscheme.bg,
border_width = dpi(2),
widget = wibox.container.background,
},
strategy = 'exact',
width = dpi(400),
widget = wibox.container.constraint,
}
gtable.crush(self, w)
--- Get the current wifi device.
---! In theory its not needed to update, why would the wifi card change? Needs validation.
self.device = networkManager:get_wireless_device()
local wifi_list = w:get_children_by_id('wifi_list')[1]
local wifi_list_height = w:get_children_by_id('wifi_list_height')[1]
local wifi_list_bar = w:get_children_by_id('wifi_list_bar')[1]
local wifi_icon = w:get_children_by_id('wifi_icon')[1]
-- Dropdown animation
local wifi_list_anim = rubato.timed {
duration = 0.2,
pos = wifi_list_height.height,
clamp_position = true,
rate = 24,
subscribed = function(v)
wifi_list_height.height = v
end,
}
-- Dropdown toggle
wifi_list_bar:buttons(gtable.join {
abutton({}, 1, function()
if wifi_list_height.height == 0 then
local size = (wifi_list.children and #wifi_list.children or 0) * dpi(50)
if size > dpi(330) then
size = dpi(330)
end
wifi_list_anim.target = dpi(size)
wifi_list_bar.shape = function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4))
end
if #wifi_list.children > 0 then
wifi_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg',
beautiful.colorscheme.bg_red))
else
wifi_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg',
beautiful.colorscheme.bg_red))
end
else
wifi_list_anim.target = 0
wifi_list_bar.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',
beautiful.colorscheme.bg_red))
end
end),
})
--- Manual rescan request, this gets all AP's and updates the list
local refresh_button = w:get_children_by_id('refresh_button')[1]
refresh_button:buttons(gtable.join {
abutton({}, 1, nil, function()
local wifi_device = networkManager:get_wireless_device()
if not wifi_device then return end
wifi_device:RequestScan(function(ap_list)
self:set_wifi_list(ap_list)
end)
end),
})
do
local wifi_device = networkManager:get_wireless_device()
if not wifi_device then return end
wifi_device:RequestScan(function(ap_list)
self:set_wifi_list(ap_list)
end)
dnd:buttons(gtable.join {
abutton({}, 1, function()
networkManager:toggle_wifi()
end),
})
end
--- Automatically toggle the Wifi toggle when the wifi state changed
networkManager:connect_signal('NetworkManager::WirelessEnabled', function(_, enabled)
if enabled then
dnd:set_enabled()
else
dnd:set_disabled()
end
end)
---TODO:Toggle a general network switch, where should the widget be added?
networkManager:connect_signal('NetworkManager::NetworkingEnabled', function(_, enabled)
--[[ if enabled then
dnd:set_enabled()
else
dnd:set_disabled()
end ]]
end)
--- Automatically delete a lost AP from the list
self.device:connect_signal('NetworkManagerDeviceWireless::AccessPointRemoved', function(_, ap)
self:delete_ap_from_list(ap)
end)
--- Automatically add a new AP to the list, if it is not already in the list
self.device:connect_signal('NetworkManagerDeviceWireless::AccessPointAdded', function(_, ap)
if not self:is_ap_in_list(ap) then
self:add_ap_to_list(ap)
end
end)
--- Automatically resort the list when the active AP changed
--- This is needed because otherwise the active AP would be where the new one currently is in the list
self.device:connect_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', function()
self:resort_wifi_list()
end)
return self
end,
})

View File

@@ -1,377 +0,0 @@
------------------------------------
-- This is the network controller --
------------------------------------
-- Awesome Libs
local abutton = require('awful.button')
local awidget = require('awful.widget')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gtable = require('gears').table
local gfilesystem = require('gears').filesystem
local gcolor = require('gears').color
local lgi = require('lgi')
local wibox = require('wibox')
local base = require('wibox.widget.base')
local NM = lgi.NM
-- Third party libs
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
-- Own libs
local ap_form = require('src.modules.network_controller.ap_form')
local cm = require('src.modules.context_menu.init')
local hover = require('src.tools.hover')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
local access_point = { mt = {} }
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
return (str:gsub('^%s', ''))
end
function access_point:get_access_point_connections(ssid)
local cn = {}
local connections = self.NetworkManagerSettings:ListConnections()
for _, connection_path in ipairs(connections) do
local NetworkManagerSettingsConnection = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = connection_path,
}
if NetworkManagerSettingsConnection.Filename:find(ssid) then
table.insert(cn, NetworkManagerSettingsConnection)
end
end
return cn
end
function access_point:create_profile(ap, password, auto_connect)
local s_wsec = {}
local security = flags_to_security(ap.Flags, ap.WpaFlags, ap.RsnFlags)
if security ~= '' then
if security:match('WPA') then
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk')
s_wsec['auth-alg'] = lgi.GLib.Variant('s', 'open')
s_wsec['psk'] = lgi.GLib.Variant('s', password)
else
s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'None')
s_wsec['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE)
s_wsec['wep-key0'] = lgi.GLib.Variant('s', password)
end
end
return {
['connection'] = {
-- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface),
['uuid'] = lgi.GLib.Variant('s', string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
return string.format('%x', v)
end)),
['id'] = lgi.GLib.Variant('s', NM.utils_ssid_to_utf8(ap.Ssid)),
['type'] = lgi.GLib.Variant('s', '802-11-wireless'),
['autoconnect'] = lgi.GLib.Variant('b', auto_connect),
},
['ipv4'] = {
['method'] = lgi.GLib.Variant('s', 'auto'),
},
['ipv6'] = {
['method'] = lgi.GLib.Variant('s', 'auto'),
},
['802-11-wireless'] = {
['mode'] = lgi.GLib.Variant('s', 'infrastructure'),
},
['802-11-wireless-security'] = s_wsec,
}
end
function access_point:disconnect()
self.NetworkManager:DeactivateConnection(self.NetworkManagerDevice.ActiveConnection)
end
function access_point:connect(ap, password, auto_connect)
local connections = self:get_access_point_connections(NM.utils_ssid_to_utf8(ap.Ssid))
local profile = self:create_profile(self.NetworkManagerAccessPoint, password, auto_connect)
if #connections == 0 then
self.NetworkManager:AddAndActivateConnectionAsync(function(proxy, context, success, fail)
if fail ~= nil then
self:emit_signal('NetworkManager::failed', tostring(fail), tostring(fail.code))
return
end
self:emit_signal('NetworkManager::connected', success)
end, { call_id = 'my-id' }, profile, self.NetworkManagerDevice.object_path,
self.NetworkManagerAccessPoint.object_path)
--88ALYLNxo9Kk*RwRxMfN
else
connections[1]:Update(profile)
self.NetworkManager:ActivateConnectionAsync(function(proxy, context, success, failure)
if failure then
self:emit_signal('NM::AccessPointFailed', tostring(failure))
return
end
self:emit_signal('NM::AccessPointConnected', NM.utils_ssid_to_utf8(ap.Ssid))
end,
{ call_id = 'my-id' }, connections[1].object_path, self.NetworkManagerDevice.object_path,
self.NetworkManagerAccessPoint.object_path)
end
end
function access_point:toggle_connection(ap, password, auto_connect)
if self:is_ap_active(ap) then
self:disconnect()
else
self:connect(ap, password, auto_connect)
end
end
function access_point:is_ap_active(ap)
return ap.object_path == self.NetworkManagerDeviceWireless.ActiveAccessPoint
end
function access_point.new(args)
args = args or {}
if not args.NetworkManagerAccessPoint then return end
local ssid_text = awidget.inputbox {
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid) or
args.NetworkManagerAccessPoint.hw_address or 'Unknown',
halign = 'left',
valign = 'center',
}
local ret = base.make_widget_from_value(wibox.widget {
{
{
{
{
{
image = gcolor.recolor_image(
icondir .. 'wifi-strength-' .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
beautiful.colorscheme.bg_red),
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,
},
{
{
ssid_text,
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(300),
id = 'alias',
},
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 = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.bg_red,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
id = 'background',
shape = beautiful.shape[8],
widget = wibox.container.background,
})
assert(type(ret) == 'table', 'access_point:ret is not a table')
gtable.crush(ret, access_point, true)
ret.NetworkManagerAccessPoint = args.NetworkManagerAccessPoint
ret.NetworkManagerSettings = args.NetworkManagerSettings
ret.NetworkManagerDeviceWireless = args.NetworkManagerDeviceWireless
ret.NetworkManagerDevice = args.NetworkManagerDevice
ret.NetworkManager = args.NetworkManager
ret.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = ret.NetworkManagerAccessPoint.object_path,
}
-- Update the access point strength
ret.NetworkManagerAccessPointProperties:connect_signal(function(_, properties, data)
if data.Strength then
awesome.emit_signal('NM::AccessPointStrength', data.Strength)
if ret.is_ap_active(ret.NetworkManagerAccessPoint.object_path) then
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
beautiful.colorscheme.bg)
else
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg',
beautiful.colorscheme.bg_red)
end
end
end, 'PropertiesChanged')
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
ret.bg = beautiful.colorscheme.bg_red
ret.fg = beautiful.colorscheme.bg
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
beautiful.colorscheme.bg)
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
icondir .. 'link.svg', beautiful.colorscheme.bg)
else
ret.bg = beautiful.colorscheme.bg
ret.fg = beautiful.colorscheme.bg_red
ret:get_children_by_id('icon')[1].image = gcolor.recolor_image(
icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg',
beautiful.colorscheme.bg_red)
ret:get_children_by_id('con')[1].image = gcolor.recolor_image(
icondir .. 'link.svg', beautiful.colorscheme.bg_red)
end
ret.ap_form = ap_form {
screen = args.screen,
NetworkManagerAccessPoint = args.NetworkManagerAccessPoint,
ap = ret,
}
ret.cm = 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 = {
{ -- Connect/Disconnect a device
name = 'ret.device.Connected' and 'Disconnect' or 'Connect',
icon = gcolor.recolor_image('ret.device.Connected' and icondir .. 'link-off.svg' or
icondir .. 'link.svg',
beautiful.colorscheme.bg_red),
callback = function()
ret:toggle_connection(ret.NetworkManagerAccessPoint)
end,
id = 'connected',
},
},
}
ret:buttons(gtable.join(
abutton({}, 1, nil,
function()
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
ret:disconnect()
else
ret.ap_form:popup_toggle()
end
end
),
abutton({}, 3, nil,
function()
ret.cm:toggle()
end
)
))
hover.bg_hover { widget = ret }
return ret
end
function access_point.mt:__call(...)
return access_point.new(...)
end
return setmetatable(access_point, access_point.mt)

View File

@@ -1,244 +0,0 @@
local abutton = require('awful.button')
local aplacement = require('awful.placement')
local apopup = require('awful.popup')
local awidget = require('awful.widget')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gtable = require('gears.table')
local gcolor = require('gears.color')
local gshape = require('gears.shape')
local gfilesystem = require('gears.filesystem')
local NM = require('lgi').NM
local wibox = require('wibox')
local hover = require('src.tools.hover')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
local capi = {
awesome = awesome,
mouse = mouse,
mousegrabber = mousegrabber,
}
local ap_form = { mt = {} }
function ap_form:popup_toggle()
self.visible = not self.visible
end
function ap_form.new(args)
args = args or {}
args.screen = args.screen
local password = awidget.inputbox { hint_text = 'Password...' }
local ret = apopup {
widget = {
{
{ -- Header
{
nil,
{
{
widget = wibox.widget.textbox,
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid),
font = beautiful.user_config.font.specify .. ',extra bold 16',
halign = 'center',
valign = 'center',
},
widget = wibox.container.margin,
margins = dpi(5),
},
{ -- Close button
{
{
widget = wibox.widget.imagebox,
image = gcolor.recolor_image(icondir .. 'close.svg', beautiful.colorscheme.bg),
resize = false,
valign = 'center',
halign = 'center',
},
widget = wibox.container.margin,
margins = dpi(5),
},
widget = wibox.container.background,
shape = beautiful.shape[8],
id = 'close_button',
bg = beautiful.colorscheme.bg_red,
},
layout = wibox.layout.align.horizontal,
},
widget = wibox.container.background,
bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.bg_red,
},
{ -- Form
{ -- Password
widget = wibox.widget.textbox,
text = 'Password',
halign = 'center',
valign = 'center',
},
{
widget = wibox.container.margin,
left = dpi(20),
right = dpi(20),
},
-- Change to inputtextbox container
{
{
{
password,
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 = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.fg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
shape = gshape.rounded_rect,
forced_width = 300,
forced_height = 50,
id = 'password_container',
},
layout = wibox.layout.align.horizontal,
},
{ -- Actions
{ -- Auto connect
{
{
{
checked = false,
shape = beautiful.shape[4],
color = beautiful.colorscheme.bg,
paddings = dpi(3),
check_color = beautiful.colorscheme.bg_red,
border_color = beautiful.colorscheme.bg_red,
border_width = dpi(2),
id = 'checkbox',
widget = wibox.widget.checkbox,
},
widget = wibox.container.constraint,
strategy = 'exact',
width = dpi(30),
height = dpi(30),
},
widget = wibox.container.place,
halign = 'center',
valign = 'center',
},
{
widget = wibox.widget.textbox,
text = 'Auto connect',
halign = 'center',
valign = 'center',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
nil,
{ -- Connect
{
{
{
widget = wibox.widget.textbox,
text = 'Connect',
halign = 'center',
valign = 'center',
},
widget = wibox.container.margin,
margins = dpi(10),
},
widget = wibox.container.background,
bg = beautiful.colorscheme.bg_blue,
fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8],
id = 'connect_button',
},
widget = wibox.container.margin,
margins = dpi(10),
},
layout = wibox.layout.align.horizontal,
},
spacing = dpi(20),
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.margin,
margins = dpi(10),
},
placement = aplacement.centered,
ontop = true,
visible = false,
width = dpi(600),
height = dpi(400),
bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.fg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
type = 'dialog',
screen = args.screen,
}
local password_container = ret.widget:get_children_by_id('password_container')[1]
gtable.crush(ret, ap_form, true)
-- Focus the searchbar when its left clicked
password_container:buttons(gtable.join {
abutton({}, 1, function()
password:focus()
end),
})
--#region Hover signals to change the cursor to a text cursor
local old_cursor, old_wibox
password_container:connect_signal('mouse::enter', function()
local wid = capi.mouse.current_wibox
if wid then
old_cursor, old_wibox = wid.cursor, wid
wid.cursor = 'xterm'
end
end)
password_container:connect_signal('mouse::leave', function()
old_wibox.cursor = old_cursor
old_wibox = nil
end)
--#endregion
local checkbox = ret.widget:get_children_by_id('checkbox')[1]
checkbox:connect_signal('button::press', function()
checkbox.checked = not checkbox.checked
end)
local close_button = ret.widget:get_children_by_id('close_button')[1]
close_button:connect_signal('button::press', function()
ret:popup_toggle()
end)
hover.bg_hover { widget = close_button }
local connect_button = ret.widget:get_children_by_id('connect_button')[1]
connect_button:connect_signal('button::press', function()
password:stop()
args.ap:connect(args.NetworkManagerAccessPoint, password:get_text(),
ret.widget:get_children_by_id('checkbox')[1].checked)
ret:popup_toggle()
end)
hover.bg_hover { widget = connect_button }
return ret
end
function ap_form.mt:__call(...)
return ap_form.new(...)
end
return setmetatable(ap_form, ap_form.mt)

View File

@@ -1,488 +0,0 @@
------------------------------------
-- This is the network controller --
------------------------------------
-- Awesome Libs
local abutton = require('awful.button')
local base = require('wibox.widget.base')
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gshape = require('gears.shape')
local gtable = require('gears.table')
local gtimer = require('gears.timer')
local lgi = require('lgi')
local NM = lgi.NM
local naughty = require('naughty')
local wibox = require('wibox')
-- Third party libs
local rubato = require('src.lib.rubato')
local hover = require('src.tools.hover')
-- Local libs
local access_point = require('src.modules.network_controller.access_point')
local dnd_widget = require('awful.widget.toggle_widget')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
local network = { mt = {} }
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,
}
---Get the wifi and or ethernet proxy and connect to their PropertiesChanged signal
-- The signals will return the following
-- wifi: { "Bitrate", "Strength" }
-- ethernet: { "Carrier", "Speed" }
function network:get_active_device()
--Get all devices
local devices = self._private.NetworkManager:GetDevices()
if (not devices) or (#devices == 0) then return end
-- Loop trough every found device
for _, path in ipairs(devices) do
--Create a new proxy for every device
local NetworkManagerDevice = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device',
path = path,
}
--Check if the device is either a wifi or ethernet device, and if its activated
-- if its activated then its currently in use
if (NetworkManagerDevice.DeviceType == network.DeviceType.WIFI) and
(NetworkManagerDevice.State == network.DeviceState.ACTIVATED) then
-- Set the wifi device as the main device
self._private.NetworkManagerDevice = NetworkManagerDevice
--New wifi proxy to check the bitrate
self._private.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
path = path,
}
-- Watch PropertiesChanged and update the bitrate
local NetworkManagerDeviceWirelessProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = self._private.NetworkManagerDeviceWireless.object_path,
}
NetworkManagerDeviceWirelessProperties:connect_signal(function(_, properties, data)
if data.Bitrate then
self:emit_signal('NM::Bitrate', data.Bitrate)
end
end, 'PropertiesChanged')
-- Watch the StateChanged signal, update and notify when a new AP is connected
self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state)
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.AccessPoint',
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
}
if new_state == network.DeviceState.ACTIVATED then
local ssid = NM.utils_ssid_to_utf8(NetworkManagerAccessPoint.Ssid)
self:emit_signal('NM::AccessPointConnected', ssid, NetworkManagerAccessPoint.Strength)
end
end, 'StateChanged')
elseif (NetworkManagerDevice.DeviceType == network.DeviceType.ETHERNET) and
(NetworkManagerDevice.State == network.DeviceState.ACTIVATED) then
self._private.NetworkManagerDevice = NetworkManagerDevice
self._private.NetworkManagerDeviceWired = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device.Wired',
path = path,
}
if self._private.NetworkManagerDevice.State == network.DeviceState.ACTIVATED then
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
end
-- Connect to the StateChanged signal and notify when the wired connection is ready
self._private.NetworkManagerDevice:connect_signal(function(_, new_state)
if new_state == network.DeviceState.ACTIVATED then
awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed)
elseif new_state == network.DeviceState.DISCONNECTED then
awesome.emit_signal('NM::EthernetStatus', false)
end
end, 'StateChanged')
end
end
end
function network:get_active_ap_ssid()
local d = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint,
}
return NM.utils_ssid_to_utf8(d.Ssid)
end
---Scan for access points and create a widget for each one.
function network:scan_access_points()
if not self._private.NetworkManagerDeviceWireless then return end
local ap_list = self:get_children_by_id('wifi_ap_list')[1]
ap_list:reset()
local ap_table = {}
self._private.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure)
if failure then
naughty.notification {
app_icon = icondir .. 'ethernet.svg',
app_name = 'Network Manager',
title = 'Error: Scan failed!',
message = 'Failed to scan for access points.\n' .. failure,
icon = gcolor.recolor_image(icondir .. 'ethernet.svg', beautiful.colorscheme.bg),
timeout = 5,
}
return
end
-- Get every access point even those who hide their ssid
for _, ap in ipairs(self._private.NetworkManagerDeviceWireless:GetAllAccessPoints()) do
-- Create a new proxy for every ap
local NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.AccessPoint',
path = ap,
}
-- We are only interested in those with a ssid
if NM.utils_ssid_to_utf8(NetworkManagerAccessPoint.Ssid) and NetworkManagerAccessPoint.Strength then
if (ap_table[NetworkManagerAccessPoint.Ssid] == nil) or
NetworkManagerAccessPoint.Strength > ap_table[NetworkManagerAccessPoint.Ssid].Strength then
ap_table[NetworkManagerAccessPoint.Ssid] = NetworkManagerAccessPoint
end
end
end
--sort ap_table first by strength
local sorted_ap_table = {}
for _, NetworkManagerAccessPoint in pairs(ap_table) do
table.insert(sorted_ap_table, NetworkManagerAccessPoint)
end
--sort the table by strength but have the active_ap at the top
table.sort(sorted_ap_table, function(a, b)
if a.object_path == self._private.NetworkManagerDeviceWireless.ActiveAccessPoint then
return true
else
return a.Strength > b.Strength
end
end)
for _, NetworkManagerAccessPoint in ipairs(sorted_ap_table) do
ap_list:add(access_point {
NetworkManagerAccessPoint = NetworkManagerAccessPoint,
NetworkManagerDevice = self._private.NetworkManagerDevice,
NetworkManagerSettings = self._private.NetworkManagerSettings,
NetworkManager = self._private.NetworkManager,
NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless,
})
end
end, { call_id = 'my-id' }, {})
end
---Toggles networking on or off
function network:toggle_wifi()
local enable = not self._private.NetworkManager.WirelessEnabled
self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', enable))
self._private.NetworkManager.WirelessEnabled = { signature = 'b', value = enable }
end
function network.new(args)
args = args or {}
local ret = base.make_widget_from_value(wibox.widget {
{
{
{
{
{
{
{
{
resize = false,
image = gcolor.recolor_image(icondir .. 'menu-down.svg',
beautiful.colorscheme.bg_red),
widget = wibox.widget.imagebox,
valign = 'center',
halign = 'center',
id = 'icon',
},
id = 'center',
halign = 'center',
valign = 'center',
widget = wibox.container.place,
},
{
{
text = 'Wifi Networks',
widget = wibox.widget.textbox,
id = 'ap_name',
},
margins = dpi(5),
widget = wibox.container.margin,
},
id = 'wifi',
layout = wibox.layout.fixed.horizontal,
},
id = 'wifi_bg',
bg = beautiful.colorscheme.bg1,
fg = beautiful.colorscheme.bg_red,
shape = beautiful.shape[4],
widget = wibox.container.background,
},
id = 'wifi_margin',
widget = wibox.container.margin,
},
{
id = 'wifi_list',
{
{
step = dpi(50),
spacing = dpi(10),
layout = require('src.lib.overflow_widget.overflow').vertical,
scrollbar_width = 0,
id = 'wifi_ap_list',
},
id = 'margin',
margins = dpi(10),
widget = wibox.container.margin,
},
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
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,
},
{
{ -- action buttons
{
dnd_widget {
color = beautiful.colorscheme.bg_red,
size = dpi(40),
},
id = 'dnd',
widget = wibox.container.place,
valign = 'center',
halign = 'center',
},
nil,
{ -- refresh
{
{
image = gcolor.recolor_image(icondir .. 'refresh.svg',
beautiful.colorscheme.bg_red),
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 = beautiful.colorscheme.border_color,
shape = beautiful.shape[4],
bg = beautiful.colorscheme.bg,
widget = wibox.container.background,
id = 'refresh',
},
layout = wibox.layout.align.horizontal,
},
widget = wibox.container.margin,
top = dpi(10),
id = 'action_buttons',
},
id = 'layout1',
layout = wibox.layout.fixed.vertical,
},
id = 'margin',
margins = dpi(15),
widget = wibox.container.margin,
},
shape = beautiful.shape[8],
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
bg = beautiful.colorscheme.bg,
id = 'background',
widget = wibox.container.background,
},
width = dpi(400),
strategy = 'exact',
widget = wibox.container.constraint,
})
assert(type(ret) == 'table', 'NetworkManager is not running')
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
dnd:connect_signal('dnd::toggle', function(enable)
ret:toggle_wifi()
end)
gtable.crush(ret, network, true)
--#region Wifi Proxies
ret._private.NetworkManager = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager',
path = '/org/freedesktop/NetworkManager',
}
ret._private.NetworkManagerSettings = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings',
path = '/org/freedesktop/NetworkManager/Settings',
}
ret._private.NetworkManagerProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = '/org/freedesktop/NetworkManager',
}
ret._private.NetworkManagerProperties:connect_signal(function(_, properties, data)
if data.WirelessEnabled ~= nil and ret._private.WirelessEnabled ~= data.WirelessEnabled then
ret._private.WirelessEnabled = data.WirelessEnabled
if ret._private.WirelessEnabled then
dnd:set_enabled()
else
dnd:set_disabled()
end
ret:emit_signal('NetworkManager::status', ret._private.WirelessEnabled)
if data.WirelessEnabled then
gtimer {
timeout = 5,
autostart = true,
call_now = false,
single_shot = true,
callback = function()
ret:scan_access_points()
end,
}
end
end
end, 'PropertiesChanged')
ret:get_active_device()
ret:scan_access_points()
if ret._private.NetworkManager.WirelessEnabled then
dnd:set_enabled()
else
dnd:set_disabled()
end
--#endregion
--#region Dropdown logic
local wifi_margin = ret:get_children_by_id('wifi_margin')[1]
local wifi_list = ret:get_children_by_id('wifi_list')[1]
local wifi = ret:get_children_by_id('wifi')[1].center
local 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(
abutton({}, 1, nil,
function()
if wifi_list.forced_height == 0 then
if not ret:get_children_by_id('wifi_ap_list')[1].children then
return
end
local size = (5 * 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',
beautiful.colorscheme.bg_red))
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',
beautiful.colorscheme.bg_red))
end
end
)
))
hover.bg_hover { widget = wifi_margin.wifi_bg }
--#endregion
local refresh_button = ret:get_children_by_id('refresh')[1]
refresh_button:buttons(gtable.join(
abutton({}, 1, nil, function()
ret:scan_access_points()
end)
))
hover.bg_hover { widget = refresh_button }
return ret
end
function network.mt:__call(...)
return network.new(...)
end
return setmetatable(network, network.mt)

View File

@@ -1,23 +1,24 @@
------------------------------------- local os = os
-- This is the notification-center -- local setmetatable = setmetatable
-------------------------------------
-- Awesome Libs -- Awesome Libs
local dpi = require('beautiful').xresources.apply_dpi local abutton = require('awful.button')
local wibox = require('wibox')
local naughty = require('naughty')
local gtimer = require('gears.timer')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color') local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem') local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table') local gtable = require('gears.table')
local abutton = require('awful.button') local gtimer = require('gears.timer')
local naughty = require('naughty')
local wibox = require('wibox')
-- Local Libs
local hover = require('src.tools.hover') local hover = require('src.tools.hover')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/' local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/'
return setmetatable({}, { local instance = nil
instance = setmetatable({}, {
__call = function() __call = function()
local ret = wibox.widget { local ret = wibox.widget {
layout = require('src.lib.overflow_widget.overflow').vertical, layout = require('src.lib.overflow_widget.overflow').vertical,
@@ -61,13 +62,13 @@ return setmetatable({}, {
notification = n, notification = n,
widget = naughty.widget.title, widget = naughty.widget.title,
markup = [[<span foreground="]] .. markup = [[<span foreground="]] ..
beautiful.colorscheme.bg .. [[" font="JetBrainsMono Nerd Font, Bold 16">]] .. (n.app_name or beautiful.colorscheme.bg .. [[" font="]] .. beautiful.user_config.font .. ' bold 12' .. [[">]] .. (n.app_name or
'Unknown App') .. [[</span> | <span font="JetBrainsMono Nerd Font, Regular 16">]] .. (n.title or 'System Notification') .. [[</span>]], 'Unknown App') .. [[</span> | <span font="]] .. beautiful.user_config.font .. ' regular 12' .. [[">]] .. (n.title or 'System Notification') .. [[</span>]],
halign = 'left', halign = 'left',
valign = 'center', valign = 'center',
}, },
widget = wibox.container.constraint, widget = wibox.container.constraint,
width = dpi(430), width = dpi(250),
height = dpi(35), height = dpi(35),
strategy = 'max', strategy = 'max',
}, },
@@ -83,7 +84,7 @@ return setmetatable({}, {
{ -- Clock { -- Clock
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
test = 'now', test = 'now',
font = 'JetBrainsMono Nerd Font, Bold 12', font = beautiful.user_config.font .. ' bold 12',
fg = beautiful.colorscheme.bg, fg = beautiful.colorscheme.bg,
halign = 'center', halign = 'center',
valign = 'center', valign = 'center',
@@ -159,7 +160,7 @@ return setmetatable({}, {
{ {
notification = n, notification = n,
widget = naughty.widget.message, widget = naughty.widget.message,
font = 'JetBrainsMono Nerd Font, Regular 10', font = beautiful.user_config.font .. ' regular 10',
halign = 'left', halign = 'left',
valign = 'center', valign = 'center',
}, },
@@ -170,15 +171,6 @@ return setmetatable({}, {
spacing = dpi(15), spacing = dpi(15),
layout = wibox.layout.fixed.horizontal, layout = wibox.layout.fixed.horizontal,
}, },
{ -- Spacer
{
widget = wibox.container.background,
bg = beautiful.colorscheme.bg,
},
widget = wibox.container.constraint,
strategy = 'exact',
height = dpi(2),
},
spacing = dpi(15), spacing = dpi(15),
id = 'main_layout', id = 'main_layout',
layout = wibox.layout.fixed.vertical, layout = wibox.layout.fixed.vertical,
@@ -244,3 +236,4 @@ return setmetatable({}, {
return ret return ret
end, end,
}) })
return instance

View File

@@ -15,7 +15,7 @@ local rubato = require('src.lib.rubato')
-- Own Libs -- Own Libs
local audio = require('src.tools.helpers.audio') local audio = require('src.tools.helpers.audio')
local backlight = require('src.tools.helpers.backlight') local backlight_helper = require('src.tools.helpers.backlight')
--local battery = require('src.tools.helpers.battery') --local battery = require('src.tools.helpers.battery')
local cpu_usage = require('src.tools.helpers.cpu_usage') local cpu_usage = require('src.tools.helpers.cpu_usage')
local cpu_temp = require('src.tools.helpers.cpu_temp') local cpu_temp = require('src.tools.helpers.cpu_temp')
@@ -26,250 +26,277 @@ local gpu_temp = require('src.tools.helpers.gpu_temp')
-- Icon directory path -- Icon directory path
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/' local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/'
return setmetatable({}, { __call = function() local capi = {
awesome = awesome,
}
---Creates a layout with bar widgets based on the given table return setmetatable({}, {
---@param widget_table table __call = function()
---@return table ---Creates a layout with bar widgets based on the given table
local function create_bar_layout(widget_table) ---@param widget_table table
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) } ---@return table
local function create_bar_layout(widget_table)
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
for _, widget in pairs(widget_table) do for _, widget in pairs(widget_table) do
local w = base.make_widget_from_value { local w = base.make_widget_from_value {
{
{ {
{ {
{ --Bar {
color = beautiful.colorscheme.bg_teal, { --Bar
background_color = beautiful.colorscheme.bg1, color = beautiful.colorscheme.bg_teal,
max_value = 100, background_color = beautiful.colorscheme.bg1,
value = 0, max_value = 100,
forced_height = dpi(8), value = 0,
shape = function(cr) forced_height = dpi(8),
gears.shape.rounded_bar(cr, dpi(58), dpi(8)) shape = function(cr)
end, gears.shape.rounded_bar(cr, dpi(58), dpi(8))
id = 'progress_role', end,
widget = wibox.widget.progressbar, id = 'progress_role',
widget = wibox.widget.progressbar,
},
halign = 'center',
valign = 'center',
widget = wibox.container.place,
}, },
direction = 'east',
widget = wibox.container.rotate,
},
widget = wibox.container.constraint,
height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58
width = dpi(24),
strategy = 'exact',
},
{
{ --Icon
id = 'image_role',
halign = 'center', halign = 'center',
valign = 'center', valign = 'center',
widget = wibox.container.place, widget = wibox.widget.imagebox,
}, },
direction = 'east', height = dpi(24),
widget = wibox.container.rotate, width = dpi(24),
widget = wibox.container.constraint,
}, },
widget = wibox.container.constraint, spacing = dpi(10),
height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 layout = wibox.layout.fixed.vertical,
width = dpi(24), }
strategy = 'exact',
},
{
{ --Icon
id = 'image_role',
halign = 'center',
valign = 'center',
widget = wibox.widget.imagebox,
},
height = dpi(24),
width = dpi(24),
widget = wibox.container.constraint,
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
}
assert(type(w) == 'table', 'Widget creation failed') assert(type(w) == 'table', 'Widget creation failed')
local bar = w:get_children_by_id('progress_role')[1] local bar = w:get_children_by_id('progress_role')[1]
local rubato_timer = rubato.timed { local rubato_timer = rubato.timed {
duration = 1, duration = 1,
pos = bar.value, pos = bar.value,
easing = rubato.linear, easing = rubato.linear,
subscribed = function(v) subscribed = function(v)
bar.value = v bar.value = v
end, end,
} }
local tooltip = awful.tooltip { local tooltip = awful.tooltip {
objects = { w }, objects = { w },
mode = 'inside', mode = 'inside',
preferred_alignments = 'middle', preferred_alignments = 'middle',
margins = dpi(10), margins = dpi(10),
} }
if widget == 'cpu_usage' then if widget == 'cpu_usage' then
cpu_usage:connect_signal('update::cpu_usage', function(_, v) cpu_usage:connect_signal('update::cpu_usage', function(_, v)
if not v then return nil end if not v then return nil end
tooltip.text = 'CPU Usage: ' .. v .. '%' tooltip.text = 'CPU Usage: ' .. v .. '%'
rubato_timer.target = v rubato_timer.target = v
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg', w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg',
beautiful.colorscheme.bg_teal) beautiful.colorscheme.bg_teal)
end) end)
elseif widget == 'cpu_temp' then elseif widget == 'cpu_temp' then
cpu_temp:connect_signal('update::cpu_temp', function(_, v) cpu_temp:connect_signal('update::cpu_temp', function(_, v)
if not v then return nil end if not v then return nil end
local temp_icon local temp_icon
if v < 50 then if v < 50 then
temp_icon = icondir .. 'cpu/thermometer-low.svg'
elseif v >= 50 and v < 80 then
temp_icon = icondir .. 'cpu/thermometer.svg'
elseif v >= 80 then
temp_icon = icondir .. 'cpu/thermometer-high.svg'
end
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
beautiful.colorscheme.bg_blue)
tooltip.text = 'CPU Temp: ' .. v .. '°C'
rubato_timer.target = v
end)
elseif widget == 'ram_usage' then
ram:connect_signal('update::ram_widget', function(_, MemTotal, _, MemAvailable)
if not MemTotal and MemAvailable then return nil end
if not MemTotal or not MemAvailable then return end
local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
tooltip.text = 'RAM Usage: ' .. ram_usage .. '%'
rubato_timer.target = ram_usage
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/ram.svg',
beautiful.colorscheme.bg_red)
end)
elseif widget == 'gpu_usage' then
gpu_usage:connect_signal('update::gpu_usage', function(_, v)
if not v then return nil end
tooltip.text = 'GPU Usage: ' .. v .. '%'
rubato_timer.target = tonumber(v)
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/gpu.svg',
beautiful.colorscheme.bg_green)
end)
elseif widget == 'gpu_temp' then
gpu_temp:connect_signal('update::gpu_temp', function(_, v)
if not v then return nil end
local temp_icon, temp_num
if v then
temp_num = tonumber(v)
if temp_num < 50 then
temp_icon = icondir .. 'cpu/thermometer-low.svg' temp_icon = icondir .. 'cpu/thermometer-low.svg'
elseif temp_num >= 50 and temp_num < 80 then elseif v >= 50 and v < 80 then
temp_icon = icondir .. 'cpu/thermometer.svg' temp_icon = icondir .. 'cpu/thermometer.svg'
elseif temp_num >= 80 then elseif v >= 80 then
temp_icon = icondir .. 'cpu/thermometer-high.svg' temp_icon = icondir .. 'cpu/thermometer-high.svg'
end end
else w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
temp_num = 'NaN' beautiful.colorscheme.bg_blue)
temp_icon = icondir .. 'cpu/thermometer-low.svg' tooltip.text = 'CPU Temp: ' .. v .. '°C'
end rubato_timer.target = v
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon, end)
beautiful.colorscheme.bg_green) elseif widget == 'ram_usage' then
tooltip.text = 'GPU Temp: ' .. temp_num .. '°C' ram:connect_signal('update::ram_widget', function(_, MemTotal, _, MemAvailable)
rubato_timer.target = temp_num if not MemTotal and MemAvailable then return nil end
end) if not MemTotal or not MemAvailable then return end
elseif widget == 'volume' then local ram_usage = math.floor(((MemTotal - MemAvailable) / MemTotal * 100) + 0.5)
audio:connect_signal('sink::get', function(_, muted, volume) tooltip.text = 'RAM Usage: ' .. ram_usage .. '%'
if not volume and muted then return nil end rubato_timer.target = ram_usage
local icon = icondir .. 'audio/volume' w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/ram.svg',
volume = tonumber(volume) beautiful.colorscheme.bg_red)
if not volume then end)
return elseif widget == 'gpu_usage' then
end gpu_usage:connect_signal('update::gpu_usage', function(_, v)
if muted then if not v then return nil end
icon = icon .. '-mute' tooltip.text = 'GPU Usage: ' .. v .. '%'
else rubato_timer.target = v
if volume < 1 then w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/gpu.svg',
icon = icon .. '-mute' beautiful.colorscheme.bg_green)
elseif volume >= 1 and volume < 34 then end)
icon = icon .. '-low' elseif widget == 'gpu_temp' then
elseif volume >= 34 and volume < 67 then gpu_temp:connect_signal('update::gpu_temp', function(_, v)
icon = icon .. '-medium' if not v then return nil end
elseif volume >= 67 then local temp_icon, temp_num
icon = icon .. '-high'
if v then
temp_num = tonumber(v)
if temp_num < 50 then
temp_icon = icondir .. 'cpu/thermometer-low.svg'
elseif temp_num >= 50 and temp_num < 80 then
temp_icon = icondir .. 'cpu/thermometer.svg'
elseif temp_num >= 80 then
temp_icon = icondir .. 'cpu/thermometer-high.svg'
end
else
temp_num = 'NaN'
temp_icon = icondir .. 'cpu/thermometer-low.svg'
end end
end w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon,
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', beautiful.colorscheme.bg_green)
beautiful.colorscheme.bg_yellow) tooltip.text = 'GPU Temp: ' .. temp_num .. '°C'
tooltip.text = 'Volume: ' .. volume .. '%' rubato_timer.target = temp_num
rubato_timer.target = volume end)
end) elseif widget == 'volume' then
elseif widget == 'microphone' then audio:connect_signal('sink::get', function(_, muted, volume)
audio:connect_signal('source::get', function(_, muted, volume) if not volume and muted then return nil end
if not volume and muted then return nil end local icon = icondir .. 'audio/volume'
if not volume then volume = tonumber(volume)
return if not volume then
end return
local icon = icondir .. 'audio/microphone' end
volume = tonumber(volume) if muted then
if not volume then icon = icon .. '-mute'
return else
end if volume < 1 then
if muted or (volume < 1) then icon = icon .. '-mute'
icon = icon .. '-off' elseif volume >= 1 and volume < 34 then
end icon = icon .. '-low'
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', elseif volume >= 34 and volume < 67 then
beautiful.colorscheme.bg_blue) icon = icon .. '-medium'
tooltip.text = 'Microphone: ' .. volume .. '%' elseif volume >= 67 then
rubato_timer.target = volume icon = icon .. '-high'
end) end
elseif widget == 'backlight' then end
backlight:connect_signal('brightness::get', function(_, v) w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
if not v then return nil end beautiful.colorscheme.bg_yellow)
local icon = icondir .. 'brightness' tooltip.text = 'Volume: ' .. volume .. '%'
if v >= 0 and v < 34 then rubato_timer.target = volume
icon = icon .. '-low' end)
elseif v >= 34 and v < 67 then elseif widget == 'microphone' then
icon = icon .. '-medium' audio:connect_signal('source::get', function(_, muted, volume)
elseif v >= 67 then if not volume and muted then return nil end
icon = icon .. '-high' if not volume then
end return
w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon .. '.svg', end
beautiful.colorscheme.bg_purple)) local icon = icondir .. 'audio/microphone'
tooltip.text = 'Backlight: ' .. v .. '%' volume = tonumber(volume)
rubato_timer.target = v if not volume then
end) return
elseif widget == 'battery' then end
--[[ battery:connect_signal('update::battery_widget', function(battery, battery_icon) if muted or (volume < 1) then
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(battery_icon, icon = icon .. '-off'
beautiful.colorscheme.bg_purple) end
tooltip.text = 'Battery: ' .. battery .. '%' w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg',
rubato_timer.target = battery beautiful.colorscheme.bg_blue)
end) ]] tooltip.text = 'Microphone: ' .. volume .. '%'
rubato_timer.target = volume
end)
elseif widget == 'backlight' then
backlight_helper:connect_signal('brightness_changed', function()
backlight_helper.brightness_get_async(function(brightness)
if not brightness then return end
brightness = math.floor((tonumber(brightness) / (backlight_helper.brightness_max or 24000) * 100) + 0.5)
local icon = icondir .. 'brightness/brightness'
if brightness >= 0 and brightness < 34 then
icon = icon .. '-low.svg'
elseif brightness >= 34 and brightness < 67 then
icon = icon .. '-medium.svg'
elseif brightness >= 67 then
icon = icon .. '-high.svg'
end
w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon,
beautiful.colorscheme.bg_purple))
tooltip.text = 'Backlight: ' .. brightness .. '%'
rubato_timer.target = brightness
end)
end)
backlight_helper.brightness_get_async(function(brightness)
if not brightness then return end
brightness = math.floor((tonumber(brightness) / (backlight_helper.brightness_max or 24000) * 100) + 0.5)
local icon = icondir .. 'brightness/brightness'
if brightness >= 0 and brightness < 34 then
icon = icon .. '-low.svg'
elseif brightness >= 34 and brightness < 67 then
icon = icon .. '-medium.svg'
elseif brightness >= 67 then
icon = icon .. '-high.svg'
end
w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon,
beautiful.colorscheme.bg_purple))
tooltip.text = 'Backlight: ' .. brightness .. '%'
rubato_timer.target = brightness
end)
elseif widget == 'battery' then
capi.awesome.connect_signal('update::battery_widget', function(battery, battery_icon)
w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(battery_icon,
beautiful.colorscheme.bg_purple)
tooltip.text = 'Battery: ' .. battery .. '%'
rubato_timer.target = battery
end)
end
table.insert(bar_layout, w)
end end
table.insert(bar_layout, w) return bar_layout
end end
return bar_layout return wibox.widget {
end
return wibox.widget {
{
{ {
{ {
{ {
{ {
create_bar_layout(beautiful.user_config.status_bar_widgets), {
width = dpi(480), create_bar_layout(beautiful.user_config.status_bar_widgets),
strategy = 'exact', width = dpi(480),
widget = wibox.container.constraint, strategy = 'exact',
widget = wibox.container.constraint,
},
widget = wibox.container.place,
}, },
widget = wibox.container.place, magins = dpi(10),
layout = wibox.container.margin,
}, },
magins = dpi(10), border_color = beautiful.colorscheme.border_color,
layout = wibox.container.margin, border_width = dpi(2),
shape = beautiful.shape[12],
widget = wibox.container.background,
}, },
border_color = beautiful.colorscheme.border_color, widget = wibox.container.constraint,
border_width = dpi(2), height = dpi(120),
shape = beautiful.shape[12], width = dpi(500),
widget = wibox.container.background, strategy = 'exact',
}, },
widget = wibox.container.constraint, top = dpi(10),
height = dpi(120), left = dpi(20),
width = dpi(500), right = dpi(20),
strategy = 'exact', bottom = dpi(10),
}, widget = wibox.container.margin,
top = dpi(10), }
left = dpi(20), end,
right = dpi(20), })
bottom = dpi(10),
widget = wibox.container.margin,
}
end, })

View File

View File

@@ -1,6 +1,4 @@
-------------------------------- local setmetatable = setmetatable
-- This is the network widget --
--------------------------------
-- Awesome Libs -- Awesome Libs
local abutton = require('awful.button') local abutton = require('awful.button')
@@ -12,6 +10,7 @@ local dpi = require('beautiful').xresources.apply_dpi
local gfilesystem = require('gears.filesystem') local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table') local gtable = require('gears.table')
local wibox = require('wibox') local wibox = require('wibox')
local gsurface = require('gears.surface')
local hover = require('src.tools.hover') local hover = require('src.tools.hover')
@@ -106,110 +105,107 @@ end
function powermenu:toggle() function powermenu:toggle()
self.keygrabber:start() self.keygrabber:start()
self.visible = not self.visible self.w.visible = not self.w.visible
end
function powermenu.new()
local w = wibox {
widget = {
{
{
{
{
image = icondir .. 'defaultpfp.svg',
resize = true,
clip_shape = beautiful.shape[30],
valign = 'center',
halign = 'center',
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(200),
height = dpi(200),
strategy = 'exact',
},
{
halign = 'center',
valign = 'center',
font = 'JetBrains Mono Bold 30',
id = 'text_role',
widget = wibox.widget.textbox,
},
spacing = dpi(50),
layout = wibox.layout.fixed.vertical,
},
{
{
get_button('shutdown'),
get_button('reboot'),
get_button('logout'),
get_button('lock'),
get_button('suspend'),
spacing = dpi(30),
layout = wibox.layout.fixed.horizontal,
},
widget = wibox.container.place,
},
spacing = dpi(50),
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.place,
},
screen = capi.screen.primary,
type = 'splash',
visible = false,
ontop = true,
bg = beautiful.colorscheme.bg .. '88',
height = capi.screen.primary.geometry.height,
width = capi.screen.primary.geometry.width,
x = capi.screen.primary.geometry.x,
y = capi.screen.primary.geometry.y,
}
gtable.crush(w, powermenu, true)
w:buttons { gtable.join(
abutton({}, 3, function()
w:toggle()
w.keygrabber:stop()
end)
), }
w.keygrabber = akeygrabber {
autostart = false,
stop_event = 'release',
stop_key = 'Escape',
keybindings = {
akey {
modifiers = {},
key = 'Escape',
on_press = function()
w:toggle()
end,
},
},
}
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
-- and copy it to the assets folder
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userPfp'", function(stdout)
if stdout then
w:get_children_by_id('icon_role')[1].image = stdout:gsub('\n', '')
else
w:get_children_by_id('icon_role')[1].image = icondir .. 'defaultpfp.svg'
end
end)
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userName' '" .. beautiful.user_config.namestyle .. "'", function(stdout)
w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '')
end)
return w
end end
if instance == nil then if instance == nil then
instance = powermenu.new() instance = setmetatable(powermenu, {
__call = function(self)
self.w = wibox {
widget = {
{
{
{
{
image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png'),
resize = true,
clip_shape = beautiful.shape[30],
valign = 'center',
halign = 'center',
id = 'icon_role',
widget = wibox.widget.imagebox,
},
widget = wibox.container.constraint,
width = dpi(200),
height = dpi(200),
strategy = 'exact',
},
{
halign = 'center',
valign = 'center',
font = 'JetBrains Mono Bold 30',
id = 'text_role',
widget = wibox.widget.textbox,
},
spacing = dpi(50),
layout = wibox.layout.fixed.vertical,
},
{
{
get_button('shutdown'),
get_button('reboot'),
get_button('logout'),
get_button('lock'),
get_button('suspend'),
spacing = dpi(30),
layout = wibox.layout.fixed.horizontal,
},
widget = wibox.container.place,
},
spacing = dpi(50),
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.place,
},
screen = capi.screen.primary,
type = 'splash',
visible = false,
ontop = true,
bg = beautiful.colorscheme.bg .. '88',
height = capi.screen.primary.geometry.height,
width = capi.screen.primary.geometry.width,
x = capi.screen.primary.geometry.x,
y = capi.screen.primary.geometry.y,
}
self.w:buttons { gtable.join(
abutton({}, 3, function()
self:toggle()
self.keygrabber:stop()
end)
), }
self.keygrabber = akeygrabber {
autostart = false,
stop_event = 'release',
stop_key = 'Escape',
keybindings = {
akey {
modifiers = {},
key = 'Escape',
on_press = function()
self:toggle()
end,
},
},
}
-- Get the profile script from /var/lib/AccountsService/icons/${USER}
-- and copy it to the assets folder
-- TODO: If the user doesnt have AccountsService look into $HOME/.faces
--[[ aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userPfp'", function(stdout)
print(stdout)
if stdout then
self.w:get_children_by_id('icon_role')[1].image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png')
else
self.w:get_children_by_id('icon_role')[1].image = icondir .. 'defaultpfp.svg'
end
end) ]]
aspawn.easy_async_with_shell("./.config/awesome/src/scripts/pfp.sh 'userName' '" .. beautiful.user_config.namestyle .. "'", function(stdout)
self.w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '')
end)
end,
})
end end
return instance return instance

View File

@@ -17,139 +17,117 @@ local base = require('wibox.widget.base')
local gtimer = require('gears.timer') local gtimer = require('gears.timer')
local cairo = require('lgi').cairo local cairo = require('lgi').cairo
local awidget = require('awful.widget') local awidget = require('awful.widget')
local ascreenshot = require('awful.screenshot')
local capi = { local wtemplate = require('wibox.template')
awesome = awesome, local akeygrabber = require('awful.keygrabber')
client = client, local akey = require('awful.key')
mouse = mouse, local abutton = require('awful.button')
} local aclient = require('awful.client')
local awful = require('awful')
--local window_elements = require("src.modules.window_switcher.window_elements")()
--[[ return function(s)
local window_switcher_list = wibox.widget {
window_elements,
margins = dpi(20),
widget = wibox.container.margin
}
local window_switcher_container = awful.popup {
widget = wibox.container.background,
ontop = true,
visible = false,
stretch = false,
screen = s,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
placement = awful.placement.centered,
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2)
}
window_switcher_container:setup {
window_switcher_list,
layout = wibox.layout.fixed.vertical
}
capi.awesome.connect_signal(
"toggle_window_switcher",
function()
if capi.mouse.screen == s then
window_switcher_container.visible = not window_switcher_container.visible
end
end
)
end ]]
local client_preview = {} local client_preview = {}
local instance = nil
if not instance then
instance = setmetatable(client_preview, {
__call = function(self, s)
function client_preview:toggle() self.popup = apopup {
self.visible = not self.visible widget = awidget.tasklist {
end screen = 1,
layout = wibox.layout.fixed.horizontal,
return setmetatable(client_preview, { filter = awidget.tasklist.filter.alltags,
__call = function(...) style = {
local args = ... font = beautiful.user_config.font .. ' regular 12',
},
local w = gobject {} widget_template = wibox.template {
gtable.crush(w, client_preview, true)
--[[ local tl = awidget.tasklist {
screen = 1,
layout = wibox.layout.fixed.horizontal,
filter = awidget.tasklist.filter.alltags,
update_function = function(widget, _, _, _, clients)
widget:reset()
for _, c in ipairs(clients) do
local tw = wibox.widget {
{ {
{ {
{ {
{ {
widget = wibox.widget.imagebox, {
resize = true, { -- icon and text
id = c.instance, {
{
widget = wibox.widget.imagebox,
valign = 'center',
halign = 'center',
id = 'icon_role',
},
{
widget = wibox.widget.textbox,
id = 'text_role',
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
widget = wibox.container.constraint,
height = dpi(32),
width = dpi(256),
},
{ -- preview
id = 'screenshot',
width = dpi(256),
widget = wibox.container.constraint,
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.place,
}, },
widget = wibox.container.constraint, widget = wibox.container.margin,
height = dpi(256), margins = dpi(20),
strategy = 'exact',
}, },
widget = wibox.container.place, widget = wibox.container.background,
border_color = beautiful.colorscheme.border_color,
id = 'border',
border_width = dpi(2),
bg = beautiful.colorscheme.bg1,
shape = beautiful.shape[8],
}, },
widget = wibox.container.margin, widget = wibox.container.margin,
margins = dpi(20), margins = dpi(20),
}, },
bg = beautiful.colorscheme.bg,
widget = wibox.container.background, widget = wibox.container.background,
bg = '#414141', create_callback = function(sself, c)
id = c.pid, local ss = ascreenshot {
shape = gshape.rounded_rect, client = c,
} }
ss:refresh()
gtimer { local ib = ss.content_widget
timeout = 1 / 24, ib.clip_shape = beautiful.shape[12]
autostart = true, ib.valign = 'center'
callback = function() ib.halign = 'center'
local content = gsurface(c.content) sself:get_widget():get_children_by_id('screenshot')[1].widget = ib
local cr = cairo.Context(content) end,
local x, y, w, h = cr:clip_extents() update_callback = function(sself, c)
local img = cairo.ImageSurface.create(cairo.Format.ARGB32, w - x, h - y) if c.active and self.popup.visible then
cr = cairo.Context(img) local ss = ascreenshot {
cr:set_source_surface(content, 0, 0) client = c,
cr.operator = cairo.Operator.SOURCE }
cr:paint() ss:refresh()
local cont = tw:get_children_by_id('icon_role')[1] local ib = ss.content_widget
if cont then ib.clip_shape = beautiful.shape[12]
cont.image = gsurface.load(img) ib.valign = 'center'
return ib.halign = 'center'
sself:get_widget():get_children_by_id('screenshot')[1].widget = ib
sself:get_widget():get_children_by_id('border')[1].border_color = beautiful.colorscheme.bg_purple
else
sself:get_widget():get_children_by_id('border')[1].border_color = beautiful.colorscheme.border_color
end end
end, end,
} },
},
widget:add(tw) ontop = true,
end visible = false,
screen = s,
return widget bg = beautiful.colorscheme.bg,
end, border_color = beautiful.colorscheme.border_color,
} ]] border_width = dpi(2),
placement = aplacement.centered,
w.popup = apopup { }
widget = {}, end,
ontop = true, })
visible = true, end
screen = args.screen, return instance
placement = aplacement.centered,
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
}
return w
end,
})

View File

@@ -1,252 +0,0 @@
---------------------------------
-- This is the window_switcher --
---------------------------------
-- Awesome Libs
local awful = require('awful')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gears = require('gears')
local wibox = require('wibox')
local color = require('src.lib.color')
local rubato = require('src.lib.rubato')
local capi = {
awesome = awesome,
client = client,
}
return function()
local elements = wibox.widget {
layout = wibox.layout.fixed.horizontal,
spacing = dpi(20),
id = 'switcher',
}
local selected = 0
local function create_elements(fn)
fn = fn or ''
elements:reset()
local clients = capi.client.get()
local clients_sorted = {}
if capi.client.focus then
clients_sorted[1] = capi.client.focus
end
for _, client in ipairs(clients) do
if client ~= clients_sorted[1] then
table.insert(clients_sorted, client)
end
end
selected = selected
for _, client in ipairs(clients_sorted) do
local window_element = wibox.widget {
{
{
{
{ -- Icon
{
id = 'icon',
--!ADD FALLBACK ICON!--
image = gears.surface(client.icon),
valign = 'center',
halign = 'center',
widget = wibox.widget.imagebox,
},
width = dpi(100),
height = dpi(100),
id = 'icon_const',
strategy = 'exact',
widget = wibox.container.constraint,
},
{
{
text = client.name,
id = 'label',
widget = wibox.widget.textbox,
},
id = 'place',
valign = 'center',
halign = 'center',
widget = wibox.container.place,
},
id = 'layout1',
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
},
id = 'box',
width = dpi(150),
height = dpi(150),
strategy = 'exact',
widget = wibox.container.constraint,
},
id = 'margin',
margins = dpi(20),
widget = wibox.container.margin,
},
shape = beautiful.shape[12],
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
bg = beautiful.colorscheme.bg,
fg = beautiful.colorscheme.bg_green,
widget = wibox.container.background,
}
elements:add(window_element)
end
if fn == 'next' then
if selected >= #clients_sorted then
selected = 1
else
selected = selected + 1
end
for i, element in ipairs(elements.children) do
-- Background rubato init
local r_timed_bg = rubato.timed { duration = 0.5 }
local g_timed_bg = rubato.timed { duration = 0.5 }
local b_timed_bg = rubato.timed { duration = 0.5 }
-- starting color
r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg)
-- Foreground rubato init
local r_timed_fg = rubato.timed { duration = 0.5 }
local g_timed_fg = rubato.timed { duration = 0.5 }
local b_timed_fg = rubato.timed { duration = 0.5 }
-- starting color
r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg_green)
-- Border rubato init
local r_timed_border = rubato.timed { duration = 0.5 }
local g_timed_border = rubato.timed { duration = 0.5 }
local b_timed_border = rubato.timed { duration = 0.5 }
-- starting color
r_timed_border.pos, g_timed_border.pos, b_timed_border.pos = color.utils.hex_to_rgba(beautiful.colorscheme
.border_color)
local function set_bg(newbg)
r_timed_bg.target, g_timed_bg.target, b_timed_bg.target = color.utils.hex_to_rgba(newbg)
end
local function set_fg(newfg)
r_timed_fg.target, g_timed_fg.target, b_timed_fg.target = color.utils.hex_to_rgba(newfg)
end
local function set_border(newborder)
r_timed_border.target, g_timed_border.target, b_timed_border.target = color.utils.hex_to_rgba(newborder)
end
local function update_bg()
element:set_bg('#' .. color.utils.rgba_to_hex { r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos })
end
local function update_fg()
element:set_fg('#' .. color.utils.rgba_to_hex { r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos })
end
local function update_border()
element.border_color = '#' ..
color.utils.rgba_to_hex { r_timed_border.pos, g_timed_border.pos, b_timed_border.pos }
end
-- Subscribe to the function bg and fg
r_timed_bg:subscribe(update_bg)
g_timed_bg:subscribe(update_bg)
b_timed_bg:subscribe(update_bg)
r_timed_fg:subscribe(update_fg)
g_timed_fg:subscribe(update_fg)
b_timed_fg:subscribe(update_fg)
r_timed_border:subscribe(update_border)
g_timed_border:subscribe(update_border)
b_timed_border:subscribe(update_border)
if i == selected then
r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg)
r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg_green)
r_timed_border.pos, g_timed_border.pos, b_timed_border.pos = color.utils.hex_to_rgba(beautiful.colorscheme.border_color)
set_border(beautiful.colorscheme.bg_purple)
set_fg(beautiful.colorscheme.fg)
set_bg(beautiful.colorscheme.bg1)
elseif i == selected - 1 or (selected == 1 and i == #clients_sorted) then
r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg1)
r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.fg)
r_timed_border.pos, g_timed_border.pos, b_timed_border.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg_purple)
set_border(beautiful.colorscheme.border_color)
set_fg(beautiful.colorscheme.bg_green)
set_bg(beautiful.colorscheme.bg)
else
r_timed_bg.pos, g_timed_bg.pos, b_timed_bg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg)
r_timed_fg.pos, g_timed_fg.pos, b_timed_fg.pos = color.utils.hex_to_rgba(beautiful.colorscheme.bg_green)
r_timed_border.pos, g_timed_border.pos, b_timed_border.pos = color.utils.hex_to_rgba(beautiful.colorscheme.border_color)
set_border(beautiful.colorscheme.border_color)
set_fg(beautiful.colorscheme.bg_green)
set_bg(beautiful.colorscheme.bg)
end
end
elseif fn == 'raise' then
local c = clients_sorted[selected]
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
c:emit_signal('request::activate')
c:raise()
--reset selected
selected = 0
end
return elements
end
elements = create_elements()
capi.awesome.connect_signal(
'window_switcher::select_next',
function()
elements = create_elements('next')
end
)
capi.awesome.connect_signal(
'window_switcher::raise',
function()
elements = create_elements('raise')
end
)
capi.client.connect_signal(
'manage',
function()
elements = create_elements()
end
)
capi.client.connect_signal(
'unmanage',
function()
elements = create_elements()
end
)
capi.awesome.connect_signal(
'window_switcher::update',
function()
elements = create_elements()
end
)
return elements
end

View File

@@ -5,7 +5,7 @@ case $1 in
"userPfp") "userPfp")
iconPath="/var/lib/AccountsService/icons/$USER" iconPath="/var/lib/AccountsService/icons/$USER"
userIconPath="$HOME/.config/awesome/src/assets/userpfp/" userIconPath="../assets/userpfp/"
if [[ -f "$userIconPath" ]]; if [[ -f "$userIconPath" ]];
then then

View File

@@ -0,0 +1,4 @@
#!/bin/bash
# First update the profile picture

View File

@@ -1,3 +1,7 @@
local setmetatable = setmetatable
local print = print
local type = type
-------------------------------------------------- --------------------------------------------------
-- ██████╗██████╗ ██╗ ██╗██╗ ██╗ █████╗ -- -- ██████╗██████╗ ██╗ ██╗██╗ ██╗ █████╗ --
-- ██╔════╝██╔══██╗╚██╗ ██╔╝██║ ██║██╔══██╗ -- -- ██╔════╝██╔══██╗╚██╗ ██╔╝██║ ██║██╔══██╗ --
@@ -6,6 +10,7 @@
-- ╚██████╗██║ ██║ ██║ ███████╗██║██║ ██║ -- -- ╚██████╗██║ ██║ ██║ ███████╗██║██║ ██║ --
-- ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝ -- -- ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝ --
-------------------------------------------------- --------------------------------------------------
local awful = require('awful') local awful = require('awful')
local beautiful = require('beautiful') local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
@@ -19,116 +24,122 @@ local capi = {
screen = screen, screen = screen,
} }
local function get_userconfig() local instance = nil
local data = config.read_json(gfilesystem.get_xdg_config_home() .. 'crylia_theme/crylia_theme.json') if not instance then
if not data then instance = setmetatable({}, {
print('Warning: No crylia_theme.json found, using default config') __call = function()
local function get_userconfig()
local data = config.read_json(gfilesystem.get_xdg_config_home() .. 'crylia_theme/crylia_theme.json')
if not data then
print('Warning: No crylia_theme.json found, using default config')
data = config.read_json('/etc/crylia_theme/crylia_theme.json') data = config.read_json('/etc/crylia_theme/crylia_theme.json')
end end
assert(type(data) == 'table', 'Invalid config file (not a table)!') assert(type(data) == 'table', 'Invalid config file (not a table)!')
return data return data
end
local function get_colorscheme()
local data = config.read_json(gfilesystem.get_xdg_config_home() .. 'crylia_theme/one_dark.json')
if not data then
print('Warning: No theme.json found, using default config')
data = config.read_json('/etc/crylia_theme/theme.json')
end
assert(type(data) == 'table', 'Invalid config file (not a table)!')
return data
end
local theme = {}
awesome.set_preferred_icon_size(128)
theme.user_config = get_userconfig()
theme.colorscheme = get_colorscheme()
theme.shape = {}
for i = 2, 30, 2 do
theme.shape[i] = function(w, h, cr)
gshape.rounded_rect(w, h, cr, dpi(i))
end
end
-- Default font, change it in user_config, not here.
theme.font = theme.user_config.font .. ' bold ' .. 16
--#region Client variables
theme.useless_gap = dpi(5)
theme.border_width = dpi(2)
theme.border_normal = theme.colorscheme.bg_1
theme.border_marked = theme.colorscheme.bg_red
--#endregion
--#region Tooltip variables
theme.tooltip_border_color = theme.colorscheme.border_color
theme.tooltip_bg = theme.colorscheme.bg
theme.tooltip_fg = theme.colorscheme.bg_teal
theme.tooltip_border_width = dpi(2)
theme.tooltip_gaps = dpi(15)
--#endregion
--#region Hotkeys variables
theme.hotkeys_bg = theme.colorscheme.bg
theme.hotkeys_fg = theme.colorscheme.fg
theme.hotkeys_border_width = dpi(2)
theme.hotkeys_border_color = theme.colorscheme.border_color
theme.hotkeys_modifiers_fg = theme.colorscheme.bg_teal
theme.hotkeys_description_font = theme.user_config.font
theme.hotkeys_font = theme.user_config.font
theme.hotkeys_group_margin = dpi(20)
theme.hotkeys_label_bg = theme.colorscheme.bg_teal
theme.hotkeys_label_fg = theme.colorscheme.bg
--#endregion
--#region Layout icons
local layout_path = gfilesystem.get_configuration_dir() .. 'src/assets/layout/'
theme.layout_cornerne = layout_path .. 'cornerne.png'
theme.layout_cornernw = layout_path .. 'cornernw.png'
theme.layout_cornerse = layout_path .. 'cornerse.png'
theme.layout_cornersw = layout_path .. 'cornersw.png'
theme.layout_dwindle = layout_path .. 'dwindle.png'
theme.layout_fairh = layout_path .. 'fairh.png'
theme.layout_fairv = layout_path .. 'fairv.png'
theme.layout_floating = layout_path .. 'floating.png'
theme.layout_fullscreen = layout_path .. 'fullscreen.png'
theme.layout_magnifier = layout_path .. 'magnifier.png'
theme.layout_max = layout_path .. 'max.png'
theme.layout_spiral = layout_path .. 'spiral.png'
theme.layout_tile = layout_path .. 'tile.png'
theme.layout_tilebottom = layout_path .. 'tilebottom.png'
theme.layout_tileleft = layout_path .. 'tileleft.png'
theme.layout_tiletop = layout_path .. 'tiletop.png'
--#endregion
theme.notification_spacing = dpi(20)
theme.bg_systray = theme.colorscheme.bg1
theme.systray_icon_spacing = dpi(10)
-- Wallpaper
beautiful.wallpaper = theme.user_config['wallpaper']
capi.screen.connect_signal('request::wallpaper', function(s)
if beautiful.wallpaper then
if type(beautiful.wallpaper) == 'string' then
gwallpaper.maximized(beautiful.wallpaper, s)
else
beautiful.wallpaper(s)
end
end
end)
beautiful.init(theme)
-- Load titlebar
require('src.core.titlebar')()
end,
})
end end
return instance
local function get_colorscheme()
local data = config.read_json(gfilesystem.get_xdg_config_home() .. 'crylia_theme/one_dark.json')
if not data then
print('Warning: No theme.json found, using default config')
data = config.read_json('/etc/crylia_theme/theme.json')
end
assert(type(data) == 'table', 'Invalid config file (not a table)!')
return data
end
local theme = {}
awesome.set_preferred_icon_size(128)
theme.user_config = get_userconfig()
theme.colorscheme = get_colorscheme()
theme.shape = {}
for i = 2, 30, 2 do
theme.shape[i] = function(w, h, cr)
gshape.rounded_rect(w, h, cr, dpi(i))
end
end
-- Default font, change it in user_config, not here.
theme.font = theme.user_config.font .. ' bold ' .. dpi(16)
--#region Client variables
theme.useless_gap = dpi(5)
theme.border_width = dpi(2)
theme.border_normal = theme.colorscheme.bg_1
theme.border_marked = theme.colorscheme.bg_red
--#endregion
--#region Tooltip variables
theme.tooltip_border_color = theme.colorscheme.border_color
theme.tooltip_bg = theme.colorscheme.bg
theme.tooltip_fg = theme.colorscheme.bg_teal
theme.tooltip_border_width = dpi(2)
theme.tooltip_gaps = dpi(15)
--#endregion
--#region Hotkeys variables
theme.hotkeys_bg = theme.colorscheme.bg
theme.hotkeys_fg = theme.colorscheme.fg
theme.hotkeys_border_width = dpi(2)
theme.hotkeys_border_color = theme.colorscheme.border_color
theme.hotkeys_modifiers_fg = theme.colorscheme.bg_teal
theme.hotkeys_description_font = theme.user_config.font
theme.hotkeys_font = theme.user_config.font
theme.hotkeys_group_margin = dpi(20)
theme.hotkeys_label_bg = theme.colorscheme.bg_teal
theme.hotkeys_label_fg = theme.colorscheme.bg
--#endregion
--#region Layout icons
local layout_path = gfilesystem.get_configuration_dir() .. 'src/assets/layout/'
theme.layout_cornerne = layout_path .. 'cornerne.png'
theme.layout_cornernw = layout_path .. 'cornernw.png'
theme.layout_cornerse = layout_path .. 'cornerse.png'
theme.layout_cornersw = layout_path .. 'cornersw.png'
theme.layout_dwindle = layout_path .. 'dwindle.png'
theme.layout_fairh = layout_path .. 'fairh.png'
theme.layout_fairv = layout_path .. 'fairv.png'
theme.layout_floating = layout_path .. 'floating.png'
theme.layout_fullscreen = layout_path .. 'fullscreen.png'
theme.layout_magnifier = layout_path .. 'magnifier.png'
theme.layout_max = layout_path .. 'max.png'
theme.layout_spiral = layout_path .. 'spiral.png'
theme.layout_tile = layout_path .. 'tile.png'
theme.layout_tilebottom = layout_path .. 'tilebottom.png'
theme.layout_tileleft = layout_path .. 'tileleft.png'
theme.layout_tiletop = layout_path .. 'tiletop.png'
--#endregion
theme.notification_spacing = dpi(20)
-- Systray theme variables
theme.bg_systray = theme.colorscheme.bg1
theme.systray_icon_spacing = dpi(10)
-- Wallpaper
beautiful.wallpaper = theme.user_config['wallpaper']
capi.screen.connect_signal('request::wallpaper', function(s)
if beautiful.wallpaper then
if type(beautiful.wallpaper) == 'string' then
gwallpaper.maximized(beautiful.wallpaper, s)
else
beautiful.wallpaper(s)
end
end
end)
beautiful.init(theme)
-- Load titlebar
--require('src.core.titlebar')()

View File

@@ -0,0 +1,91 @@
local setmetatable = setmetatable
local gtable = require('gears.table')
local gobject = require('gears.object')
local lgi = require('lgi')
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local bluetooth = {}
function bluetooth:StartDiscovery()
self.Adapter1:StartDiscovery()
self:emit_signal('Bluetooth::DiscoveryStarted')
end
function bluetooth:StopDiscovery()
self.Adapter1:StopDiscovery()
self:emit_signal('Bluetooth::DiscoveryStopped')
end
function bluetooth:RemoveDevice(device)
if not device then return end
self.Adapter1:RemoveDevice(device)
end
function bluetooth:toggle_wifi()
local powered = not self.Adapter1.Powered
self.Adapter1:Set('org.bluez.Adapter1', 'Powered', lgi.GLib.Variant('b', powered))
self.Adapter1.Powered = {
signature = 'b',
value = powered,
}
end
return setmetatable(bluetooth, {
__call = function(self)
gtable.crush(self, gobject())
self.ObjectManager = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.ObjectManager',
path = '/',
}
self.Adapter1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.Adapter1',
path = '/org/bluez/hci0',
}
self.Adapter1Properties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.Properties',
path = '/org/bluez/hci0',
}
self.Adapter1Properties:connect_signal(function(_, _, data)
if data.Powered ~= nil then
self:emit_signal('Bluetooth::Powered', data.Powered)
end
end, 'PropertiesChanged')
self.ObjectManager:connect_signal(function(_, path)
self:emit_signal('Bluetooth::DeviceAdded', path)
end, 'InterfacesAdded')
self.ObjectManager:connect_signal(function(_, path)
self:emit_signal('Bluetooth::DeviceRemoved', path)
end, 'InterfacesRemoved')
setmetatable(self, {
__index = function(_, key)
if key == 'Powered' then
return self.Adapter1.Powered
elseif key == 'Alias' then
return self.Adapter1.Alias
elseif key == 'PowerState' then
return self.Adapter1.PowerState
end
end,
})
return self
end,
})

View File

@@ -0,0 +1,88 @@
local setmetatable = setmetatable
local gtable = require('gears.table')
local gobject = require('gears.object')
local lgi = require('lgi')
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local device = {}
function device:Connect()
self.Device1:ConnectAsync()
end
function device:Disconnect()
self.Device1:DisconnectAsync()
end
function device:Pair()
self.AgentManager1:RegisterAgent(self.Agent1.object_path, 'KeyboardDisplay')
self.Device1:PairAsync()
end
function device:CancelPair()
self.Device1:CancelPairAsync()
end
function device:Rename(newname)
self.Device1:Set('org.bluez.Device1', 'Alias', lgi.GLib.Variant('s', newname))
self.Device1.Alias = { signature = 's', value = newname }
return self.Device1:Get('org.bluez.Device1', 'Alias')
end
function device:ToggleTrusted()
local trusted = not self.Device1.Trusted
self.Device1:Set('org.bluez.Device1', 'Trusted', lgi.GLib.Variant('b', trusted))
self.Device1.Trusted = { signature = 'b', value = trusted }
end
return setmetatable(device, {
__call = function(_, path)
if not path then return end
local self = gobject {}
gtable.crush(self, device, true)
self.Device1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.Device1',
path = path,
}
if not self.Device1 then return end
self.Agent1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.Agent1',
path = '/org/bluez/agent',
}
self.AgentManager1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.AgentManager1',
path = '/org/bluez',
}
setmetatable(self, {
__index = function(_, key)
if key == 'Alias' then
return self.Device1.Alias
elseif key == 'Icon' then
return self.Device1.Icon
elseif key == 'Paired' then
return self.Device1.Paired
elseif key == 'Connected' then
return self.Device1.Connected
elseif key == 'Trusted' then
return self.Device1.Trusted
elseif key == 'RSSI' then
return self.Device1.RSSI
end
end,
})
return self
end,
})

View File

@@ -38,6 +38,7 @@ config.write = function(path, content)
end end
config.read_json = function(path) config.read_json = function(path)
print(path)
local handler = io.open(path, 'r') local handler = io.open(path, 'r')
if not handler then error('Invalid path') return end if not handler then error('Invalid path') return end

View File

@@ -7,23 +7,31 @@ local Gtk = lgi.require('Gtk', '3.0')
local icon_lookup = {} local icon_lookup = {}
function icon_lookup:get_gicon_path(app, icon_string) function icon_lookup:get_gicon_path(app, icon_string)
if (not app) and (not icon_string) then return end if (not app) and (not icon_string) or not self.gtk_theme then return end
if icon_string then if icon_string then
return self.gtk_theme:lookup_icon(icon_string, 64, 0):get_filename() or '' local icon = self.gtk_theme:lookup_icon(icon_string or "", 64, 0)
if icon then
return icon:get_filename() or ''
end
end
if app then
local icon_info = self.gtk_theme:lookup_by_gicon(app, 64, 0)
if icon_info then
return icon_info:get_filename()
end
end end
local icon_info = self.gtk_theme:lookup_by_gicon(app, 64, 0)
if icon_info then
return icon_info:get_filename()
end
return nil return nil
end end
local instance = nil local instance = nil
if not instance then if not instance then
instance = setmetatable(icon_lookup, { instance = setmetatable(icon_lookup, {
__call = function(self, ...) __call = function(self, theme_name,...)
self.gtk_theme = Gtk.IconTheme.get_default() self.gtk_theme = Gtk.IconTheme.get_default()
return self return self
end, end,
}) })

View File

@@ -6,43 +6,108 @@ local audio = {}
local instance = nil local instance = nil
function audio.set_sink_volume(volume) function audio:set_sink_volume(volume)
aspawn('pactl set-sink-volume @DEFAULT_SINK@ ' .. volume .. '%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-volume @DEFAULT_SINK@ ' .. volume .. '%', function()
self.allow_cmd = true
end)
end end
function audio.set_source_volume(volume) function audio:set_source_volume(volume)
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ ' .. volume .. '%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-source-volume @DEFAULT_SOURCE@ ' .. volume .. '%', function()
self.allow_cmd = true
end)
end end
function audio.sink_volume_up() function audio:sink_volume_up()
aspawn('pactl set-sink-volume @DEFAULT_SINK@ +2%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-volume @DEFAULT_SINK@ +2%', function()
self.allow_cmd = true
end)
end end
function audio.source_volume_up() function audio:source_volume_up()
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ +2%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-source-volume @DEFAULT_SOURCE@ +2%', function()
self.allow_cmd = true
end)
end end
function audio.sink_volume_down() function audio:sink_volume_down()
aspawn('pactl set-sink-volume @DEFAULT_SINK@ -2%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-volume @DEFAULT_SINK@ -2%', function()
self.allow_cmd = true
end)
end end
function audio.source_volume_down() function audio:source_volume_down()
aspawn('pactl set-source-volume @DEFAULT_SOURCE@ -2%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-source-volume @DEFAULT_SOURCE@ -2%', function()
self.allow_cmd = true
end)
end end
function audio.sink_toggle_mute() function audio:sink_toggle_mute()
aspawn('pactl set-sink-mute @DEFAULT_SINK@ toggle') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-mute @DEFAULT_SINK@ toggle', function()
self.allow_cmd = true
end)
end end
function audio.source_toggle_mute() function audio:source_toggle_mute()
aspawn('pactl set-source-mute @DEFAULT_SOURCE@ toggle') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-source-mute @DEFAULT_SOURCE@ toggle', function()
self.allow_cmd = true
end)
end
function audio:sink_unmute()
if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-mute @DEFAULT_SINK@ false', function()
self.allow_cmd = true
end)
end
function audio:sink_mute()
if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-sink-mute @DEFAULT_SINK@ true', function()
self.allow_cmd = true
end)
end
function audio:source_unmute()
if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('pactl set-source-mute @DEFAULT_SOURCE@ false', function()
self.allow_cmd = true
end)
end
function audio:source_mute()
if not self.allow_cmd then return end
self.allow_cmd = false
aspawn('pactl set-source-mute @DEFAULT_SOURCE@ true', function()
self.allow_cmd = true
end)
end end
local function new() local function new()
local self = gobject {} local self = gobject {}
gtable.crush(self, audio, true) gtable.crush(self, audio, true)
self.allow_cmd = true
aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], { aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], {
stdout = function(line) stdout = function(line)
-- Volume changed -- Volume changed

View File

@@ -1,6 +1,7 @@
local aspawn = require('awful.spawn') local aspawn = require('awful.spawn')
local gobject = require('gears.object') local gobject = require('gears.object')
local gtable = require('gears.table') local gtable = require('gears.table')
local gtimer = require('gears.timer')
local backlight = {} local backlight = {}
@@ -8,17 +9,25 @@ local instance = nil
function backlight.brightness_get_async(callback) function backlight.brightness_get_async(callback)
aspawn.easy_async_with_shell('brightnessctl get', function(stdout) aspawn.easy_async_with_shell('brightnessctl get', function(stdout)
callback(tonumber(stdout:gsub('\n', ''))) callback(stdout:gsub('\n', ''))
end) end)
end end
function backlight:brightness_increase() function backlight:brightness_increase()
aspawn('brightnessctl set 2+%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('brightnessctl set 2+%', function()
self.allow_cmd = true
end)
self:emit_signal('brightness_changed') self:emit_signal('brightness_changed')
end end
function backlight:brightness_decrease() function backlight:brightness_decrease()
aspawn('brightnessctl set 2-%') if not self.allow_cmd then return end
self.allow_cmd = false
aspawn.easy_async_with_shell('brightnessctl set 2-%', function()
self.allow_cmd = true
end)
self:emit_signal('brightness_changed') self:emit_signal('brightness_changed')
end end
@@ -32,6 +41,11 @@ local function new()
self.max_brightness = tonumber(stdout:gsub('\n', '') or 1) self.max_brightness = tonumber(stdout:gsub('\n', '') or 1)
end) end)
-- Function locker to avoid spawning more commands than can be processed at a time
self.allow_cmd = true
self:emit_signal('brightness_changed')
return self return self
end end

View File

@@ -1,15 +1,38 @@
local awatch = require('awful.widget.watch') local awatch = require('awful.widget.watch')
local aspawn = require('awful.spawn')
local gobject = require('gears.object') local gobject = require('gears.object')
local instance local instance
local json = require('src.lib.json-lua.json-lua')
local function new() local function new()
local self = gobject {} local self = gobject {}
awatch([[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], 3, function(_, stdout) aspawn.easy_async_with_shell([[ lspci | grep ' VGA ' | cut -d" " -f 1 ]], function(stdout)
stdout = stdout:match('%d+') if stdout:match('00:03.0') then -- Nvidia
if not stdout then return end awatch([[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], 3, function(_, stdout)
self:emit_signal('update::gpu_usage', stdout) stdout = stdout:match('%d+')
if not stdout then return end
self:emit_signal('update::gpu_usage', stdout)
end)
elseif stdout:match('00:02.0') then -- Intel
awatch([[ bash -c "intel_gpu_top -J & sleep 1 && pkill intel_gpu_top" ]], 3, function(_, stdout)
local gpu_data = json:decode('[' .. stdout:gsub('/', '') .. ']')[2]
if not gpu_data or type(gpu_data) ~= table then return end
local gpu_usage = (gpu_data.engines.Render3D0.busy +
gpu_data.engines.Blitter0.busy +
gpu_data.engines.Video0.busy +
gpu_data.engines.VideoEnhance0.busy) / 4
self:emit_signal('update::gpu_usage', math.floor(gpu_usage + 0.5))
end)
elseif stdout:match('00:01.0') then -- AMD
-- AMD
end
end) end)
return self return self
end end

View File

@@ -30,7 +30,7 @@ local function overlay_color(col, overlay, opacity)
end end
local function bg_hover(args) local function bg_hover(args)
args = args or {} --[[ args = args or {}
local old_cursor, old_wibox local old_cursor, old_wibox
local _, r, g, b, a = args.widget.bg:get_rgba() local _, r, g, b, a = args.widget.bg:get_rgba()
@@ -117,7 +117,7 @@ local function bg_hover(args)
args.widget:connect_signal('property::bg', function(_, newbg) args.widget:connect_signal('property::bg', function(_, newbg)
r, g, b, a = hex_to_rgba(newbg) r, g, b, a = hex_to_rgba(newbg)
end) end) ]]
end end
--[[ local function fg_hover(args) --[[ local function fg_hover(args)

View File

@@ -0,0 +1,60 @@
local setmetatable = setmetatable
local aspawn = require("awful.spawn")
local lgi = require('lgi')
local cairo = lgi.cairo
local gfilesystem = require('gears.filesystem')
local gsurface = require('gears.surface')
local gtable = require('gears.table')
local gobject = require('gears.object')
--[[
Preload all external image or svg files as cairo surfaces and return them,
if no icon is found an empty surface is returned
]]
local cache = {}
local ret = {}
local instance = nil
if not instance then
instance = setmetatable(ret, {
__call = function()
gtable.crush(ret, gobject{}, true)
local icon_path = gfilesystem.get_configuration_dir() .. 'src/assets/icons/'
local layout_path = gfilesystem.get_configuration_dir() .. 'src/assets/layout/'
aspawn.easy_async_with_shell('ls -a "' .. icon_path .. '"', function(stdout)
for str in stdout:gmatch("([^\n]*)\n?") do
if str ~= "" and str ~= "." and str ~= ".." then
local surface = cairo.ImageSurface(cairo.ARGB, 64, 64)
cache[str] = surface
end
end
ret:emit_signal("done")
end)
aspawn.easy_async_with_shell('ls -a "' .. layout_path .. '"', function(stdout)
for str in stdout:gmatch("([^\n]*)\n?") do
if str ~= "" and str ~= "." and str ~= ".." then
local surface = cairo.ImageSurface(cairo.ARGB, 64, 64)
cache[str] = surface
end
end
end)
return ret
end,
__index = function(self,key)
print(key, cache[key])
if key and cache[key] then
print("test")
return cache[key]
elseif(key == "user_image") or (key == "background") or (key == "os_logo") then
return cache[key]
else
--return cairo.ImageSurface()
end
end
})
end
return instance

View File

@@ -0,0 +1,79 @@
local gtable = require('gears.table')
local gobject = require('gears.object')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local instance = nil
if not instance then
instance = setmetatable({}, {
__call = function(_, device_path)
local self = gobject {}
self.object_path = device_path
self.NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.AccessPoint',
path = device_path,
}
if not NM.utils_ssid_to_utf8(self.NetworkManagerAccessPoint.Ssid) then
self.NetworkManagerAccessPoint = nil
self = nil
return nil
end
self.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = device_path,
}
self.NetworkManagerAccessPointProperties:connect_signal(function(_, _, data)
if data.Strength then
self:emit_signal('NetworkManagerAccessPoint::Strength', data.Strength)
elseif data.LastSeen then
self:emit_signal('NetworkManagerAccessPoint::LastSeen', data.LastSeen)
end
end, 'PropertiesChanged')
self:emit_signal('NetworkManagerAccessPoint::Strength', self.NetworkManagerAccessPoint.Strength)
setmetatable(self, {
__index = function(s, key)
if key == 'SSID' then
return NM.utils_ssid_to_utf8(s.NetworkManagerAccessPoint.Ssid)
elseif key == 'Frequency' then
return s.NetworkManagerAccessPoint.Frequency
elseif key == 'MaxBitrate' then
return s.NetworkManagerAccessPoint.MaxBitrate
elseif key == 'HwAddress' then
return s.NetworkManagerAccessPoint.HwAddress
elseif key == 'Strength' then
return s.NetworkManagerAccessPoint.Strength
elseif key == 'Security' then
local str = ''
if s.Flags == 1 and s.WpaFlags == 0 and s.RsnFlags == 0 then
str = str .. ' WEP'
end
if s.WpaFlags ~= 0 then
str = str .. ' WPA1'
end
if not s.RsnFlags ~= 0 then
str = str .. ' WPA2'
end
if s.WpaFlags == 512 or s.RsnFlags == 512 then
str = str .. ' 802.1X'
end
return (str:gsub('^%s', ''))
end
end,
})
return self
end,
})
end
return instance

View File

@@ -0,0 +1,169 @@
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local gtable = require('gears.table')
local gobject = require('gears.object')
local access_point = require('src.tools.network.access_point')
local device = {}
device._private = {}
local WIRELESS = {}
device._private.DeviceType = {
ETHERNET = 1,
WIFI = 2,
}
device._private.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,
}
function WIRELESS:IsApActive(ap)
return self.NetworkManagerDeviceWireless.ActiveAccessPoint == ap.object_path
end
function WIRELESS:GetAllAccessPoints()
return self.NetworkManagerDeviceWireless:GetAllAccessPoints()
end
--- If we scan we simply update the list that holds all access points
--- We can then get the list and create a new access point for all devices
---@param callback any
function WIRELESS:RequestScan(callback)
local ap_list = {}
self.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure)
for _, value in ipairs(self.NetworkManagerDeviceWireless:GetAllAccessPoints()) do
table.insert(ap_list, access_point(value))
end
callback(ap_list)
end, { call_id = 'AMOGUS' }, {})
end
return setmetatable(device, {
__call = function(_, device_path)
local self = gobject {}
gtable.crush(self, device, true)
self.object_path = device_path
self.NetworkManagerDevice = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device',
path = device_path,
}
self.NetworkManagerDevice:connect_signal(function(_, new_state, reason)
self:emit_signal('NetworkManagerDevice::StateChanged', new_state, reason)
end, 'StateChanged')
if self.NetworkManagerDevice.DeviceType == self._private.DeviceType.WIFI then
gtable.crush(self, WIRELESS, true)
self.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device.Wireless',
path = device_path,
}
self.NetworkManagerDeviceWirelessProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = device_path,
}
self.NetworkManagerDeviceWirelessProperties:connect_signal(function(_, _, data)
if data.Birate then
self:emit_signal('NetworkManagerDeviceWireless::Bitrate', data.Bitrate)
end
if data.ActiveAccessPoint then
self:emit_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', self.current_ap, data.ActiveAccessPoint)
self.current_ap = data.ActiveAccessPoint
end
end, 'PropertiesChanged')
self.current_ap = self.NetworkManagerDeviceWireless.ActiveAccessPoint
self.ap_list = {}
self.NetworkManagerDeviceWireless:connect_signal(function(_, path)
--check if path is already in list
for _, value in ipairs(self.ap_list) do
if value == path then
return
end
end
table.insert(self.ap_list, path)
self:emit_signal('NetworkManagerDeviceWireless::AccessPointAdded', access_point(path))
end, 'AccessPointAdded')
self.NetworkManagerDeviceWireless:connect_signal(function(_, path)
self:emit_signal('NetworkManagerDeviceWireless::AccessPointRemoved', path)
for i, value in ipairs(self.ap_list) do
if value == path then
table.remove(self.ap_list, i)
return
end
end
end, 'AccessPointRemoved')
elseif self.NetworkManagerDevice.DeviceType == self._private.DeviceType.ETHERNET then
self.NetworkManagerDeviceWired = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Device.Wired',
path = device_path,
}
self:emit_signal('NetworkManagerDeviceWired::Speed', self._private.NetworkManagerDeviceWired.Speed)
self.NetworkManagerDeviceWiredProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = device_path,
}
self.NetworkManagerDeviceWiredProperties:connect_signal(function(_, _, data)
if data.Carrier then
self:emit_signal('NetworkManagerDeviceWired::Carrier', data.Carrier)
end
end, 'PropertiesChanged')
end
setmetatable(self, {
__index = function(self, key)
if key == 'DeviceType' then
return self.NetworkManagerDevice.DeviceType
elseif key == 'State' then
return self.NetworkManagerDevice.State
elseif key == 'StateReason' then
return self.NetworkManagerDevice.StateReason
elseif key == 'Bitrate' then
if self.NetworkManagerDeviceWireless then
return self.NetworkManagerDeviceWireless.Bitrate
end
elseif key == 'Speed' then
if self.NetworkManagerDeviceWired then
return self.NetworkManagerDeviceWired.Speed
end
elseif key == 'Managed' then
return self.NetworkManagerDevice.Managed
elseif key == 'ActiveConnection' then
return self.NetworkManagerDevice.ActiveConnection
end
end,
})
return self
end,
})

View File

@@ -0,0 +1,189 @@
local lgi = require('lgi')
local gobject = require('gears.object')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local nmdevice = require('src.tools.network.device')
local settings = require('src.tools.network.settings')
local network = gobject {}
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,
}
---Will try to connect to an access point by first searching if the connection already exists
--- and then adding the connection if its not.
---@param ap any
---@param connection any
---@param callback any
function network:ConnectToAccessPointAsync(ap, device, connection, callback)
print(ap, connection)
for path, value in pairs(self.NetworkManagerSettings.ConnectionList or {}) do
print(--[[ connection.connection.id.value, ]] ap.SSID, value:GetSettings().connection.id)
if (connection and connection.connection.id.value or ap.SSID) == value:GetSettings().connection.id then
if connection then
value:Update(connection)
end
self.NetworkManager:ActivateConnectionAsync(function(_, _, succ, failure)
print(failure, succ)
if failure then
callback(false)
return
else
callback(true)
return
end
end, { call_id = 'amogus' }, path, device.object_path, ap.object_path)
return
end
end
if not connection then
callback(false)
return
end
self.NetworkManager:AddAndActivateConnectionAsync(function(_, _, succ, fail)
if fail then
callback(false)
return
else
callback(true)
return
end
end, { call_id = 'amogus' }, connection, device.object_path, ap.object_path)
end
function network:DisconnectFromAP()
self.NetworkManager:DeactivateConnection(self:get_wireless_device().ActiveConnection)
end
--TODO: Make sure this works, I don't know how its going
--TODO: to work if there were multiple wireless devices, probably try
--TODO: to find the one that is active or something like that
---Returns the current wifi device, if none if found returns the ethernet devie, else nil
---@return wifi|ethernet|nil device
function network:get_wireless_device()
local ethernet_device = nil
for _, device in pairs(self.Devices) do
print(device.DeviceType, device.device_path)
if device.DeviceType == self.DeviceType.WIFI then
return device
elseif device.DeviceType == self.DeviceType.ETHERNET then
ethernet_device = device
end
end
return ethernet_device
end
function network:get_devices()
local devices = self.NetworkManager:GetDevices() or {}
self.Devices = {}
for _, device in ipairs(devices) do
self.Devices[device] = nmdevice(device)
self.Devices[device]:connect_signal('NetworkManagerDevice::StateChanged', function(_, s, r)
end)
end
end
function network:toggle_network()
self.NetworkManager:Set('org.freedesktop.NetworkManager', 'NetworkingEnabled', lgi.GLib.Variant('b', not self.NetworkingEnabled))
end
function network:toggle_wifi()
if self.NetworkingEnabled == false then
self:toggle_network()
end
self.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', not self.WirelessEnabled))
end
local instance = nil
if not instance then
instance = setmetatable(network, {
__call = function(self)
self.NetworkManager = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager',
path = '/org/freedesktop/NetworkManager',
}
self.NetworkManagerProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = '/org/freedesktop/NetworkManager',
}
self.NetworkManagerSettings = settings()
self.NetworkManager:connect_signal(function(_, device_path)
if device_path then
self:emit_signal('NetworkManager::DeviceAdded', device_path)
end
end, 'DeviceAdded')
self.NetworkManager:connect_signal(function(_, device_path)
if device_path then
self:emit_signal('NetworkManager::DeviceRemoved', device_path)
end
end, 'DeviceRemoved')
self.NetworkManagerProperties:connect_signal(function(_, _, data)
if data.WirelessEnabled ~= nil then
self.WirelessEnabled = data.WirelessEnabled
self:emit_signal('NetworkManager::WirelessEnabled', data.WirelessEnabled)
end
if data.NetworkingEnabled ~= nil then
self.NetworkingEnabled = data.NetworkingEnabled
self:emit_signal('NetworkManager::NetworkingEnabled', data.NetworkingEnabled)
end
end, 'PropertiesChanged')
-- Init values because signal isn't emitted on startup
self:emit_signal('NetworkManager::WirelessEnabled', self.NetworkManager.WirelessEnabled)
self:emit_signal('NetworkManager::NetworkingEnabled', self.NetworkManager.NetworkingEnabled)
self.WirelessEnabled = self.NetworkManager.WirelessEnabled
self.NetworkingEnabled = self.NetworkManager.NetworkingEnabled
self:get_devices()
return self
end,
})
end
return instance

View File

@@ -0,0 +1,136 @@
local gobject = require('gears.object')
local gtable = require('gears.table')
local lgi = require('lgi')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local settings = gobject {}
---Get a connection path by uuid
---@param uuid string
---@return string connection_path
function settings:GetConnectionByUUID(uuid)
return self.NetworkManagerSettings:GetConnectionByUuid(uuid) or ''
end
function settings:GetConnectionForSSID(ssid)
for _, con in pairs(self.ConnectionList) do
if con:GetSettings().connection.id == ssid then
return con
end
end
end
--! For some reason not working, using AddAndActivateConnection instead works and adds the connection just fine
---Tries to add a new connection to the connections and returns the path if successfull
---@param con table connection
---@return string?
function settings:AddConnection(con)
--[[ local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = '/org/freedesktop/NetworkManager/Settings/',
} ]]
--[[ c:Update(con)
print('No Problem')
print(c:GetSettings().connection.id) ]]
--local path = self.NetworkManagerSettings:AddConnection(con)
--print(path)
--return path
end
function settings:RemoveConnection(con)
if not con then return end
con:Delete()
end
---Returns a new and valid connection table
---@param args {passwd: string, security: string, autoconnect: boolean, ssid: string}
---@return table
function settings:NewConnectionProfile(args)
local security = {}
if args.security:match('WPA') then
security = {
['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk'),
['auth-alg'] = lgi.GLib.Variant('s', 'open'),
['psk'] = lgi.GLib.Variant('s', args.passwd),
}
else
security = {
['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk'),
['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE),
['wep-key0'] = lgi.GLib.Variant('s', args.passwd),
}
end
return {
['connection'] = {
['uuid'] = lgi.GLib.Variant('s', string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
return string.format('%x', v)
end)),
['id'] = lgi.GLib.Variant('s', args.ssid),
['type'] = lgi.GLib.Variant('s', '802-11-wireless'),
['autoconnect'] = lgi.GLib.Variant('b', args.autoconnect),
},
['ipv4'] = {
['method'] = lgi.GLib.Variant('s', 'auto'),
},
['ipv6'] = {
['method'] = lgi.GLib.Variant('s', 'auto'),
},
['802-11-wireless'] = {
['mode'] = lgi.GLib.Variant('s', 'infrastructure'),
},
['802-11-wireless-security'] = security,
}
end
local instance = nil
if not instance then
instance = setmetatable(settings, {
__call = function(self)
self.NetworkManagerSettings = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings',
path = '/org/freedesktop/NetworkManager/Settings',
}
self.ConnectionList = {}
for _, value in pairs(self.NetworkManagerSettings:ListConnections()) do
local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = value,
}
if c then self.ConnectionList[value] = c end
end
self.NetworkManagerSettings:connect_signal(function(_, con)
print('New!', con)
local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = con,
}
self.ConnectionList[con] = c
end, 'NewConnection')
self.NetworkManagerSettings:connect_signal(function(_, con)
print('Removed!', con)
self.ConnectionList[con] = nil
end, 'ConnectionRemoved')
return self
end,
})
end
return instance

View File

@@ -8,18 +8,17 @@ local ical_calendar_cache = {}
local date_time = {} local date_time = {}
setmetatable(date_time, { setmetatable(date_time, {
__call = function(args) __call = function(self, args)
local dt = table.copy(date_time)
dt.day = args.day or 1 self.day = args.day or 1
dt.month = args.month or 1 self.month = args.month or 1
dt.year = args.year or 1970 self.year = args.year or 1970
dt.hour = args.hour or 0 self.hour = args.hour or 0
dt.minute = args.minute or 0 self.minute = args.minute or 0
dt.second = args.second or 0 self.second = args.second or 0
return dt return self
end, end,
__newindex = function(self, ...) __newindex = function(self, ...)
if ... == 'weeknum' then if ... == 'weeknum' then
@@ -29,53 +28,135 @@ setmetatable(date_time, {
return self.weeknum return self.weeknum
end end
end, end,
__add = function(a, b) __tostring = function(self)
local dt = table.copy(date_time) return string.format('%d-%d-%d %d:%d:%d', self.year, self.month, self.day, self.hour, self.minute, self.second)
if type(a) == 'table' and type(b) == 'table' then
elseif type(a) == 'table' and type(b) == 'number' then
else
error('Cannot add number with date')
end
end,
__sub = function(a, b)
end,
__mul = function(a, b)
end,
__div = function(a, b)
end, end,
}); });
local parser = {} local parser = {}
local instance = nil function parser.VCALENDAR(handler)
local parse = {}
local line
while true do
line = handler:read('*l')
if not line then break end
local key, value = line:match('^(%w+):(.*)$')
function parser:VEVENT() if key == 'END' then
return parse
end
if key == 'BEGIN' then
if value == 'VEVENT' then
parse[value] = parser.VEVENT(handler)
elseif value == 'VTIMEZONE' then
parse[value] = parser.VTIMEZONE(handler)
end
elseif key == 'VERSION' then
parse[key] = value
elseif key == 'PRODID' then
parse[key] = value
elseif key == 'CALSCALE' then
parse[key] = value
elseif key == 'METHOD' then
parse[key] = value
elseif key == 'X-WR-CALNAME' then
parse[key] = value
elseif key == 'X-WR-TIMEZONE' then
parse[key] = value
elseif key == 'X-WR-CALDESC' then
parse[key] = value
end
end
end end
---Start parsing a new calendar function parser.VTIMEZONE(handler)
---@param path string path to .ical file local parse = {}
function parser.parse(path) local line
while true do
line = handler:read('*l')
if not line then break end
local key, value = line:match('^(%w+):(.*)$')
local ical_name = path if key == 'END' then
return parse
end
-- Check if the calendar has been parsed previously if key == 'BEGIN' then
if ical_calendar_cache[ical_name] then if value == 'DAYLIGHT' or value == 'STANDARD' then
return ical_calendar_cache[ical_name] parse[value] = parser.TZ(handler)
else end
-- If not create a new one in the cache elseif key == 'TZID' then
ical_calendar_cache[ical_name] = {} parse[key] = value
elseif key == 'LAST-MODIFIED' then
parse[key] = value
elseif key == 'X-LIC-LOCATION' then
parse[key] = value
end
end end
end
return ical_calendar_cache[ical_name] function parser.TZ(handler)
local parse = {}
local line
while true do
line = handler:read('*l')
if not line then break end
local key, value = line:match('^(%w+):(.*)$')
if key == 'END' then
return parse
end
if key == 'TZNAME' then
parse[key] = value
elseif key == 'TZOFFSETFROM' then
parse[key] = value
elseif key == 'TZOFFSETTO' then
parse[key] = value
elseif key == 'DTSTART' then
parse[key] = parse.DT(value)
elseif key == 'RRULE' then
parse[key] = parse.RRULE(value)
end
end
end
function parser.VEVENT(handler)
local parse = {}
local line
while true do
line = handler:read('*l')
if not line then break end
local key, value = line:match('^(%w+):(.*)$')
if key == 'END' then
return parse
end
if key == 'UID' then
parse[key] = value
elseif key == 'SEQUENCE' then
parse[key] = value
elseif key == 'SUMMARY' then
parse[key] = value
elseif key == 'LOCATION' then
parse[key] = value
elseif key == 'STATUS' then
parse[key] = value
elseif key == 'RRULE' then
parse[key] = parser.RRULE(value)
end
end
end end
function parser.new(path) function parser.new(path)
local cal = {}
-- Get the file from the path -- Get the file from the path
local ical_name = path local ical_name = path
@@ -85,12 +166,27 @@ function parser.new(path)
return ical_calendar_cache[ical_name] return ical_calendar_cache[ical_name]
end end
-- If not create a new one in the cache local handler = io.open(path, 'r')
ical_calendar_cache[ical_name] = { mt = {} } if not handler then return end
while true do
local line = handler:read('*l')
if not line then break end
local key, value = line:match('^(%w+):(.*)$')
if key and value then
if key == 'BEGIN' and value == 'VCALENDAR' then
cal[value] = parser.VCALENDAR(handler)
end
end
end
handler:close()
return ical_calendar_cache[ical_name] return ical_calendar_cache[ical_name]
end end
local instance = nil
if not instance then if not instance then
instance = setmetatable(parser, { instance = setmetatable(parser, {
-- If this module is called load all cached calendars from the cache -- If this module is called load all cached calendars from the cache

View File

@@ -81,6 +81,7 @@ return setmetatable({}, { __call = function(_, screen)
calendar_popup.x = geo.x - (calendar_popup.width / 2) calendar_popup.x = geo.x - (calendar_popup.width / 2)
end end
calendar_popup.visible = not calendar_popup.visible calendar_popup.visible = not calendar_popup.visible
collectgarbage('collect')
end) end)
), } ), }

View File

@@ -16,7 +16,8 @@ local wibox = require('wibox')
-- Local Libs -- Local Libs
local hover = require('src.tools.hover') local hover = require('src.tools.hover')
local nm_widget = require('src.modules.network_controller') local nm_widget = require('src.modules.network')
local networkManager = require('src.tools.network')()
local capi = { local capi = {
awesome = awesome, awesome = awesome,
@@ -62,33 +63,61 @@ return setmetatable({}, {
hover.bg_hover { widget = w } hover.bg_hover { widget = w }
capi.awesome.connect_signal('NM::AccessPointStrength', function(strength) -- Little workaround because signals from nm_widget are not working?
strength = mfloor(strength) --! Find out why the signals are not working
w:get_children_by_id('wifi_strength')[1].text = strength .. '%' local function update_ethernet(device)
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir .. w.tt = atooltip {
'wifi-strength-' .. mfloor(strength / 25) + 1 .. '.svg', beautiful.colorscheme.bg)
end)
capi.awesome.connect_signal('NM::EthernetStatus', function(connected, speed)
local tt = atooltip {
objects = { w }, objects = { w },
mode = 'outside', mode = 'outside',
preferred_alignments = 'middle', preferred_alignments = 'middle',
margins = dpi(10), margins = dpi(10),
text = 'Connected via Ethernet at ' .. mfloor(device.Speed or 0) .. '/Mbps',
} }
if connected then end
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir .. 'ethernet.svg',
beautiful.colorscheme.bg)
tt.text = 'Connected via Ethernet at ' .. mfloor(speed or 0) .. '/Mbps'
else
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir .. 'no-internet.svg',
beautiful.colorscheme.bg)
tt.text = 'No connection found'
end
end)
local nm = nm_widget { screen = screen } local nm = nm_widget { screen = screen }
local function active_access_point_strength(strength)
local s
if strength > 80 then
s = 5
elseif strength >= 60 and strength < 80 then
s = 4
elseif strength >= 40 and strength < 60 then
s = 3
elseif strength >= 20 and strength < 40 then
s = 2
else
s = 1
end
w:get_children_by_id('wifi_strength')[1].text = math.floor(strength) .. '%'
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir ..
'wifi-strength-' .. s .. '.svg', beautiful.colorscheme.bg)
end
capi.awesome.connect_signal('ActiveAccessPointStrength', active_access_point_strength)
-- Remove the wifi signals when no wifi is active/readd them when wifi is active
networkManager:connect_signal('NetworkManager::WirelessEnabled', function(enabled)
if enabled then
capi.awesome.connect_signal('ActiveAccessPointStrength', active_access_point_strength)
w:get_children_by_id('wifi_strength')[1].visible = true
w.tt = nil
else
-- If its nil then there is no internet
local dev = networkManager:get_wireless_device()
if not dev then
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir .. 'no-internet.svg', beautiful.colorscheme.bg)
else
w:get_children_by_id('wifi_icon')[1].image = gcolor.recolor_image(icondir .. 'ethernet.svg', beautiful.colorscheme.bg)
update_ethernet(dev)
w.tt = nil
end
capi.awesome.disconnect_signal('ActiveAccessPointStrength', active_access_point_strength)
w:get_children_by_id('wifi_strength')[1].visible = false
end
end)
local network_controler_popup = apopup { local network_controler_popup = apopup {
widget = nm, widget = nm,
visible = true, visible = true,

7
awesome_crylia.desktop Normal file
View File

@@ -0,0 +1,7 @@
[Desktop Entry]
Name=Awesome Crylia Theme
Comment=Crylia Theme for AwesomeWM
TryExec=sh -c "awesome_crylia -c $HOME/.config/crylia_theme/rc.lua"
Exec=sh -c "/usr/local/bin/awesome_crylia -c $HOME/.config/crylia_theme/rc.lua"
Type=Application

96
install.sh Normal file
View File

@@ -0,0 +1,96 @@
#!/bin/bash
echo "
╭─────────────────────────────────────────────────────────────────╮
│ ______ ___ ________ │
│ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ │
│ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ │
│ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ │
│ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ │
│ /____/ │
╰─────────────────────────────────────────────────────────────────╯
"
if (($EUID != 0)); then
echo "ERROR: Please run as root!\n"
exit
fi
# Try to install dependencies
if [whereis apt | awk '{print $2}' = "*apt"]; then
apt update && apt install libconfig-dev libdbus-1-dev libegl-dev libev-dev libgl-dev libpcre2-dev libpixman-1-dev libx11-xcb-dev libxcb1-dev libxcb-composite0-dev libxcb-damage0-dev libxcb-dpms0-dev libxcb-glx0-dev libxcb-image0-dev libxcb-present-dev libxcb-randr0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-shape0-dev libxcb-util-dev libxcb-xfixes0-dev libxext-dev meson ninja-build uthash-dev
else if [whereis pacman | awk '{print $2}' = "*apt"]; then
pacman -Suy
fi
CONFIG_PATH="$HOME/.config";
DESKTOP_FILE="awesome_crylia.desktop";
SESSION_PATH="/usr/share/xsessions";
# Copy the desktop file to the xsessions folder
cp $DESKTOP_FILE "$SESSION_PATH/$DESKTOP_FILE"
# Check if the file got copied
if ![ -f "$SESSION_PATH/$DESKTOP_FILE"]; then
printf '%c' "ERROR: Couldn't copy .desktop file";
fi
function y_or_n {
while true; do
read -p "$* [Y/N]: " yn
case $yn in
[Yy]*) return 1;;
[Nn]*) return 0;;
esac
done
}
# $1 the folder that should be backuped
# $2 the new backup folder name
# $3 the file to copy to $1
function backup_and_copy {
if [-d "$1"]; then
cp -r "$1" "$2"
if [-d "$2"]; then
rm -r "$1"
else
if (yes_or_no "WARNING: Couldn't create backup of $1, continue?" == 0); then
echo "Aborted";
exit -1;
fi
fi
fi
cp -r "$3 $1"
if ![-d "$1"]; then
echo "ERROR: Couldn't copy $3 to $1"
fi
}
backup_and_copy "$CONFIG_PATH/crylia_theme" "$CONFIG_PATH/crylia_theme_backup" "awesome"
backup_and_copy "$CONFIG_PATH/kitty" "$CONFIG_PATH/kitty_backup" "kitty"
backup_and_copy "$CONFIG_PATH/starship.toml" "$CONFIG_PATH/starship.toml.backup" "starship.toml"
# Clone, build and install my awesome fork
git clone https://github.com/Crylia/awesome /tmp
cd /tmp/awesome
make
make install
rm -rf /tmp/awesome
while true; do
read -p "Would you like to install my neofetch config? [Y/N]: " yn
if (($yn == [Yy*])); then
backup_and_copy "$CONFIG_PATH/neofetch" "$CONFIG_PATH/neofetch_backup" "neofetch"
fi
done
# Clone, build and install picom
git clone https://github.com/yshui/picom.git /tmp
meson setup --buildtype=release build
ninja -C build
ninja -C build install
rm -rf /tmp/picom