diff --git a/awesome/src/assets/userpfp/userpfp.png b/awesome/src/assets/userpfp/userpfp.png index f7f5c0d..0b684b3 100644 Binary files a/awesome/src/assets/userpfp/userpfp.png and b/awesome/src/assets/userpfp/userpfp.png differ diff --git a/awesome/src/bindings/global_keys.lua b/awesome/src/bindings/global_keys.lua index b4ded56..4ea358e 100644 --- a/awesome/src/bindings/global_keys.lua +++ b/awesome/src/bindings/global_keys.lua @@ -240,7 +240,9 @@ return gtable.join( {}, 'XF86AudioLowerVolume', 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, { description = 'Lower volume', group = 'System' } ), @@ -248,7 +250,9 @@ return gtable.join( {}, 'XF86AudioRaiseVolume', 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, { description = 'Increase volume', group = 'System' } ), @@ -256,7 +260,7 @@ return gtable.join( {}, 'XF86AudioMute', function(c) - audio_helper.sink_toggle_mute() + audio_helper:sink_toggle_mute() end, { description = 'Mute volume', group = 'System' } ), @@ -330,8 +334,8 @@ return gtable.join( -- Check if data already had the client then return for _, v in ipairs(data) do if v.WM_NAME == client_data.WM_NAME and - v.WM_CLASS == client_data.WM_CLASS and - v.WM_INSTANCE == client_data.WM_INSTANCE then + v.WM_CLASS == client_data.WM_CLASS and + v.WM_INSTANCE == client_data.WM_INSTANCE then return end end @@ -375,7 +379,7 @@ return gtable.join( -- Remove client_data from data_table for k, v in ipairs(data) do 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) ruled.client.remove_rule { rule = { class = c.class, instance = c.instance }, diff --git a/awesome/src/core/signals.lua b/awesome/src/core/signals.lua index ef62e9a..5147b42 100644 --- a/awesome/src/core/signals.lua +++ b/awesome/src/core/signals.lua @@ -48,7 +48,6 @@ if not instance then raise = true, }) end - collectgarbage('collect') end) capi.tag.connect_signal('property::selected', function(c) diff --git a/awesome/src/modules/audio/init.lua b/awesome/src/modules/audio/init.lua new file mode 100644 index 0000000..84060c9 --- /dev/null +++ b/awesome/src/modules/audio/init.lua @@ -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 diff --git a/awesome/src/modules/audio/volume_osd.lua b/awesome/src/modules/audio/volume_osd.lua deleted file mode 100644 index b4f1594..0000000 --- a/awesome/src/modules/audio/volume_osd.lua +++ /dev/null @@ -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 }) diff --git a/awesome/src/modules/bluetooth/device.lua b/awesome/src/modules/bluetooth/device.lua index bc04cf8..6f5a2ac 100644 --- a/awesome/src/modules/bluetooth/device.lua +++ b/awesome/src/modules/bluetooth/device.lua @@ -227,7 +227,8 @@ function device.new(args) widget = wibox.container.margin, }, widget = wibox.container.background, - }, spacing = dpi(10), + }, + spacing = dpi(10), entries = { { -- Connect/Disconnect a device name = ret.device.Connected and 'Disconnect' or 'Connect', diff --git a/awesome/src/modules/bluetooth/init.lua b/awesome/src/modules/bluetooth/init.lua index d02cea8..726844b 100644 --- a/awesome/src/modules/bluetooth/init.lua +++ b/awesome/src/modules/bluetooth/init.lua @@ -1,645 +1,420 @@ --------------------------------------- --- This is the bluetooth controller -- --------------------------------------- +local setmetatable = setmetatable --- Awesome Libs -local abutton = require('awful.button') -local aspawn = require('awful.spawn') -local base = require('wibox.widget.base') -local beautiful = require('beautiful') -local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy') -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 naughty = require('naughty') local wibox = require('wibox') +local gtable = require('gears.table') +local gobject = require('gears.object') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local base = require('wibox.widget.base') +local gfilesystem = require('gears.filesystem') +local gcolor = require('gears.color') +local gshape = require('gears.shape') +local abutton = require('awful.button') --- Third party libs local rubato = require('src.lib.rubato') -local hover = require('src.tools.hover') --- Own libs -local bt_device = require('src.modules.bluetooth.device') +local bt = require('src.tools.bluetooth.adapter')() +local dev = require('src.tools.bluetooth.device') local dnd_widget = require('awful.widget.toggle_widget') local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/' -local capi = { - awesome = awesome, - mouse = mouse, - mousegrabber = mousegrabber, -} +local bluetooth = gobject {} -local bluetooth = { mt = {} } ---#region wibox.widget.base boilerplate +---Add a device to a specified list +---@param path string device +function bluetooth:add_device_to_list(path) + if not path then return end -function bluetooth:layout(_, width, height) - if self._private.widget then - return { base.place_widget_at(self._private.widget, 0, 0, width, height) } - end -end + local paired_list = self:get_children_by_id('paired_list')[1] + local discovered_list = self:get_children_by_id('discovered_list')[1] -function bluetooth:fit(context, width, height) - local w, h = 0, 0 - if self._private.widget then - w, h = base.fit_widget(self, context, self._private.widget, width, height) - end - return w, h -end + local device = dev(path) -bluetooth.set_widget = base.set_widget_common - -function bluetooth:get_widget() - return self._private.widget -end - ---#endregion - ----Get the list of paired devices ----@return table devices table of paired devices -function bluetooth:get_paired_devices() - return self:get_children_by_id('connected_device_list')[1].children -end - ----Get the list of discovered devices ----@return table devices table of discovered devices -function bluetooth:get_discovered_devices() - return self:get_children_by_id('discovered_device_list')[1].children -end - ---- Remove a device by first disconnecting it async then removing it -function bluetooth:remove_device_information(device) - device:DisconnectAsync(function(_, _, out, err) - self._private.Adapter1:RemoveDevice(device.object_path) - end) -end - ---- Add a new device into the devices list -function bluetooth:add_device(device, object_path) - - -- Get a reference to both lists - local plist = self:get_children_by_id('connected_device_list')[1] - local dlist = self:get_children_by_id('discovered_device_list')[1] - - -- For the first list check if the device already exists and if its connection state changed - -- if it changed then remove it from the current list and put it into the other one - for _, value in pairs(dlist.children) do - -- I'm not sure why Connected is in both cases true when its a new connection but eh just take it, it works - if value.device.Address:match(device.Address) and (device.Connected ~= value.device.Connected) then - return - elseif value.device.Address:match(device.Address) and (device.Connected == value.device.Connected) then - dlist:remove_widgets(value) - plist:add(plist:add(bt_device { - device = device, - path = object_path, - remove_callback = function() - self:remove_device_information(device) - end, - })) - return; - end - end - -- Just check if the device already exists in the list - for _, value in pairs(plist.children) do - if value.device.Address:match(device.Address) then return end - end - - -- If its paired add it to the paired list - -- else add it to the discovered list + local bg, fg if device.Paired then - plist:add(bt_device { - device = device, - path = object_path, - remove_callback = function() - self:remove_device_information(device) - end, - }) - self:emit_signal('device::added_connected') + bg = beautiful.colorscheme.bg_blue + fg = beautiful.colorscheme.bg else - dlist:add(bt_device { - device = device, - path = object_path, - remove_callback = function() - self:remove_device_information(device) - end, - }) - self:emit_signal('device::added_discovered') + bg = beautiful.colorscheme.bg + fg = beautiful.colorscheme.bg_blue end -end ----Remove a device from any list ----@param object_path string the object path of the device -function bluetooth:remove_device(object_path) - local plist = self:get_children_by_id('connected_device_list')[1] - local dlist = self:get_children_by_id('discovered_device_list')[1] - for _, d in ipairs(dlist.children) do - if d.device.object_path == object_path then - dlist:remove_widgets(d) - self:emit_signal('device::removed_discovered') - end - end - for _, d in ipairs(plist.children) do - if d.device.object_path == object_path and (not d.device.Paired) then - plist:remove_widgets(d) - self:emit_signal('device::removed_connected') - end - end -end - ----Start scanning for devices -function bluetooth:scan() - self._private.Adapter1:StartDiscovery() -end - ----Stop scanning for devices -function bluetooth:stop_scan() - self._private.Adapter1:StopDiscovery() -end - ----Toggle bluetooth on or off -function bluetooth:toggle() - local powered = self._private.Adapter1.Powered - - self._private.Adapter1:Set('org.bluez.Adapter1', 'Powered', lgi.GLib.Variant('b', not powered)) - self._private.Adapter1.Powered = { - signature = 'b', - value = not powered, - } -end - ---- Open blueman-manager -function bluetooth:open_settings() - aspawn('blueman-manager') -end - ----Get a new device proxy and connect a PropertyChanged signal to it and ----add the device to the list ----@param object_path string the object path of the device -function bluetooth:get_device_info(object_path) - if (not object_path) or (not object_path:match('/org/bluez/hci0/dev')) then return end - - -- New Device1 proxy - local Device1 = dbus_proxy.Proxy:new { - bus = dbus_proxy.Bus.SYSTEM, - name = 'org.bluez', - interface = 'org.bluez.Device1', - path = object_path, - } - - -- New Properties proxy for the object_path - local Device1Properties = dbus_proxy.Proxy:new { - bus = dbus_proxy.Bus.SYSTEM, - name = 'org.bluez', - interface = 'org.freedesktop.DBus.Properties', - path = object_path, - } - - -- Just return if the Device1 has no name, this usually means random devices with just a mac address - if (not Device1.Name) or (Device1.Name == '') then return end - - -- For some reason it notifies twice or thrice - local just_notified = false - - local notify_timer = gtimer { - timeout = 3, - autostart = false, - single_shot = true, - callback = function() - just_notified = false - end, - } - - -- Connect the PropertyChanged signal to update the device when a property changes and send a notification - Device1Properties:connect_signal(function(_, _, changed_props) - if changed_props['Connected'] ~= nil then - if not just_notified then - naughty.notification { - app_icon = icondir .. 'bluetooth-on.svg', - app_name = 'Bluetooth', - title = Device1.Name, - icon = icondir .. Device1.Icon .. '.svg', - timeout = 5, - message = 'Device ' .. - Device1.Name .. ' is now ' .. (changed_props['Connected'] and 'connected' or 'disconnected'), - category = Device1.Connected and 'device.added' or 'device.removed', - } - just_notified = true - notify_timer:start() - end - end - capi.awesome.emit_signal(object_path .. '_updated', Device1) - end, 'PropertiesChanged') - - self:add_device(Device1, object_path) -end - ----Send a notification ----@param powered boolean the powered state of the adapter -local function send_state_notification(powered) - naughty.notification { - app_icon = icondir .. 'bluetooth-on.svg', - app_name = 'Bluetooth', - title = 'Bluetooth', - message = powered and 'Enabled' or 'Disabled', - icon = powered and icondir .. 'bluetooth-on.svg' or icondir .. 'bluetooth-off.svg', - category = powered and 'device.added' or 'device.removed', - } -end - -function bluetooth.new(args) - args = args or {} - - -- For some reason the first widget isn't read so the first container is a duplicate - local ret = base.make_widget_from_value { + local w = base.make_widget_from_value { { { { { { - { - resize = false, - image = gcolor.recolor_image(icondir .. 'menu-down.svg', - beautiful.colorscheme.bg_purple), - widget = wibox.widget.imagebox, - valign = 'center', - halign = 'center', - id = 'connected_icon', - }, - { - { - text = 'Paired Devices', - valign = 'center', - halign = 'center', - widget = wibox.widget.textbox, - }, - margins = dpi(5), - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.horizontal, - }, - bg = beautiful.colorscheme.bg1, - fg = beautiful.colorscheme.bg_purple, - shape = beautiful.shape[4], - widget = wibox.container.background, - id = 'connected_bg', - }, - id = 'connected_margin', - widget = wibox.container.margin, - }, - { - { - { - { - step = dpi(50), - spacing = dpi(10), - layout = require('src.lib.overflow_widget.overflow').vertical, - scrollbar_width = 0, - id = 'connected_device_list', - }, - id = 'margin', - margins = dpi(10), - widget = wibox.container.margin, - }, - border_color = beautiful.colorscheme.bg1, - border_width = dpi(2), - shape = beautiful.shape[4], - widget = wibox.container.background, - }, - widget = wibox.container.constraint, - strategy = 'exact', - height = 0, - id = 'connected_list', - }, - { - { - { - { - resize = false, - image = gcolor.recolor_image(icondir .. 'menu-down.svg', - beautiful.colorscheme.bg_blue), - widget = wibox.widget.imagebox, - valign = 'center', - halign = 'center', - id = 'discovered_icon', - }, - { - { - text = 'Nearby Devices', - valign = 'center', - halign = 'center', - widget = wibox.widget.textbox, - }, - margins = dpi(5), - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.horizontal, - }, - id = 'discovered_bg', - bg = beautiful.colorscheme.bg1, - fg = beautiful.colorscheme.bg_blue, - shape = beautiful.shape[4], - widget = wibox.container.background, - }, - id = 'discovered_margin', - top = dpi(10), - widget = wibox.container.margin, - }, - { - { - { - id = 'discovered_device_list', - spacing = dpi(10), - step = dpi(50), - layout = require('src.lib.overflow_widget.overflow').vertical, - scrollbar_width = 0, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - border_color = beautiful.colorscheme.border_color, - border_width = dpi(2), - shape = beautiful.shape[4], - widget = wibox.container.background, - forced_height = 0, - id = 'discovered_list', - }, - { - { -- action buttons - { - dnd_widget { - color = beautiful.colorscheme.bg_blue, - size = dpi(40), - }, - id = 'dnd', - widget = wibox.container.place, - valign = 'center', + widget = wibox.widget.imagebox, halign = 'center', + valign = 'center', + resize = true, + id = 'icon_role', + image = gcolor.recolor_image( + icondir .. device.Icon .. '.svg', beautiful.colorscheme.bg_blue), }, - nil, - { -- refresh - { - { - image = gcolor.recolor_image(icondir .. 'refresh.svg', - beautiful.colorscheme.bg), - resize = false, - valign = 'center', - halign = 'center', - widget = wibox.widget.imagebox, - }, - widget = wibox.container.margin, - margins = dpi(5), - }, - shape = beautiful.shape[4], - bg = beautiful.colorscheme.bg_blue, - id = 'scan', - widget = wibox.container.background, - }, - layout = wibox.layout.align.horizontal, + height = dpi(24), + width = dpi(24), + strategy = 'exact', + widget = wibox.container.constraint, }, - widget = wibox.container.margin, - top = dpi(10), + { + { + { + text = device.Alias or device.Name or path or '', + widget = wibox.widget.textbox, + }, + widget = wibox.container.constraint, + width = dpi(300), + strategy = 'exact', + }, + strategy = 'max', + height = dpi(40), + width = dpi(260), + widget = wibox.container.constraint, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, }, - layout = wibox.layout.fixed.vertical, + { -- Spacing + width = dpi(10), + widget = wibox.container.constraint, + }, + { + { + { + halign = 'center', + valign = 'center', + resize = false, + id = 'con_icon', + image = gcolor.recolor_image(icondir .. 'link-off.svg', fg), + widget = wibox.widget.imagebox, + }, + width = dpi(24), + height = dpi(24), + strategy = 'exact', + widget = wibox.container.constraint, + }, + margins = dpi(5), + widget = wibox.container.margin, + }, + layout = wibox.layout.align.horizontal, }, - margins = dpi(15), + margins = dpi(5), widget = wibox.container.margin, }, - margins = dpi(15), - 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, + object_path = path, } - --#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] - local connected_icon = ret:get_children_by_id('connected_icon')[1] + if device.Paired then + table.insert(paired_list.children, w) + else + table.insert(discovered_list.children, w) + end +end - local connected_animation = rubato.timed { - duration = 0.2, - pos = connected_list.height, - clamp_position = true, - subscribed = function(v) - connected_list.height = v - end, - } +return setmetatable(bluetooth, { + __call = function(self) - ret:connect_signal('device::added_connected', function(device) - if device.Connected then - local size = (#ret:get_paired_devices() * 60) - if size < 210 then - connected_animation.target = dpi(size) + local dnd = dnd_widget { + color = beautiful.colorscheme.bg_blue, + size = dpi(40), + } - connected_margin.connected_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + local w = base.make_widget_from_value { + { + { + { + { -- Paired header + { + { + { + widget = wibox.widget.imagebox, + resize = false, + id = 'paired_icon', + image = gcolor.recolor_image(icondir .. 'menu-down.svg', beautiful.colorscheme.bg_blue), + }, + widget = wibox.container.place, + }, + { + { + text = 'Paired Devices', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + id = 'paired_list_bar', + bg = beautiful.colorscheme.bg1, + fg = beautiful.colorscheme.bg_blue, + shape = beautiful.shape[4], + widget = wibox.container.background, + }, + { -- Paired list + { + { + { + id = 'paired_list', + scrollbar_width = 0, + spacing = dpi(10), + step = dpi(50), + 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 = 'paired_list_height', + strategy = 'exact', + height = 0, + widget = wibox.container.constraint, + }, + { -- Spacer + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(10), + }, + { -- discovered header + { + { + { + widget = wibox.widget.imagebox, + resize = false, + id = 'discovered_icon', + image = gcolor.recolor_image(icondir .. 'menu-down.svg', beautiful.colorscheme.bg_blue), + }, + widget = wibox.container.place, + }, + { + { + text = 'Discovered Devices', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + id = 'discovered_list_bar', + bg = beautiful.colorscheme.bg1, + fg = beautiful.colorscheme.bg_blue, + shape = beautiful.shape[4], + widget = wibox.container.background, + }, + { -- discovered list + { + { + { + id = 'discovered_list', + scrollbar_width = 0, + spacing = dpi(10), + step = dpi(50), + 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 = 'discovered_list_height', + strategy = 'exact', + height = 0, + widget = wibox.container.constraint, + }, + { -- widgets + { + { + dnd, + widget = wibox.container.place, + }, + nil, + { + { + { + image = gcolor.recolor_image(icondir .. 'refresh.svg', beautiful.colorscheme.bg_blue), + 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), + shape = beautiful.shape[4], + bg = beautiful.colorscheme.bg, + 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, true) + + local paired_list = w:get_children_by_id('paired_list')[1] + local discovered_list = w:get_children_by_id('discovered_list')[1] + + local paired_list_height = w:get_children_by_id('paired_list_height')[1] + local discovered_list_height = w:get_children_by_id('discovered_list_height')[1] + + local paired_list_bar = w:get_children_by_id('paired_list_bar')[1] + local discovered_list_bar = w:get_children_by_id('discovered_list_bar')[1] + + local paired_icon = w:get_children_by_id('paired_icon')[1] + local discovered_icon = w:get_children_by_id('discovered_icon')[1] + + local paired_list_anim = rubato.timed { + duration = 0.2, + pos = paired_list_height.height, + clamp_position = true, + rate = 24, + subscribed = function(v) + paired_list_height.height = v + end, + } + local discovered_list_anim = rubato.timed { + duration = 0.2, + pos = discovered_list_height.height, + clamp_position = true, + rate = 24, + subscribed = function(v) + discovered_list_height.height = v + end, + } + + paired_list_bar:buttons(gtable.join { + abutton({}, 1, function() + if paired_list_height.height == 0 then + local size = (paired_list.children and #paired_list.children or 0) * dpi(50) + if size > dpi(330) then + size = dpi(330) + end + paired_list_anim.target = dpi(size) + paired_list_bar.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + end + if #paired_list.children > 0 then + paired_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + beautiful.colorscheme.bg_blue)) + else + paired_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + beautiful.colorscheme.bg_blue)) + end + else + paired_list_anim.target = 0 + paired_list_bar.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4)) + end + paired_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + beautiful.colorscheme.bg_blue)) end + end), + }) - connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_purple)) - end - end - end) - - ret:connect_signal('device::removed_connected', function(device) - local size = (#ret:get_paired_devices() * 60) - if size < 210 then - connected_animation.target = dpi(size) - - connected_margin.connected_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - - connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_purple)) - end - end) - - connected_margin:connect_signal('button::press', function() - if connected_list.height == 0 then - local size = (#ret:get_paired_devices() * 60) - if size < 210 then - connected_animation.target = dpi(size) - - connected_margin.connected_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + discovered_list_bar:buttons(gtable.join { + abutton({}, 1, function() + if discovered_list_height.height == 0 then + local size = (discovered_list.children and #discovered_list.children or 0) * dpi(50) + if size > dpi(330) then + size = dpi(330) + end + discovered_list_anim.target = dpi(size) + discovered_list_bar.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + end + if #discovered_list.children > 0 then + discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + beautiful.colorscheme.bg_blue)) + else + discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + beautiful.colorscheme.bg_blue)) + end + else + discovered_list_anim.target = 0 + discovered_list_bar.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4)) + end + discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + beautiful.colorscheme.bg_blue)) end + end), + }) - connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_purple)) - end - else - connected_animation.target = 0 - connected_margin.connected_bg.shape = beautiful.shape[4] + local refresh_button = w:get_children_by_id('refresh_button')[1] + refresh_button:buttons(gtable.join { + abutton({}, 1, nil, function() + bt:StartDiscovery() + end), + }) - connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', - beautiful.colorscheme.bg_purple)) - end - end) + dnd:buttons(gtable.join { + abutton({}, 1, function() + bt:toggle_wifi() + end), + }) - local discovered_margin = ret:get_children_by_id('discovered_margin')[1] - local discovered_list = ret:get_children_by_id('discovered_list')[1] - local discovered_bg = ret:get_children_by_id('discovered_bg')[1] - local discovered_icon = ret:get_children_by_id('discovered_icon')[1] - - local discovered_animation = rubato.timed { - duration = 0.2, - pos = discovered_list.forced_height, - easing = rubato.linear, - subscribed = function(v) - discovered_list.forced_height = v - end, - } - - ret:connect_signal('device::added_discovered', function(device) - if not device.Connected then - local size = (#ret:get_discovered_devices() * 60) - if size > 210 then - size = 210 - end - if size > 0 then - discovered_animation.target = dpi(size) - discovered_margin.discovered_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_blue)) - end - end - end) - - ret:connect_signal('device::removed_discovered', function(device) - local size = (#ret:get_discovered_devices() * 60) - if size > 210 then - size = 210 - end - if size > 0 then - discovered_animation.target = dpi(size) - discovered_margin.discovered_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_blue)) - end - end) - - discovered_margin:connect_signal('button::press', function() - if discovered_list.forced_height == 0 then - local size = (#ret:get_discovered_devices() * 60) - if size > 210 then - size = 210 - end - if size > 0 then - discovered_animation.target = dpi(size) - discovered_margin.discovered_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', - beautiful.colorscheme.bg_blue)) - end - else - discovered_animation.target = 0 - discovered_bg.shape = beautiful.shape[4] - discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', - beautiful.colorscheme.bg_blue)) - end - 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() - ret:scan() - end), - } - - hover.bg_hover { widget = ret:get_children_by_id('scan')[1] } - 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 + if bt.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 + bt:connect_signal('Bluetooth::Powered', function(_, powered) + if powered then + dnd:set_enabled() + else + dnd:set_disabled() + end + print(powered) + end) - return ret -end + bt:connect_signal('Bluetooth::DeviceAdded', function(_, path) + self:add_device_to_list(path) + end) -function bluetooth.mt:__call(...) - return bluetooth.new(...) -end + bt:connect_signal('Bluetooth::DeviceRemoved', function(_, path) + self:remove_device_from_list(path) + end) -return setmetatable(bluetooth, bluetooth.mt) + return self + end, +}) diff --git a/awesome/src/modules/brightness/brightness_osd.lua b/awesome/src/modules/brightness/brightness_osd.lua deleted file mode 100644 index 5afcbf2..0000000 --- a/awesome/src/modules/brightness/brightness_osd.lua +++ /dev/null @@ -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) diff --git a/awesome/src/modules/brightness/init.lua b/awesome/src/modules/brightness/init.lua new file mode 100644 index 0000000..9ddf7f0 --- /dev/null +++ b/awesome/src/modules/brightness/init.lua @@ -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 diff --git a/awesome/src/modules/crylia_bar/dock.lua b/awesome/src/modules/crylia_bar/dock.lua index 080283b..d577e43 100644 --- a/awesome/src/modules/crylia_bar/dock.lua +++ b/awesome/src/modules/crylia_bar/dock.lua @@ -101,7 +101,9 @@ function dock:get_element_widget(desktop_file) if not desktop_file then return end 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 icon_lookup:get_gicon_path(nil, Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'X-AppImage-Old-Icon')) or '' diff --git a/awesome/src/modules/init.lua b/awesome/src/modules/init.lua index 7207116..4c7ec83 100644 --- a/awesome/src/modules/init.lua +++ b/awesome/src/modules/init.lua @@ -30,6 +30,8 @@ if not instance then end) require('src.modules.app_launcher')() require('src.modules.powermenu')() + require('src.modules.brightness')() + require('src.modules.audio')() end, }) end diff --git a/awesome/src/modules/inputbox/init.lua b/awesome/src/modules/inputbox/init.lua index f1c0a58..12b5e18 100644 --- a/awesome/src/modules/inputbox/init.lua +++ b/awesome/src/modules/inputbox/init.lua @@ -454,9 +454,9 @@ end local button_signal = function(self, x, y, button) if button == 1 then - self:set_cursor_pos_from_mouse(x, y) - self:start_mousegrabber(x, y) - self:start_keygrabber() + --self:set_cursor_pos_from_mouse(x, y) + --self:start_mousegrabber(x, y) + --self:start_keygrabber() end end diff --git a/awesome/src/modules/network/init.lua b/awesome/src/modules/network/init.lua index 03593cd..93f8455 100644 --- a/awesome/src/modules/network/init.lua +++ b/awesome/src/modules/network/init.lua @@ -380,7 +380,7 @@ function network:add_ap_to_list(ap) halign = 'center', widget = wibox.widget.imagebox, }, - strategy = 'max', + strategy = 'exact', height = dpi(24), width = dpi(24), widget = wibox.container.constraint, diff --git a/awesome/src/modules/notification-center/widgets/status_bars.lua b/awesome/src/modules/notification-center/widgets/status_bars.lua index a860087..c8038b0 100644 --- a/awesome/src/modules/notification-center/widgets/status_bars.lua +++ b/awesome/src/modules/notification-center/widgets/status_bars.lua @@ -15,7 +15,7 @@ local rubato = require('src.lib.rubato') -- Own Libs 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 cpu_usage = require('src.tools.helpers.cpu_usage') 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 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 - ---@param widget_table table - ---@return table - local function create_bar_layout(widget_table) - local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) } +return setmetatable({}, { + __call = function() + ---Creates a layout with bar widgets based on the given table + ---@param widget_table table + ---@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 - local w = base.make_widget_from_value { - { + for _, widget in pairs(widget_table) do + local w = base.make_widget_from_value { { { - { --Bar - color = beautiful.colorscheme.bg_teal, - background_color = beautiful.colorscheme.bg1, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = 'progress_role', - widget = wibox.widget.progressbar, + { + { --Bar + color = beautiful.colorscheme.bg_teal, + background_color = beautiful.colorscheme.bg1, + max_value = 100, + value = 0, + forced_height = dpi(8), + shape = function(cr) + gears.shape.rounded_bar(cr, dpi(58), dpi(8)) + end, + 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', valign = 'center', - widget = wibox.container.place, + widget = wibox.widget.imagebox, }, - direction = 'east', - widget = wibox.container.rotate, + height = dpi(24), + width = dpi(24), + widget = wibox.container.constraint, }, - 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', - valign = 'center', - widget = wibox.widget.imagebox, - }, - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint, - }, - spacing = dpi(10), - layout = wibox.layout.fixed.vertical, - } + 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 { - duration = 1, - pos = bar.value, - easing = rubato.linear, - subscribed = function(v) - bar.value = v - end, - } + local rubato_timer = rubato.timed { + duration = 1, + pos = bar.value, + easing = rubato.linear, + subscribed = function(v) + bar.value = v + end, + } - local tooltip = awful.tooltip { - objects = { w }, - mode = 'inside', - preferred_alignments = 'middle', - margins = dpi(10), - } + local tooltip = awful.tooltip { + objects = { w }, + mode = 'inside', + preferred_alignments = 'middle', + margins = dpi(10), + } - if widget == 'cpu_usage' then - cpu_usage:connect_signal('update::cpu_usage', function(_, v) - if not v then return nil end - tooltip.text = 'CPU Usage: ' .. v .. '%' - rubato_timer.target = v - w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg', - beautiful.colorscheme.bg_teal) - end) - elseif widget == 'cpu_temp' then - cpu_temp:connect_signal('update::cpu_temp', function(_, v) - if not v then return nil end - local temp_icon - 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 + if widget == 'cpu_usage' then + cpu_usage:connect_signal('update::cpu_usage', function(_, v) + if not v then return nil end + tooltip.text = 'CPU Usage: ' .. v .. '%' + rubato_timer.target = v + w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icondir .. 'cpu/cpu.svg', + beautiful.colorscheme.bg_teal) + end) + elseif widget == 'cpu_temp' then + cpu_temp:connect_signal('update::cpu_temp', function(_, v) + if not v then return nil end + local temp_icon + if v < 50 then 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' - elseif temp_num >= 80 then + elseif v >= 80 then temp_icon = icondir .. 'cpu/thermometer-high.svg' end - else - temp_num = 'NaN' - temp_icon = icondir .. 'cpu/thermometer-low.svg' - end - w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon, - beautiful.colorscheme.bg_green) - tooltip.text = 'GPU Temp: ' .. temp_num .. '°C' - rubato_timer.target = temp_num - end) - elseif widget == 'volume' then - audio:connect_signal('sink::get', function(_, muted, volume) - if not volume and muted then return nil end - local icon = icondir .. 'audio/volume' - volume = tonumber(volume) - if not volume then - return - end - if muted then - icon = icon .. '-mute' - else - 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' + 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 = 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' + 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 - w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', - beautiful.colorscheme.bg_yellow) - tooltip.text = 'Volume: ' .. volume .. '%' - rubato_timer.target = volume - end) - elseif widget == 'microphone' then - audio:connect_signal('source::get', function(_, muted, volume) - if not volume and muted then return nil end - if not volume then - return - end - local icon = icondir .. 'audio/microphone' - volume = tonumber(volume) - if not volume then - return - end - if muted or (volume < 1) then - icon = icon .. '-off' - end - w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', - beautiful.colorscheme.bg_blue) - tooltip.text = 'Microphone: ' .. volume .. '%' - rubato_timer.target = volume - end) - elseif widget == 'backlight' then - backlight:connect_signal('brightness::get', function(_, v) - if not v then return nil end - local icon = icondir .. 'brightness' - if v >= 0 and v < 34 then - icon = icon .. '-low' - elseif v >= 34 and v < 67 then - icon = icon .. '-medium' - elseif v >= 67 then - icon = icon .. '-high' - end - w:get_children_by_id('image_role')[1]:set_image(gears.color.recolor_image(icon .. '.svg', - beautiful.colorscheme.bg_purple)) - tooltip.text = 'Backlight: ' .. v .. '%' - rubato_timer.target = v - end) - elseif widget == 'battery' then - --[[ battery: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) ]] + w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon, + beautiful.colorscheme.bg_green) + tooltip.text = 'GPU Temp: ' .. temp_num .. '°C' + rubato_timer.target = temp_num + end) + elseif widget == 'volume' then + audio:connect_signal('sink::get', function(_, muted, volume) + if not volume and muted then return nil end + local icon = icondir .. 'audio/volume' + volume = tonumber(volume) + if not volume then + return + end + if muted then + icon = icon .. '-mute' + else + 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 + w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', + beautiful.colorscheme.bg_yellow) + tooltip.text = 'Volume: ' .. volume .. '%' + rubato_timer.target = volume + end) + elseif widget == 'microphone' then + audio:connect_signal('source::get', function(_, muted, volume) + if not volume and muted then return nil end + if not volume then + return + end + local icon = icondir .. 'audio/microphone' + volume = tonumber(volume) + if not volume then + return + end + if muted or (volume < 1) then + icon = icon .. '-off' + end + w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(icon .. '.svg', + beautiful.colorscheme.bg_blue) + 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 - table.insert(bar_layout, w) + return bar_layout end - return bar_layout - end - - return wibox.widget { - { + return wibox.widget { { { { { - create_bar_layout(beautiful.user_config.status_bar_widgets), - width = dpi(480), - strategy = 'exact', - widget = wibox.container.constraint, + { + create_bar_layout(beautiful.user_config.status_bar_widgets), + width = dpi(480), + strategy = 'exact', + widget = wibox.container.constraint, + }, + widget = wibox.container.place, }, - widget = wibox.container.place, + magins = dpi(10), + layout = wibox.container.margin, }, - magins = dpi(10), - layout = wibox.container.margin, + border_color = beautiful.colorscheme.border_color, + border_width = dpi(2), + shape = beautiful.shape[12], + widget = wibox.container.background, }, - border_color = beautiful.colorscheme.border_color, - border_width = dpi(2), - shape = beautiful.shape[12], - widget = wibox.container.background, + widget = wibox.container.constraint, + height = dpi(120), + width = dpi(500), + strategy = 'exact', }, - widget = wibox.container.constraint, - height = dpi(120), - width = dpi(500), - strategy = 'exact', - }, - top = dpi(10), - left = dpi(20), - right = dpi(20), - bottom = dpi(10), - widget = wibox.container.margin, - } - -end, }) + top = dpi(10), + left = dpi(20), + right = dpi(20), + bottom = dpi(10), + widget = wibox.container.margin, + } + end, +}) diff --git a/awesome/src/modules/osd/init.lua b/awesome/src/modules/osd/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/awesome/src/modules/powermenu/init.lua b/awesome/src/modules/powermenu/init.lua index ef91cbc..d0a42b4 100644 --- a/awesome/src/modules/powermenu/init.lua +++ b/awesome/src/modules/powermenu/init.lua @@ -10,6 +10,7 @@ local dpi = require('beautiful').xresources.apply_dpi local gfilesystem = require('gears.filesystem') local gtable = require('gears.table') local wibox = require('wibox') +local gsurface = require('gears.surface') local hover = require('src.tools.hover') @@ -116,7 +117,7 @@ if instance == nil then { { { - image = icondir .. 'defaultpfp.svg', + image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png'), resize = true, clip_shape = beautiful.shape[30], valign = 'center', @@ -192,13 +193,14 @@ if instance == nil then -- 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) + --[[ 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 = stdout:gsub('\n', '') + 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) + 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', '') diff --git a/awesome/src/scripts/pfp.sh b/awesome/src/scripts/pfp.sh index 29c9066..c8cb007 100755 --- a/awesome/src/scripts/pfp.sh +++ b/awesome/src/scripts/pfp.sh @@ -5,7 +5,7 @@ case $1 in "userPfp") iconPath="/var/lib/AccountsService/icons/$USER" - userIconPath="$HOME/.config/awesome/src/assets/userpfp/" + userIconPath="../assets/userpfp/" if [[ -f "$userIconPath" ]]; then diff --git a/awesome/src/scripts/user_data.sh b/awesome/src/scripts/user_data.sh new file mode 100644 index 0000000..f8bd27e --- /dev/null +++ b/awesome/src/scripts/user_data.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# First update the profile picture + diff --git a/awesome/src/tools/bluetooth/adapter.lua b/awesome/src/tools/bluetooth/adapter.lua new file mode 100644 index 0000000..c8017c9 --- /dev/null +++ b/awesome/src/tools/bluetooth/adapter.lua @@ -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, +}) diff --git a/awesome/src/tools/bluetooth/device.lua b/awesome/src/tools/bluetooth/device.lua new file mode 100644 index 0000000..13d0cea --- /dev/null +++ b/awesome/src/tools/bluetooth/device.lua @@ -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, +}) diff --git a/awesome/src/tools/gio_icon_lookup.lua b/awesome/src/tools/gio_icon_lookup.lua index 5dbb61f..372a3ed 100644 --- a/awesome/src/tools/gio_icon_lookup.lua +++ b/awesome/src/tools/gio_icon_lookup.lua @@ -7,23 +7,31 @@ local Gtk = lgi.require('Gtk', '3.0') local icon_lookup = {} 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 - 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 - local icon_info = self.gtk_theme:lookup_by_gicon(app, 64, 0) - if icon_info then - return icon_info:get_filename() - end return nil end local instance = nil if not instance then instance = setmetatable(icon_lookup, { - __call = function(self, ...) + __call = function(self, theme_name,...) self.gtk_theme = Gtk.IconTheme.get_default() + return self end, }) diff --git a/awesome/src/tools/helpers/audio.lua b/awesome/src/tools/helpers/audio.lua index b02bae1..da6a43f 100644 --- a/awesome/src/tools/helpers/audio.lua +++ b/awesome/src/tools/helpers/audio.lua @@ -6,43 +6,108 @@ local audio = {} local instance = nil -function audio.set_sink_volume(volume) - aspawn('pactl set-sink-volume @DEFAULT_SINK@ ' .. volume .. '%') +function audio:set_sink_volume(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 -function audio.set_source_volume(volume) - aspawn('pactl set-source-volume @DEFAULT_SOURCE@ ' .. volume .. '%') +function audio:set_source_volume(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 -function audio.sink_volume_up() - aspawn('pactl set-sink-volume @DEFAULT_SINK@ +2%') +function audio:sink_volume_up() + 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 -function audio.source_volume_up() - aspawn('pactl set-source-volume @DEFAULT_SOURCE@ +2%') +function audio:source_volume_up() + 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 -function audio.sink_volume_down() - aspawn('pactl set-sink-volume @DEFAULT_SINK@ -2%') +function audio:sink_volume_down() + 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 -function audio.source_volume_down() - aspawn('pactl set-source-volume @DEFAULT_SOURCE@ -2%') +function audio:source_volume_down() + 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 -function audio.sink_toggle_mute() - aspawn('pactl set-sink-mute @DEFAULT_SINK@ toggle') +function audio:sink_toggle_mute() + 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 -function audio.source_toggle_mute() - aspawn('pactl set-source-mute @DEFAULT_SOURCE@ toggle') +function audio:source_toggle_mute() + 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 local function new() - local self = gobject {} gtable.crush(self, audio, true) + self.allow_cmd = true + aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], { stdout = function(line) -- Volume changed diff --git a/awesome/src/tools/helpers/backlight.lua b/awesome/src/tools/helpers/backlight.lua index efa0144..0be2219 100644 --- a/awesome/src/tools/helpers/backlight.lua +++ b/awesome/src/tools/helpers/backlight.lua @@ -1,6 +1,7 @@ local aspawn = require('awful.spawn') local gobject = require('gears.object') local gtable = require('gears.table') +local gtimer = require('gears.timer') local backlight = {} @@ -8,17 +9,25 @@ local instance = nil function backlight.brightness_get_async(callback) aspawn.easy_async_with_shell('brightnessctl get', function(stdout) - callback(tonumber(stdout:gsub('\n', ''))) + callback(stdout:gsub('\n', '')) end) end 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') end 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') end @@ -32,6 +41,11 @@ local function new() self.max_brightness = tonumber(stdout:gsub('\n', '') or 1) 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 end diff --git a/awesome/src/tools/helpers/gpu_usage.lua b/awesome/src/tools/helpers/gpu_usage.lua index b9718cc..8d049d2 100644 --- a/awesome/src/tools/helpers/gpu_usage.lua +++ b/awesome/src/tools/helpers/gpu_usage.lua @@ -1,15 +1,38 @@ local awatch = require('awful.widget.watch') +local aspawn = require('awful.spawn') local gobject = require('gears.object') local instance +local json = require('src.lib.json-lua.json-lua') + local function new() local self = gobject {} - awatch([[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], 3, function(_, stdout) - stdout = stdout:match('%d+') - if not stdout then return end - self:emit_signal('update::gpu_usage', stdout) + aspawn.easy_async_with_shell([[ lspci | grep ' VGA ' | cut -d" " -f 1 ]], function(stdout) + if stdout:match('00:03.0') then -- Nvidia + awatch([[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], 3, function(_, 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) + return self end diff --git a/awesome/src/tools/hover.lua b/awesome/src/tools/hover.lua index 6327bbb..7a08571 100644 --- a/awesome/src/tools/hover.lua +++ b/awesome/src/tools/hover.lua @@ -30,7 +30,7 @@ local function overlay_color(col, overlay, opacity) end local function bg_hover(args) - --[[ args = args or {} +--[[ args = args or {} local old_cursor, old_wibox local _, r, g, b, a = args.widget.bg:get_rgba() diff --git a/awesome/src/tools/icon_preloader.lua b/awesome/src/tools/icon_preloader.lua new file mode 100644 index 0000000..7d855b1 --- /dev/null +++ b/awesome/src/tools/icon_preloader.lua @@ -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 diff --git a/awesome_crylia.desktop b/awesome_crylia.desktop new file mode 100644 index 0000000..c704bd2 --- /dev/null +++ b/awesome_crylia.desktop @@ -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 + diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..e783d8d --- /dev/null +++ b/install.sh @@ -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