Some fixes

This commit is contained in:
Rene Kievits
2023-04-26 00:28:06 +02:00
parent 24bce4c810
commit 0e3aafcff5
26 changed files with 1240 additions and 1388 deletions

View File

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

View File

@@ -1,3 +1,6 @@
local table = table
local ipairs = ipairs
-- Awesome libs
local akeygrabber = require('awful.keygrabber')
local akey = require('awful.key')
@@ -15,8 +18,8 @@ local config = require('src.tools.config')
local audio_helper = require('src.tools.helpers.audio')
local backlight_helper = require('src.tools.helpers.backlight')
local beautiful = require('beautiful')
local powermenu = require('src.modules.powermenu')
local kb_helper = require('src.tools.helpers.kb_helper')
local window_switcher = require('src.modules.window_switcher')
local capi = {
awesome = awesome,
@@ -26,13 +29,26 @@ local capi = {
local modkey = beautiful.user_config['modkey']
local awful = require('awful')
local f = 1
akeygrabber {
keybindings = {
akey {
modifiers = { 'Mod1' },
key = 'Tab',
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,
},
},
@@ -47,11 +63,13 @@ akeygrabber {
stop_key = 'Mod1',
stop_event = 'release',
start_callback = function()
capi.awesome.emit_signal('toggle_window_switcher')
aclient.focus.history.disable_tracking()
window_switcher.popup.visible = true
end,
stop_callback = function()
capi.awesome.emit_signal('window_switcher::raise')
capi.awesome.emit_signal('toggle_window_switcher')
aclient.focus.history.enable_tracking()
window_switcher.popup.visible = false
collectgarbage('collect')
end,
export_keybindings = true,
}
@@ -63,18 +81,6 @@ return gtable.join(
hotkeys_popup.show_help,
{ 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(
{ modkey },
'#66',
@@ -201,7 +207,7 @@ return gtable.join(
{ modkey },
'#40',
function()
capi.awesome.emit_signal('application_launcher::show')
require('src.modules.app_launcher'):toggle(capi.mouse.screen)
end,
{ descripton = 'Application launcher', group = 'Application' }
),
@@ -217,7 +223,7 @@ return gtable.join(
{ modkey, 'Shift' },
'#26',
function()
powermenu:toggle()
require('src.modules.powermenu'):toggle()
end,
{ descripton = 'Session options', group = 'System' }
),

View File

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

View File

@@ -1,19 +1,20 @@
-------------------------------
-- The Notification defaults --
-------------------------------
-- Awesome Libs
local setmetatable = setmetatable
-- Awesome Libs
local abutton = require('awful.button')
local aspawn = require('awful.spawn')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local dpi = beautiful.xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table')
local naughty = require('naughty')
local wibox = require('wibox')
local abutton = require('awful.button')
local gtable = require('gears.table')
-- Third party libs
local rubato = require('src.lib.rubato')
-- Local Libs
local hover = require('src.tools.hover')
local capi = {
@@ -21,382 +22,366 @@ local capi = {
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.icon_size = dpi(80)
naughty.config.defaults.timeout = 5
naughty.config.defaults.title = 'System Notification'
naughty.config.defaults.margin = dpi(10)
naughty.config.defaults.position = 'bottom_right'
naughty.config.defaults.border_width = dpi(2)
naughty.config.defaults.border_color = beautiful.colorscheme.border_color
naughty.config.defaults.spacing = dpi(10)
naughty.config.defaults.border_color = beautiful.colorscheme.border_color
naughty.config.defaults.border_width = dpi(2)
naughty.config.defaults.icon_size = dpi(64)
naughty.config.defaults.margin = dpi(10)
naughty.config.defaults.ontop = true
naughty.config.defaults.position = 'bottom_right'
naughty.config.defaults.spacing = dpi(10)
naughty.config.defaults.timeout = 5
naughty.config.defaults.title = 'System Notification'
naughty.connect_signal('request::display', function(n)
if beautiful.user_config.dnd then
n:destroy()
else
if not n.icon then n.icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg' end
if not n.app_name then n.app_name = 'System' end
if not n.title then n.title = 'System Notification' end
if not n.message then n.message = 'No message provided' end
naughty.connect_signal('request::display', function(n)
if beautiful.user_config.dnd then
n:destroy()
else
n.app_name = n.app_name or 'System'
n.icon = n.icon or gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg'
n.message = n.message or 'No message provided'
n.title = n.title or 'System Notification'
local color = beautiful.colorscheme.bg_blue
if n.urgency == 'critical' then
color = beautiful.colorscheme.bg_red
end
local color = beautiful.colorscheme.bg_blue
if n.urgency == 'critical' then
color = beautiful.colorscheme.bg_red
end
if n.app_name == 'Spotify' then
n.actions = {
naughty.action {
program = 'Spotify',
id = 'skip-prev',
name = 'Previous',
position = 1,
}, naughty.action {
program = 'Spotify',
id = 'play-pause',
name = 'Play/Pause',
position = 2,
}, naughty.action {
program = 'Spotify',
id = 'skip-next',
name = 'Next',
position = 3,
},
}
n.resident = true
end
if n.app_name == 'Spotify' then
n.actions = {
naughty.action {
program = 'Spotify',
id = 'skip-prev',
name = 'Previous',
position = 1,
}, naughty.action {
program = 'Spotify',
id = 'play-pause',
name = 'Play/Pause',
position = 2,
}, naughty.action {
program = 'Spotify',
id = 'skip-next',
name = 'Next',
position = 3,
},
}
n.resident = true
end
if n.category == 'device.added' or n.category == 'network.connected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-added.oga')
elseif n.category == 'device.removed' or n.category == 'network.disconnected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-removed.oga')
elseif n.category == 'device.error' or n.category == 'im.error' or n.category == 'network.error' or n.category ==
'transfer.error' then
aspawn('ogg123 ogg123 /usr/share/sounds/Pop/stereo/alert/battery-low.oga')
elseif n.category == 'email.arrived' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/message-new-email.oga')
end
if n.category == 'device.added' or n.category == 'network.connected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-added.oga')
elseif n.category == 'device.removed' or n.category == 'network.disconnected' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/device-removed.oga')
elseif n.category == 'device.error' or n.category == 'im.error' or n.category == 'network.error' or n.category ==
'transfer.error' then
aspawn('ogg123 ogg123 /usr/share/sounds/Pop/stereo/alert/battery-low.oga')
elseif n.category == 'email.arrived' then
aspawn('ogg123 /usr/share/sounds/Pop/stereo/notification/message-new-email.oga')
end
local action_template = wibox.widget {
notification = n,
base_layout = wibox.widget {
spacing = dpi(90),
layout = wibox.layout.flex.horizontal,
},
widget_template = {
{
{
widget = wibox.widget.textbox,
id = 'text_role',
valign = 'center',
halign = 'center',
font = 'JetBrainsMono Nerd Font, Bold 16',
},
widget = wibox.container.constraint,
height = dpi(35),
strategy = 'exact',
},
id = 'background_role',
widget = wibox.container.background,
bg = color,
fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8],
},
style = {
underline_normal = false,
underline_selected = false,
shape_normal = beautiful.shape[8],
--Don't remove or it will break
bg_normal = color,
bg_selected = color,
fg_normal = beautiful.colorscheme.bg,
fg_selected = beautiful.colorscheme.bg,
},
widget = naughty.list.actions,
}
local action_template = wibox.widget {
notification = n,
base_layout = wibox.widget {
spacing = dpi(90),
layout = wibox.layout.flex.horizontal,
},
widget_template = {
{
{
widget = wibox.widget.textbox,
id = 'text_role',
valign = 'center',
halign = 'center',
font = beautiful.user_config.font .. ' bold 16',
},
widget = wibox.container.constraint,
height = dpi(35),
strategy = 'exact',
},
id = 'background_role',
widget = wibox.container.background,
bg = color,
fg = beautiful.colorscheme.bg,
shape = beautiful.shape[8],
},
style = {
underline_normal = false,
underline_selected = false,
shape_normal = beautiful.shape[8],
--Don't remove or it will break
bg_normal = color,
bg_selected = color,
fg_normal = beautiful.colorscheme.bg,
fg_selected = beautiful.colorscheme.bg,
},
widget = naughty.list.actions,
}
-- Hack to get the action buttons to work even after update
for i = 1, #action_template._private.layout.children, 1 do
hover.bg_hover { widget = action_template._private.layout.children[i].children[1], overlay = 12, press_overlay = 24 }
end
if (#action_template._private.layout.children > 0) and action_template._private.notification[1].actions[1].program == 'Spotify' then
action_template._private.layout.children[1].children[1]:connect_signal('button::press', function()
aspawn('playerctl previous')
end)
action_template._private.layout.children[2].children[1]:connect_signal('button::press', function()
aspawn('playerctl play-pause')
end)
action_template._private.layout.children[3].children[1]:connect_signal('button::press', function()
aspawn('playerctl next')
end)
end
-- Hack to get the action buttons to work even after update
for i = 1, #action_template._private.layout.children, 1 do
hover.bg_hover { widget = action_template._private.layout.children[i].children[1], overlay = 12, press_overlay = 24 }
end
if (#action_template._private.layout.children > 0) and action_template._private.notification[1].actions[1].program == 'Spotify' then
action_template._private.layout.children[1].children[1]:connect_signal('button::press', function()
aspawn('playerctl previous')
end)
action_template._private.layout.children[2].children[1]:connect_signal('button::press', function()
aspawn('playerctl play-pause')
end)
action_template._private.layout.children[3].children[1]:connect_signal('button::press', function()
aspawn('playerctl next')
end)
end
local start_timer = n.timeout
if n.timeout == 0 then
start_timer = 5
end
local start_timer = n.timeout
if n.timeout == 0 then
start_timer = 5
end
local notification = wibox.template {
widget = wibox.widget {
{
{
{
{ -- Title
local notification = wibox.template {
widget = wibox.widget {
{
{
{
{ -- 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,
shape = beautiful.shape[4],
{ -- Title
{
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,
strategy = 'exact',
width = dpi(20),
height = dpi(20),
height = dpi(128),
width = dpi(128),
},
{ -- Title
{
{
notification = n,
widget = naughty.widget.title,
markup = [[<span foreground="]] ..
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>]],
widget = naughty.widget.message,
font = beautiful.user_config.font .. ' bold 10',
halign = 'left',
valign = 'center',
},
widget = wibox.container.constraint,
width = dpi(430),
height = dpi(35),
strategy = 'max',
strategy = 'exact',
height = dpi(128),
},
spacing = dpi(10),
spacing = dpi(15),
layout = wibox.layout.fixed.horizontal,
},
widget = wibox.container.margin,
left = dpi(10),
},
nil,
{
{
{ -- Clock
widget = wibox.widget.textclock,
format = '%H:%M',
font = 'JetBrainsMono Nerd Font, Bold 16',
fg = beautiful.colorscheme.bg,
halign = 'right',
valign = 'center',
{ -- Spacer
{
widget = wibox.container.background,
bg = beautiful.colorscheme.bg,
},
{ -- 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,
widget = wibox.container.constraint,
strategy = 'exact',
height = dpi(2),
},
right = dpi(5),
widget = wibox.container.margin,
action_template,
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 = color,
fg = beautiful.colorscheme.bg,
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
shape = beautiful.shape[8],
widget = wibox.container.background,
},
{ -- 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,
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.constraint,
strategy = 'exact',
width = dpi(600),
},
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
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()
if #action_template._private.layout.children < 1 then
notification:get_widget().children[1].children[1].children[1].children[3] = nil
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)
--[[
naughty.notification {
app_name = 'Spotify',
title = 'The Beatles - Here Comes The Sun',
message = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
icon = '/home/crylia/Bilder/57384097.jpg',
timeout = 30,
actions = {
naughty.action {
name = 'amet',
position = 1,
text = 'Test',
},
naughty.action {
name = 'Lorem ipsum dolor sit amet',
position = 2,
},
naughty.action {
name = 'Lorem',
position = 3,
},
},
}
]]
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),
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,112 @@
-------------------------------------------------------------------------------------------------
-- This class contains rules for float exceptions or special themeing for certain applications --
-------------------------------------------------------------------------------------------------
local setmetatable = setmetatable
local ipairs = ipairs
-- Awesome Libs
local aclient = require('awful.client')
local aplacement = require('awful.placement')
local ascreen = require('awful.screen')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local dpi = beautiful.xresources.apply_dpi
local ruled = require('ruled')
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()
ruled.client.append_rule {
rule = {},
properties = {
border_width = dpi(2),
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,
},
}
local instance = nil
if not instance then
instance = setmetatable({}, {
__call = function()
capi.awesome.register_xproperty('_NET_WM_BYPASS_COMPOSITOR', 'boolean')
ruled.client.append_rule {
rule_any = {
type = {
'normal',
'dialog',
},
},
properties = {
titlebars_enabled = true,
},
}
ruled.client.connect_signal('request::rules', function()
ruled.client.append_rule {
rule = {},
properties = {
border_width = dpi(2),
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 {
rule_any = {
class = {
'proton-bridge',
'1password',
'protonvpn',
'Steam',
},
},
properties = {
minimized = true,
},
}
ruled.client.append_rule {
rule_any = {
class = {
'discord',
'spotify',
},
},
properties = {
tag = '1',
screen = 2,
},
}
ruled.client.append_rule {
rule_any = {
type = {
'normal',
'dialog',
},
},
properties = {
titlebars_enabled = true,
},
}
ruled.client.append_rule {
rule_any = {
class = {
'proton-bridge',
'1password',
'protonvpn',
'Steam',
},
},
properties = {
minimized = true,
},
}
ruled.client.append_rule {
rule_any = {
class = {
'discord',
'spotify',
},
},
properties = {
tag = '1',
screen = 2,
},
}
ruled.client.append_rule {
rule_any = {
class = {
'steam_app_990080',
},
},
callback = function(c)
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
c:connect_signal('focus', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end)
c:connect_signal('raised', function()
c:set_xproperty('_NET_WM_BYPASS_COMPOSITOR', true)
end)
end,
}
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)
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)
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
return instance

View File

@@ -1,5 +1,8 @@
--- A module to manage the first installation and setup the config without having to edit
--- the config files manually.
local setmetatable = setmetatable
local pairs = pairs
local ipairs = ipairs
local table = table
local math = math
--Awesome Libs
local abutton = require('awful.button')
@@ -10,20 +13,19 @@ local atooltip = require('awful.tooltip')
local beautiful = require('beautiful')
local dpi = require('beautiful').xresources.apply_dpi
local gcolor = require('gears.color')
local gfilesystem = require('gears.filesystem')
local gtable = require('gears.table')
local wibox = require('wibox')
local gfilesystem = require('gears.filesystem')
local inputwidget = require('src.modules.inputbox')
--Own Libs
local toggle_button = require('awful.widget.toggle_widget')
local inputwidget = require('src.modules.inputbox')
local capi = {
screen = screen,
}
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 setup = { mt = {} }

View File

@@ -1,11 +1,10 @@
---@diagnostic disable: undefined-field
local setmetatable = setmetatable
-- Awesome Libs
local aplacement = require('awful.placement')
local gtimer = require('gears.timer')
local ascreen = require('awful.screen')
local ruled = require('ruled')
local config = require('src.tools.config')
local beautiful = require('beautiful')
local gtimer = require('gears.timer')
local capi = {
awesome = awesome,
@@ -15,60 +14,62 @@ local capi = {
tag = tag,
}
capi.screen.connect_signal('added', function()
capi.awesome.restart()
end)
local instance = nil
if not instance then
instance = setmetatable({}, {
__call = function()
capi.screen.connect_signal('added', function()
capi.awesome.restart()
end)
capi.screen.connect_signal('removed', function()
capi.awesome.restart()
end)
capi.screen.connect_signal('removed', function()
capi.awesome.restart()
end)
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
aplacement.no_offscreen(c)
end
if c.transient_for then
c.floating = true
end
if c.fullscreen then
gtimer.delayed_call(function()
if c.valid then
c:geometry(c.screen.geometry)
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
aplacement.no_offscreen(c)
end
if c.transient_for then
c.floating = true
end
if c.fullscreen then
gtimer.delayed_call(function()
if c.valid then
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
collectgarbage('collect')
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
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) ]]
end
return instance

View File

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

View File

@@ -18,6 +18,8 @@ local gshape = require('gears.shape')
local gobject = require('gears.object')
local mousegrabber = mousegrabber
local rubato = require('src.lib.rubato')
local overflow = { mt = {} }
-- 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_enabled = self._private.scrollbar_enabled
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
-- 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.
function overflow:layout(context, orig_width, orig_height)
local result = {}
local is_y = self._private.dir == "y"
local is_y = self._private.dir == 'y'
local widgets = self._private.widgets
local avail_in_dir = is_y and orig_height or orig_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_y = bar_pos
if scrollbar_position == "left" then
if scrollbar_position == 'left' then
widget_x = widget_x + bar_w
elseif scrollbar_position == "right" then
elseif scrollbar_position == 'right' then
bar_x = orig_width - bar_w
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_x = bar_pos
if scrollbar_position == "top" then
if scrollbar_position == 'top' then
widget_y = widget_y + bar_h
elseif scrollbar_position == "bottom" then
elseif scrollbar_position == 'bottom' then
bar_y = orig_height - bar_h
end
@@ -305,6 +307,13 @@ end
-- @tparam number scroll_factor The scroll factor.
-- @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)
local current = self._private.scroll_factor
local interval = self._private.used_in_dir - self._private.avail_in_dir
@@ -318,10 +327,22 @@ function overflow:set_scroll_factor(factor)
return
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")
self:emit_signal("property::scroll_factor", factor)
if first_call then
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))
print(self.rubato_timed.target)
--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
function overflow:get_scroll_factor()
@@ -347,8 +368,8 @@ function overflow:set_scrollbar_width(width)
self._private.scrollbar_width = width
self:emit_signal("widget::layout_changed")
self:emit_signal("property::scrollbar_width", width)
self:emit_signal('widget::layout_changed')
self:emit_signal('property::scrollbar_width', width)
end
--- The scrollbar position.
@@ -370,8 +391,8 @@ function overflow:set_scrollbar_position(position)
self._private.scrollbar_position = position
self:emit_signal("widget::layout_changed")
self:emit_signal("property::scrollbar_position", position)
self:emit_signal('widget::layout_changed')
self:emit_signal('property::scrollbar_position', position)
end
function overflow:get_scrollbar_position()
@@ -396,8 +417,8 @@ function overflow:set_scrollbar_enabled(enabled)
self._private.scrollbar_enabled = enabled
self:emit_signal("widget::layout_changed")
self:emit_signal("property::scrollbar_enabled", enabled)
self:emit_signal('widget::layout_changed')
self:emit_signal('property::scrollbar_enabled', enabled)
end
function overflow:get_scrollbar_enabled()
@@ -407,7 +428,7 @@ end
-- Wraps a callback function for `mousegrabber` that is capable of
-- updating the scroll factor.
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 start_pos = container._private.scroll_factor * bar_interval
local start = is_y and initial_y or initial_x
@@ -439,7 +460,7 @@ local function apply_scrollbar_mouse_signal(container, w)
if button_id ~= 1 then
return
end
mousegrabber.run(build_grabber(container, x, y, geo), "fleur")
mousegrabber.run(build_grabber(container, x, y, geo), 'fleur')
end)
end
@@ -461,8 +482,8 @@ function overflow:set_scrollbar_widget(widget)
self._private.scrollbar_widget = w
self:emit_signal("widget::layout_changed")
self:emit_signal("property::scrollbar_widget", widget)
self:emit_signal('widget::layout_changed')
self:emit_signal('property::scrollbar_widget', widget)
end
function overflow:get_scrollbar_widget()
@@ -473,13 +494,13 @@ function overflow:reset()
self._private.widgets = {}
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)
self._private.scrollbar_widget = scrollbar_widget
self:emit_signal("widget::layout_changed")
self:emit_signal("widget::reset")
self:emit_signal("widget::reseted")
self:emit_signal('widget::layout_changed')
self:emit_signal('widget::reset')
self:emit_signal('widget::reseted')
end
local function new(dir, ...)
@@ -500,9 +521,9 @@ local function new(dir, ...)
ret._private.fill_space = true
ret._private.scrollbar_width = 5
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)
ret._private.scrollbar_widget = scrollbar_widget
@@ -525,7 +546,7 @@ end
-- @tparam widget ... Widgets that should be added to the layout.
-- @constructorfct wibox.layout.overflow.horizontal
function overflow.horizontal(...)
return new("horizontal", ...)
return new('horizontal', ...)
end
--- Returns a new vertical overflow layout.
@@ -536,7 +557,7 @@ end
-- @tparam widget ... Widgets that should be added to the layout.
-- @constructorfct wibox.layout.overflow.vertical
function overflow.vertical(...)
return new("vertical", ...)
return new('vertical', ...)
end
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 akey = require('awful.key')
local akeygrabber = require('awful.keygrabber')
@@ -5,22 +13,22 @@ local aplacement = require('awful.placement')
local apopup = require('awful.popup')
local beautiful = require('beautiful')
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 gtimer = require('gears.timer')
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 hover = require('src.tools.hover')
local inputbox = require('src.modules.inputbox')
-- Local Libs
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 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/'
@@ -31,6 +39,12 @@ local capi = {
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.
--- @param self The launcher table.
---
function launcher:fetch_apps()
for _, app in ipairs(Gio.AppInfo.get_all()) do
local app_id = app:get_id()
@@ -190,54 +204,15 @@ function launcher:fetch_apps()
end
end
local function levenshtein_distance(str1, str2)
local len1 = string.len(str1)
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
---Reset the grid and add all apps that match to a filter using fzy scoring
---@param filter string Filter for the name, category and keywords
function launcher:filter_apps(filter)
filter = filter or ''
self.grid:reset()
local app_list = {}
for _, app in pairs(self.app_table) do
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.keywords or '')
then
@@ -245,17 +220,22 @@ function launcher:filter_apps(filter)
end
end
table.sort(app_list, function(a, b)
return a.name < b.name
end)
--sort by lowest levenshtein distance
table.sort(app_list, function(a, b)
return levenshtein_distance(filter, a.name) < levenshtein_distance(filter, b.name)
local score_a = fzy.score(filter, a.name)
local score_b = fzy.score(filter, b.name)
if score_a ~= score_b then
return score_a > score_b
else
return a.name < b.name
end
end)
for _, app in ipairs(app_list) do
self.grid:add(app)
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)
if not self.popup.visible then
self.popup.screen = screen
@@ -268,13 +248,20 @@ function launcher:toggle(screen)
x = 1, y = 1,
}
self.popup.visible = false
collectgarbage('collect')
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)
self.grid:get_widgets_at(y, x)[1].border_color = beautiful.colorscheme.border_color
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)
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]
@@ -282,7 +269,10 @@ function launcher:selection_update(x, y)
w_new.border_color = beautiful.colorscheme.bg_teal
end
-- Offset to know when to scroll up/down
local up_offset = 0
--- Move the cursor down
function launcher:move_down()
local row, _ = self.grid:get_dimension()
if self.cursor.y < row then
@@ -303,6 +293,7 @@ function launcher:move_down()
end
end
--- Move the cursor up
function launcher:move_up()
local row, _ = self.grid:get_dimension()
if self.cursor.y > 1 then
@@ -320,6 +311,7 @@ function launcher:move_up()
end
end
--- Move the cursor left
function launcher:move_left()
if self.cursor.x > 1 then
self.cursor.x = self.cursor.x - 1
@@ -327,6 +319,7 @@ function launcher:move_left()
end
end
--- Move the cursor right
function launcher:move_right()
local _, col = self.grid:get_dimension()
if self.cursor.x < col then
@@ -336,11 +329,13 @@ function launcher:move_right()
end
end
--- Wrapper to focus the searchbar
function launcher:focus_searchbar()
self.searchbar:focus()
self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.bg_teal
end
--- Wrapper to unfocus the searchbar
function launcher:unfocus_searchbar()
self.searchbar:unfocus()
self.popup.widget:get_children_by_id('searchbar_bg')[1].border_color = beautiful.colorscheme.border_color
@@ -450,6 +445,7 @@ if not instance then
self:toggle(capi.mouse.screen)
self.grid:get_widgets_at(self.cursor.x, self.cursor.y)[1].execute()
self:filter_apps('')
self.searchbar:set_text('')
elseif key == 'Down' then
if not (self.keygrabber.running == akeygrabber.current_instance) then
self:selection_update(1, 1)

View File

@@ -15,7 +15,7 @@ local lgi = require('lgi')
local wibox = require('wibox')
-- 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 input = require('src.modules.inputbox')

View File

@@ -413,84 +413,6 @@ function bluetooth.new(args)
widget = wibox.container.margin,
}
assert(type(ret) == 'table', 'bluetooth_controller: ret is not a table')
-- Get a reference to the dnd button
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
-- Toggle bluetooth on or off
dnd:connect_signal('dnd::toggle', function()
ret:toggle()
end)
gtable.crush(ret, bluetooth, true)
--#region Bluetooth Proxies
-- Create a proxy for the freedesktop ObjectManager
ret._private.ObjectManager = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.ObjectManager',
path = '/',
}
-- Create a proxy for the bluez Adapter1 interface
ret._private.Adapter1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.Adapter1',
path = '/org/bluez/hci0',
}
if not ret._private.Adapter1.Powered then return end
-- Create a proxy for the bluez Adapter1 Properties interface
ret._private.Adapter1Properties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.Properties',
path = '/org/bluez/hci0',
}
-- Connect to the ObjectManager's InterfacesAdded signal
ret._private.ObjectManager:connect_signal(function(_, interface)
ret:get_device_info(interface)
end, 'InterfacesAdded')
-- Connect to the ObjectManager's InterfacesRemoved signal
ret._private.ObjectManager:connect_signal(function(_, interface)
ret:remove_device(interface)
end, 'InterfacesRemoved')
-- Connect to the Adapter1's PropertiesChanged signal
ret._private.Adapter1Properties:connect_signal(function(_, _, data)
if data.Powered ~= nil then
send_state_notification(data.Powered)
if data.Powered then
dnd:set_enabled()
ret:scan()
else
dnd:set_disabled()
end
ret:emit_signal('bluetooth::status', data.Powered)
end
end, 'PropertiesChanged')
gtimer.delayed_call(function()
for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do
ret:get_device_info(path)
end
if ret._private.Adapter1.Powered then
dnd:set_enabled()
ret:scan()
else
dnd:set_disabled()
end
ret:emit_signal('bluetooth::status', ret._private.Adapter1.Powered)
send_state_notification(ret._private.Adapter1.Powered)
end)
--#endregion
--#region Dropdown logic
local connected_margin = ret:get_children_by_id('connected_margin')[1]
local connected_list = ret:get_children_by_id('connected_list')[1]
@@ -626,6 +548,14 @@ function bluetooth.new(args)
end)
--#endregion
-- Get a reference to the dnd button
local dnd = ret:get_children_by_id('dnd')[1]:get_widget()
-- Toggle bluetooth on or off
dnd:connect_signal('dnd::toggle', function()
ret:toggle()
end)
-- Add buttons to the scan button
ret:get_children_by_id('scan')[1]:buttons {
abutton({}, 1, function()
@@ -637,6 +567,74 @@ function bluetooth.new(args)
hover.bg_hover { widget = connected_margin.connected_bg }
hover.bg_hover { widget = discovered_bg }
gtable.crush(ret, bluetooth, true)
--#region Bluetooth Proxies
-- Create a proxy for the freedesktop ObjectManager
ret._private.ObjectManager = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.ObjectManager',
path = '/',
}
-- Create a proxy for the bluez Adapter1 interface
ret._private.Adapter1 = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.bluez.Adapter1',
path = '/org/bluez/hci0',
}
if not ret._private.Adapter1.Powered then return ret end
-- Create a proxy for the bluez Adapter1 Properties interface
ret._private.Adapter1Properties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.bluez',
interface = 'org.freedesktop.DBus.Properties',
path = '/org/bluez/hci0',
}
-- Connect to the Adapter1's PropertiesChanged signal
ret._private.Adapter1Properties:connect_signal(function(_, _, data)
if data.Powered ~= nil then
send_state_notification(data.Powered)
if data.Powered then
dnd:set_enabled()
ret:scan()
else
dnd:set_disabled()
end
ret:emit_signal('bluetooth::status', data.Powered)
end
end, 'PropertiesChanged')
-- Connect to the ObjectManager's InterfacesAdded signal
ret._private.ObjectManager:connect_signal(function(_, interface)
ret:get_device_info(interface)
end, 'InterfacesAdded')
-- Connect to the ObjectManager's InterfacesRemoved signal
ret._private.ObjectManager:connect_signal(function(_, interface)
ret:remove_device(interface)
end, 'InterfacesRemoved')
gtimer.delayed_call(function()
for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do
ret:get_device_info(path)
end
if ret._private.Adapter1.Powered then
dnd:set_enabled()
ret:scan()
else
dnd:set_disabled()
end
ret:emit_signal('bluetooth::status', ret._private.Adapter1.Powered)
send_state_notification(ret._private.Adapter1.Powered)
end)
--#endregion
return ret
end

View File

@@ -478,12 +478,14 @@ function calendar:create_calendar_widget()
task_popup.x = capi.mouse.coords().x
task_popup.y = capi.mouse.coords().y
task_popup.visible = not task_popup.visible
collectgarbage('collect')
end)
)
)
tw:connect_signal('mouse::leave', function()
task_popup.visible = false
collectgarbage('collect')
end)
hover.bg_hover { widget = tw }
@@ -754,7 +756,7 @@ function calendar.new(args)
{
widget = wibox.widget.imagebox,
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',
valign = 'center',
},
@@ -883,7 +885,7 @@ function calendar.new(args)
border_width = dpi(2),
border_strategy = 'inner',
fg = beautiful.colorscheme.fg,
shape = beautiful.shape,
shape = beautiful.shape[12],
})
ret:get_tasks()

View File

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

View File

@@ -74,27 +74,24 @@ function dock:toggle()
self.popup.visible = not self.popup.visible
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
local elements_copy = { pinned = {} }
for _, element in ipairs(elements['pinned']) do
table.insert(elements_copy['pinned'], { desktop_file = element.desktop_file })
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
---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(callback)
function dock:read_elements_from_file_async()
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
for _, v in ipairs(data) do
local w = self:get_element_widget(v.desktop_file)
table.insert(elements['pinned'], w)
end
if callback then
callback()
end
end
---Creates a pinned widget for the dock and adds it into the elements table
@@ -135,6 +132,7 @@ function dock:get_element_widget(desktop_file)
bg = beautiful.colorscheme.bg1,
shape = beautiful.shape[8],
widget = wibox.container.background,
desktop_file = desktop_file,
}
local action_entries = {}

View File

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

View File

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

View File

@@ -20,7 +20,7 @@ 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 cm = require('src.modules.context_menu')
local hover = require('src.tools.hover')
local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/'
@@ -268,7 +268,7 @@ function access_point.new(args)
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
if ret.is_ap_active(ret.NetworkManagerAccessPoint) 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)

View File

@@ -43,7 +43,7 @@ function ap_form.new(args)
{
widget = wibox.widget.textbox,
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid),
font = beautiful.user_config.font.specify .. ',extra bold 16',
font = beautiful.user_config.font .. ' extra bold 16',
halign = 'center',
valign = 'center',
},

View File

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

View File

@@ -1,6 +1,4 @@
--------------------------------
-- This is the network widget --
--------------------------------
local setmetatable = setmetatable
-- Awesome Libs
local abutton = require('awful.button')
@@ -106,110 +104,106 @@ end
function powermenu:toggle()
self.keygrabber:start()
self.visible = not self.visible
end
function powermenu.new()
local w = wibox {
widget = {
{
{
{
{
image = icondir .. 'defaultpfp.svg',
resize = true,
clip_shape = 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
self.w.visible = not self.w.visible
end
if instance == nil then
instance = powermenu.new()
instance = setmetatable(powermenu, {
__call = function(self)
self.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,
}
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)
if stdout then
self.w:get_children_by_id('icon_role')[1].image = stdout:gsub('\n', '')
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
return instance

View File

@@ -17,139 +17,117 @@ local base = require('wibox.widget.base')
local gtimer = require('gears.timer')
local cairo = require('lgi').cairo
local awidget = require('awful.widget')
local capi = {
awesome = awesome,
client = client,
mouse = mouse,
}
--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 ascreenshot = require('awful.screenshot')
local wtemplate = require('wibox.template')
local akeygrabber = require('awful.keygrabber')
local akey = require('awful.key')
local abutton = require('awful.button')
local aclient = require('awful.client')
local awful = require('awful')
local client_preview = {}
local instance = nil
if not instance then
instance = setmetatable(client_preview, {
__call = function(self, s)
function client_preview:toggle()
self.visible = not self.visible
end
return setmetatable(client_preview, {
__call = function(...)
local args = ...
local w = gobject {}
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 {
self.popup = apopup {
widget = awidget.tasklist {
screen = 1,
layout = wibox.layout.fixed.horizontal,
filter = awidget.tasklist.filter.alltags,
style = {
font = beautiful.user_config.font .. ' regular 12',
},
widget_template = wibox.template {
{
{
{
{
widget = wibox.widget.imagebox,
resize = true,
id = c.instance,
{
{ -- icon and text
{
{
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,
height = dpi(256),
strategy = 'exact',
widget = wibox.container.margin,
margins = dpi(20),
},
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,
margins = dpi(20),
},
bg = beautiful.colorscheme.bg,
widget = wibox.container.background,
bg = '#414141',
id = c.pid,
shape = gshape.rounded_rect,
}
gtimer {
timeout = 1 / 24,
autostart = true,
callback = function()
local content = gsurface(c.content)
local cr = cairo.Context(content)
local x, y, w, h = cr:clip_extents()
local img = cairo.ImageSurface.create(cairo.Format.ARGB32, w - x, h - y)
cr = cairo.Context(img)
cr:set_source_surface(content, 0, 0)
cr.operator = cairo.Operator.SOURCE
cr:paint()
local cont = tw:get_children_by_id('icon_role')[1]
if cont then
cont.image = gsurface.load(img)
return
create_callback = function(sself, c)
local ss = ascreenshot {
client = c,
}
ss:refresh()
local ib = ss.content_widget
ib.clip_shape = beautiful.shape[12]
ib.valign = 'center'
ib.halign = 'center'
sself:get_widget():get_children_by_id('screenshot')[1].widget = ib
end,
update_callback = function(sself, c)
if c.active and self.popup.visible then
local ss = ascreenshot {
client = c,
}
ss:refresh()
local ib = ss.content_widget
ib.clip_shape = beautiful.shape[12]
ib.valign = 'center'
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,
}
widget:add(tw)
end
return widget
end,
} ]]
w.popup = apopup {
widget = {},
ontop = true,
visible = true,
screen = args.screen,
placement = aplacement.centered,
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
}
return w
end,
})
},
},
ontop = true,
visible = false,
screen = s,
bg = beautiful.colorscheme.bg,
border_color = beautiful.colorscheme.border_color,
border_width = dpi(2),
placement = aplacement.centered,
}
end,
})
end
return instance

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

@@ -1,3 +1,7 @@
local setmetatable = setmetatable
local print = print
local type = type
--------------------------------------------------
-- ██████╗██████╗ ██╗ ██╗██╗ ██╗ █████╗ --
-- ██╔════╝██╔══██╗╚██╗ ██╔╝██║ ██║██╔══██╗ --
@@ -6,6 +10,7 @@
-- ╚██████╗██║ ██║ ██║ ███████╗██║██║ ██║ --
-- ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝ --
--------------------------------------------------
local awful = require('awful')
local beautiful = require('beautiful')
local dpi = beautiful.xresources.apply_dpi
@@ -19,116 +24,122 @@ local capi = {
screen = screen,
}
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')
local instance = nil
if not instance then
instance = setmetatable({}, {
__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')
end
data = config.read_json('/etc/crylia_theme/crylia_theme.json')
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
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')()
return instance

View File

@@ -8,18 +8,17 @@ local ical_calendar_cache = {}
local date_time = {}
setmetatable(date_time, {
__call = function(args)
local dt = table.copy(date_time)
__call = function(self, args)
dt.day = args.day or 1
dt.month = args.month or 1
dt.year = args.year or 1970
self.day = args.day or 1
self.month = args.month or 1
self.year = args.year or 1970
dt.hour = args.hour or 0
dt.minute = args.minute or 0
dt.second = args.second or 0
self.hour = args.hour or 0
self.minute = args.minute or 0
self.second = args.second or 0
return dt
return self
end,
__newindex = function(self, ...)
if ... == 'weeknum' then
@@ -29,53 +28,135 @@ setmetatable(date_time, {
return self.weeknum
end
end,
__add = function(a, b)
local dt = table.copy(date_time)
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)
__tostring = function(self)
return string.format('%d-%d-%d %d:%d:%d', self.year, self.month, self.day, self.hour, self.minute, self.second)
end,
});
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
---Start parsing a new calendar
---@param path string path to .ical file
function parser.parse(path)
function parser.VTIMEZONE(handler)
local parse = {}
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 ical_calendar_cache[ical_name] then
return ical_calendar_cache[ical_name]
else
-- If not create a new one in the cache
ical_calendar_cache[ical_name] = {}
if key == 'BEGIN' then
if value == 'DAYLIGHT' or value == 'STANDARD' then
parse[value] = parser.TZ(handler)
end
elseif key == 'TZID' then
parse[key] = value
elseif key == 'LAST-MODIFIED' then
parse[key] = value
elseif key == 'X-LIC-LOCATION' then
parse[key] = value
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
function parser.new(path)
local cal = {}
-- Get the file from the path
local ical_name = path
@@ -85,12 +166,27 @@ function parser.new(path)
return ical_calendar_cache[ical_name]
end
-- If not create a new one in the cache
ical_calendar_cache[ical_name] = { mt = {} }
local handler = io.open(path, 'r')
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]
end
local instance = nil
if not instance then
instance = setmetatable(parser, {
-- 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)
end
calendar_popup.visible = not calendar_popup.visible
collectgarbage('collect')
end)
), }