From f399235db0f67378d65bd8bb8ec12604a123c541 Mon Sep 17 00:00:00 2001 From: Rene Kievits Date: Sun, 19 Mar 2023 19:22:02 +0100 Subject: [PATCH] yes, I'm very commit lazy --- awesome/awful/widget/inputbox.lua | 171 ++- awesome/awful/widget/toggle_widget.lua | 46 +- awesome/rc.lua | 74 +- awesome/src/assets/CT.svg | 1 + awesome/src/assets/icons/ArchLogo.png | Bin 20595 -> 0 bytes .../src/assets/icons/notifications/close.svg | 4 + .../src/assets/icons/setup/titlebar_left.png | Bin 0 -> 39014 bytes .../src/assets/icons/setup/titlebar_top.png | Bin 0 -> 38475 bytes awesome/src/assets/icons/start.png | Bin 0 -> 98986 bytes awesome/src/assets/userpfp/crylia.png | Bin 316886 -> 0 bytes awesome/src/assets/userpfp/userpfp.png | Bin 0 -> 312349 bytes awesome/src/bindings/bind_to_tags.lua | 80 +- awesome/src/bindings/client_buttons.lua | 27 +- awesome/src/bindings/client_keys.lua | 207 +++- awesome/src/bindings/global_buttons.lua | 11 +- awesome/src/bindings/global_keys.lua | 398 +++--- awesome/src/core/error_handling.lua | 23 +- awesome/src/core/notifications.lua | 778 +++++++----- awesome/src/core/rules.lua | 118 +- awesome/src/core/setup.lua | 1075 +++++++++------- awesome/src/core/signals.lua | 244 +--- awesome/src/core/titlebar.lua | 627 ++++++++++ awesome/src/lib/dbus_proxy | 1 + awesome/src/lib/nice | 1 - awesome/src/modules/__test.lua | 60 - .../application_launcher/application.lua | 279 ++--- .../src/modules/application_launcher/init.lua | 115 +- .../src/modules/audio/audio_controller.lua | 575 +++++++++ .../src/modules/audio/volume_controller.lua | 553 --------- awesome/src/modules/audio/volume_osd.lua | 215 ++-- awesome/src/modules/bluetooth/device.lua | 235 ++-- awesome/src/modules/bluetooth/init.lua | 462 ++++--- .../src/modules/brightness/brightness_osd.lua | 170 ++- awesome/src/modules/calendar/calendar.lua | 1089 ----------------- awesome/src/modules/calendar/init.lua | 383 +++--- awesome/src/modules/calendar/task_info.lua | 216 ++-- awesome/src/modules/context_menu/init.lua | 117 +- awesome/src/modules/crylia_bar/center_bar.lua | 30 +- awesome/src/modules/crylia_bar/dock.lua | 994 ++++++++------- awesome/src/modules/crylia_bar/init.lua | 80 +- awesome/src/modules/crylia_bar/left_bar.lua | 33 +- awesome/src/modules/crylia_bar/right_bar.lua | 19 +- awesome/src/modules/crylia_wibox/init.lua | 92 +- awesome/src/modules/desktop/context_menu.lua | 52 - awesome/src/modules/desktop/desktop.lua | 457 +++---- awesome/src/modules/desktop/element.lua | 232 +++- awesome/src/modules/init.lua | 52 +- awesome/src/modules/inputbox/init.lua | 796 ++++++++++++ awesome/src/modules/inputbox/new.lua | 485 ++++++++ .../network_controller/access_point.lua | 236 ++-- .../modules/network_controller/ap_form.lua | 140 +-- .../src/modules/network_controller/init.lua | 285 +++-- .../src/modules/notification-center/init.lua | 471 +++---- .../notification-center/notification_list.lua | 268 ---- .../modules/notification-center/profile.lua | 208 ---- .../modules/notification-center/song_info.lua | 501 -------- .../spacingline_widget.lua | 22 - .../notification-center/status_bars.lua | 840 ------------- .../modules/notification-center/time_date.lua | 65 - .../modules/notification-center/weather.lua | 224 ---- .../widgets/notification_list.lua | 71 ++ .../notification-center/widgets/profile.lua | 174 +++ .../notification-center/widgets/song_info.lua | 241 ++++ .../widgets/status_bars.lua | 266 ++++ .../notification-center/widgets/weather.lua | 203 +++ awesome/src/modules/powermenu/init.lua | 214 ++++ awesome/src/modules/powermenu/powermenu.lua | 249 ---- .../window_switcher/window_elements.lua | 85 +- awesome/src/scripts/mic.sh | 27 - awesome/src/scripts/pfp.sh | 4 +- awesome/src/scripts/vol.sh | 16 - awesome/src/theme/colors.lua | 359 +++--- awesome/src/theme/init.lua | 30 +- awesome/src/theme/theme_config.lua | 847 +++++++------ awesome/src/theme/user_config.lua | 189 ++- awesome/src/tools/auto_starter.lua | 15 +- awesome/src/tools/config.lua | 87 ++ awesome/src/tools/gio_icon_lookup.lua | 85 +- awesome/src/tools/helpers/audio.lua | 151 ++- awesome/src/tools/helpers/backlight.lua | 76 +- awesome/src/tools/helpers/cpu_freq.lua | 38 +- awesome/src/tools/helpers/cpu_temp.lua | 53 +- awesome/src/tools/helpers/cpu_usage.lua | 59 +- awesome/src/tools/helpers/gpu_temp.lua | 30 +- awesome/src/tools/helpers/gpu_usage.lua | 29 +- awesome/src/tools/helpers/kb_helper.lua | 48 + awesome/src/tools/helpers/playerctl.lua | 516 +++----- awesome/src/tools/helpers/pulseaudio.lua | 35 + awesome/src/tools/helpers/ram.lua | 29 +- awesome/src/tools/hover.lua | 319 +++++ awesome/src/widgets/audio.lua | 148 ++- awesome/src/widgets/battery.lua | 103 +- awesome/src/widgets/bluetooth.lua | 52 +- awesome/src/widgets/clock.lua | 67 +- awesome/src/widgets/cpu_info.lua | 351 +++--- awesome/src/widgets/date.lua | 102 +- awesome/src/widgets/gpu_info.lua | 270 ++-- awesome/src/widgets/kblayout.lua | 613 ++++------ awesome/src/widgets/layout_list.lua | 58 +- awesome/src/widgets/network.lua | 92 +- awesome/src/widgets/power.lua | 68 +- awesome/src/widgets/ram_info.lua | 70 +- awesome/src/widgets/systray.lua | 35 +- awesome/src/widgets/taglist.lua | 283 ++--- awesome/src/widgets/tasklist.lua | 224 ++-- awesome/todo.md | 5 + awesome/wibox/layout/fixed.lua | 3 +- 107 files changed, 11120 insertions(+), 10906 deletions(-) create mode 100644 awesome/src/assets/CT.svg delete mode 100644 awesome/src/assets/icons/ArchLogo.png create mode 100644 awesome/src/assets/icons/notifications/close.svg create mode 100644 awesome/src/assets/icons/setup/titlebar_left.png create mode 100644 awesome/src/assets/icons/setup/titlebar_top.png create mode 100644 awesome/src/assets/icons/start.png delete mode 100644 awesome/src/assets/userpfp/crylia.png create mode 100644 awesome/src/assets/userpfp/userpfp.png create mode 100644 awesome/src/core/titlebar.lua create mode 160000 awesome/src/lib/dbus_proxy delete mode 160000 awesome/src/lib/nice delete mode 100644 awesome/src/modules/__test.lua create mode 100644 awesome/src/modules/audio/audio_controller.lua delete mode 100644 awesome/src/modules/audio/volume_controller.lua delete mode 100644 awesome/src/modules/calendar/calendar.lua delete mode 100644 awesome/src/modules/desktop/context_menu.lua create mode 100644 awesome/src/modules/inputbox/init.lua create mode 100644 awesome/src/modules/inputbox/new.lua delete mode 100644 awesome/src/modules/notification-center/notification_list.lua delete mode 100644 awesome/src/modules/notification-center/profile.lua delete mode 100644 awesome/src/modules/notification-center/song_info.lua delete mode 100644 awesome/src/modules/notification-center/spacingline_widget.lua delete mode 100644 awesome/src/modules/notification-center/status_bars.lua delete mode 100644 awesome/src/modules/notification-center/time_date.lua delete mode 100644 awesome/src/modules/notification-center/weather.lua create mode 100644 awesome/src/modules/notification-center/widgets/notification_list.lua create mode 100644 awesome/src/modules/notification-center/widgets/profile.lua create mode 100644 awesome/src/modules/notification-center/widgets/song_info.lua create mode 100644 awesome/src/modules/notification-center/widgets/status_bars.lua create mode 100644 awesome/src/modules/notification-center/widgets/weather.lua create mode 100644 awesome/src/modules/powermenu/init.lua delete mode 100644 awesome/src/modules/powermenu/powermenu.lua delete mode 100755 awesome/src/scripts/mic.sh delete mode 100755 awesome/src/scripts/vol.sh create mode 100644 awesome/src/tools/config.lua create mode 100644 awesome/src/tools/helpers/kb_helper.lua create mode 100644 awesome/src/tools/helpers/pulseaudio.lua create mode 100644 awesome/src/tools/hover.lua diff --git a/awesome/awful/widget/inputbox.lua b/awesome/awful/widget/inputbox.lua index 103e59d..2e06fa0 100644 --- a/awesome/awful/widget/inputbox.lua +++ b/awesome/awful/widget/inputbox.lua @@ -8,13 +8,13 @@ --------------------------------------------------------------------------- local setmetatable = setmetatable -local beautiful = require("beautiful") -local gtable = require("gears.table") -local base = require("wibox.widget.base") -local gstring = require("gears.string") -local akeygrabber = require("awful.keygrabber") -local akey = require("awful.key") -local textbox = require("wibox.widget.textbox") +local beautiful = require('beautiful') +local gtable = require('gears.table') +local base = require('wibox.widget.base') +local gstring = require('gears.string') +local akeygrabber = require('awful.keygrabber') +local akey = require('awful.key') +local textbox = require('wibox.widget.textbox') local capi = { selection = selection, @@ -28,15 +28,15 @@ local inputbox = { mt = {} } local function text_with_cursor(text, cursor_pos, self) local char, spacer, text_start, text_end - local cursor_fg = beautiful.inputbox_cursor_fg or "#313131" - local cursor_bg = beautiful.inputbox_cursor_bg or "#0dccfc" - local placeholder_text = self.hint_text or "" - local placeholder_fg = beautiful.inputbox_placeholder_fg or "#777777" - local highlight_bg = beautiful.inputbox_highlight_bg or "#35ffe4" - local highlight_fg = beautiful.inputbox_highlight_fg or "#000000" + local cursor_fg = beautiful.inputbox_cursor_fg or '#313131' + local cursor_bg = beautiful.inputbox_cursor_bg or '#0dccfc' + local placeholder_text = self.hint_text or '' + local placeholder_fg = beautiful.inputbox_placeholder_fg or '#777777' + local highlight_bg = beautiful.inputbox_highlight_bg or '#35ffe4' + local highlight_fg = beautiful.inputbox_highlight_fg or '#000000' - if text == "" then - return "" .. placeholder_text .. "" + if text == '' then + return "" .. placeholder_text .. '' end local offset = 0 @@ -45,13 +45,13 @@ local function text_with_cursor(text, cursor_pos, self) end if #text < cursor_pos then - char = " " - spacer = "" + char = ' ' + spacer = '' text_start = gstring.xml_escape(text) - text_end = "" + text_end = '' else char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset)) - spacer = " " + spacer = ' ' text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1)) text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1)) end @@ -65,10 +65,10 @@ local function text_with_cursor(text, cursor_pos, self) return text_start_highlight .. "" .. - text_highlighted .. "" .. text_end_highlight + text_highlighted .. '' .. text_end_highlight else return text_start .. "" .. - char .. "" .. text_end .. spacer + char .. '' .. text_end .. spacer end end @@ -90,23 +90,23 @@ inputbox.set_widget = base.set_widget_common --- Clears the current text function inputbox:clear() - self:set_text("") + self:set_text('') end function inputbox:get_text() - return self._private.text or "" + return self._private.text or '' end function inputbox:set_text(text) self._private.text = text self.markup = text_with_cursor(self:get_text(), #self:get_text(), self) - self:emit_signal("property::text", text) + self:emit_signal('property::text', text) end --- Stop the keygrabber and mousegrabber function inputbox:stop() if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end - self:emit_signal("stopped") + self:emit_signal('stopped') self.akeygrabber.stop() end @@ -116,16 +116,16 @@ function inputbox:focus() self:run() end - self:connect_signal("button::press", function() + self:connect_signal('button::press', function() if capi.mouse.current_widget ~= self then - self:emit_signal("keygrabber::stop", "") + self:emit_signal('keygrabber::stop', '') end end) end --- Init the inputbox and start the keygrabber function inputbox:run() - if not self._private.text then self._private.text = "" end + if not self._private.text then self._private.text = '' end -- Init the cursor position, but causes on refocus the cursor to move to the left local cursor_pos = #self:get_text() + 1 @@ -136,24 +136,22 @@ function inputbox:run() self.akeygrabber = akeygrabber { autostart = true, start_callback = function() - self:emit_signal("started") + self:emit_signal('started') end, stop_callback = function(_, stop_key) - if stop_key == "Return" then - self:emit_signal("submit", self:get_text(), stop_key) - -- Only reset text on enter as on escape you might want to continue later - self:set_text("") + if stop_key == 'Return' then + self:emit_signal('submit', self:get_text(), stop_key) else - self:emit_signal("stopped", stop_key) + self:emit_signal('stopped', stop_key) end end, - stop_key = { "Escape", "Return" }, + stop_key = { 'Escape', 'Return' }, keybindings = { --lShift, rShift = #50, #62 --lControl, rControl = #37, #105 akey { - modifiers = { "Shift" }, - key = "Left", -- left + modifiers = { 'Shift' }, + key = 'Left', -- left on_press = function() if cursor_pos > 1 then local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0 @@ -178,12 +176,12 @@ function inputbox:run() cursor_pos = #self._private.text + 1 end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Shift", "Left") - end + self:emit_signal('inputbox::key_pressed', 'Shift', 'Left') + end, }, akey { - modifiers = { "Shift" }, - key = "Right", -- right + modifiers = { 'Shift' }, + key = 'Right', -- right on_press = function() if #self._private.text >= cursor_pos then if not self._private.highlight.cur_pos_end then @@ -209,29 +207,29 @@ function inputbox:run() cursor_pos = #self._private.text + 1 end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Shift", "Right") - end + self:emit_signal('inputbox::key_pressed', 'Shift', 'Right') + end, }, akey { - modifiers = { "Control" }, - key = "a", -- a + modifiers = { 'Control' }, + key = 'a', -- a on_press = function() -- Mark the entire text self._private.highlight = { cur_pos_start = 1, - cur_pos_end = #self._private.text + cur_pos_end = #self._private.text, } self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Control", "a") - end + self:emit_signal('inputbox::key_pressed', 'Control', 'a') + end, }, akey { - modifiers = { "Control" }, - key = "v", -- v + modifiers = { 'Control' }, + key = 'v', -- v on_press = function() local sel = capi.selection() if sel then - sel = sel:gsub("\n", "") + sel = sel:gsub('\n', '') if self._private.highlight and self._private.highlight.cur_pos_start and self._private.highlight.cur_pos_end then -- insert the text into the selected part @@ -248,35 +246,35 @@ function inputbox:run() end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Control", "v") - end + self:emit_signal('inputbox::key_pressed', 'Control', 'v') + end, }, akey { - modifiers = { "Control" }, - key = "c", -- c + modifiers = { 'Control' }, + key = 'c', -- c on_press = function() --TODO - end + end, }, akey { - modifiers = { "Control" }, - key = "x", -- x + modifiers = { 'Control' }, + key = 'x', -- x on_press = function() --TODO - end + end, }, akey { - modifiers = { "Control" }, - key = "Left", -- left + modifiers = { 'Control' }, + key = 'Left', -- left on_press = function() -- Find all spaces local spaces = {} local t, i = self._private.text, 0 - while t:find("%s") do - i = t:find("%s") + while t:find('%s') do + i = t:find('%s') table.insert(spaces, i) - t = t:sub(1, i - 1) .. "-" .. t:sub(i + 1) + t = t:sub(1, i - 1) .. '-' .. t:sub(i + 1) end local cp = 1 @@ -292,14 +290,14 @@ function inputbox:run() cursor_pos = #self._private.text + 1 end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Control", "Left") - end + self:emit_signal('inputbox::key_pressed', 'Control', 'Left') + end, }, akey { - modifiers = { "Control" }, - key = "Right", -- right + modifiers = { 'Control' }, + key = 'Right', -- right on_press = function() - local next_space = self._private.text:sub(cursor_pos):find("%s") + local next_space = self._private.text:sub(cursor_pos):find('%s') if next_space then cursor_pos = cursor_pos + next_space else @@ -312,12 +310,12 @@ function inputbox:run() cursor_pos = #self._private.text + 1 end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", "Control", "Right") - end + self:emit_signal('inputbox::key_pressed', 'Control', 'Right') + end, }, akey { modifiers = {}, - key = "BackSpace", --BackSpace + key = 'BackSpace', --BackSpace on_press = function() -- If text is highlighted delete that, else just delete the character to the left if self._private.highlight and self._private.highlight.cur_pos_start and @@ -337,12 +335,12 @@ function inputbox:run() end end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", nil, "BackSpace") - end + self:emit_signal('inputbox::key_pressed', nil, 'BackSpace') + end, }, akey { modifiers = {}, - key = "Delete", --delete + key = 'Delete', --delete on_press = function() -- If text is highlighted delete that, else just delete the character to the right if self._private.highlight and self._private.highlight.cur_pos_start and @@ -359,41 +357,41 @@ function inputbox:run() end end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", nil, "Delete") - end + self:emit_signal('inputbox::key_pressed', nil, 'Delete') + end, }, akey { modifiers = {}, - key = "Left", --left + key = 'Left', --left on_press = function() -- Move cursor ro the left if cursor_pos > 1 then cursor_pos = cursor_pos - 1 end self._private.highlight = {} - end + end, }, akey { modifiers = {}, - key = "Right", --right + key = 'Right', --right on_press = function() -- Move cursor to the right if cursor_pos <= #self._private.text then cursor_pos = cursor_pos + 1 end self._private.highlight = {} - end + end, }, --self.keybindings }, keypressed_callback = function(_, modifiers, key) - if modifiers[1] == "Shift" then + if modifiers[1] == 'Shift' then if key:wlen() == 1 then self:set_text(self._private.text:sub(1, cursor_pos - 1) .. string.upper(key) .. self._private.text:sub(cursor_pos)) cursor_pos = cursor_pos + #key end - elseif modifiers[1] == "Mod2" or "" then + elseif modifiers[1] == 'Mod2' or '' then if key:wlen() == 1 then self:set_text(self._private.text:sub(1, cursor_pos - 1) .. key .. self._private.text:sub(cursor_pos)) @@ -407,8 +405,8 @@ function inputbox:run() cursor_pos = #self._private.text + 1 end self.markup = text_with_cursor(self:get_text(), cursor_pos, self) - self:emit_signal("inputbox::key_pressed", modifiers, key) - end + self:emit_signal('inputbox::key_pressed', modifiers, key) + end, } end @@ -426,6 +424,7 @@ end -- @treturn awful.widget.inputbox The inputbox widget. -- @constructorfct awful.widget.inputbox function inputbox.new(args) + args = args or {} -- directly pass a possible default text(this is not meant to be a hint) local w = textbox() @@ -437,7 +436,7 @@ function inputbox.new(args) w.keybindings = args.keybindings or {} w.hint_text = args.hint_text - w.markup = args.text or text_with_cursor("", 1, w) + w.markup = args.text or text_with_cursor('', 1, w) return w end diff --git a/awesome/awful/widget/toggle_widget.lua b/awesome/awful/widget/toggle_widget.lua index 1907e9c..887a5fc 100644 --- a/awesome/awful/widget/toggle_widget.lua +++ b/awesome/awful/widget/toggle_widget.lua @@ -1,11 +1,11 @@ -local base = require("wibox.widget.base") -local gtable = require("gears.table") -local gcolor = require("gears.color") -local dpi = require("beautiful").xresources.apply_dpi -local wibox = require("wibox") -local gshape = require("gears.shape") -local rubato = require("src.lib.rubato") -local abutton = require("awful.button") +local base = require('wibox.widget.base') +local gtable = require('gears.table') +local gcolor = require('gears.color') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local gshape = require('gears.shape') +local rubato = require('src.lib.rubato') +local abutton = require('awful.button') local toggle_widget = { mt = {} } @@ -52,7 +52,7 @@ function toggle_widget:toggle_animation(pos, color) cr:move_to(pos, 0) local x = pos local y = 5 - local newwidth = width / 2 - 10 + local newwidth = width / 2 - 6 local newheight = height - 10 local radius = height / 6.0 @@ -88,7 +88,7 @@ function toggle_widget.new(args) end, draw = ret:toggle_animation(0, ret.newcolor), }, - id = "background", + id = 'background', }, active = false, widget = wibox.container.background, @@ -106,9 +106,9 @@ function toggle_widget.new(args) duration = 0.2, pos = 5, subscribed = function(pos) - ret.toggle_button:get_children_by_id("background")[1].draw = ret:toggle_animation(pos, ret.newcolor) - ret.toggle_button:emit_signal("widget::redraw_needed") - end + ret.toggle_button:get_children_by_id('background')[1].draw = ret:toggle_animation(pos, ret.newcolor) + ret.toggle_button:emit_signal('widget::redraw_needed') + end, } ret:set_widget(wibox.widget { @@ -116,27 +116,27 @@ function toggle_widget.new(args) { args.text and { text = args.text, - valign = "center", - align = "center", + valign = 'center', + align = 'center', widget = wibox.widget.textbox, - id = "clearall" + id = 'clearall', } or nil, ret.toggle_button, spacing = args.text and dpi(10) or dpi(0), layout = wibox.layout.fixed.horizontal, - id = "layout12" + id = 'layout12', }, - id = "background4", + id = 'background4', fg = args.fg, shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) end, - widget = wibox.container.background + widget = wibox.container.background, }, - id = "place", + id = 'place', widget = wibox.container.place, - valign = "bottom", - halign = "right", + valign = 'bottom', + halign = 'right', }) ret.toggle_button:buttons( @@ -147,7 +147,7 @@ function toggle_widget.new(args) else ret:set_enabled() end - ret:emit_signal("dnd::toggle", ret.active) + ret:emit_signal('dnd::toggle', ret.active) end ) ) diff --git a/awesome/rc.lua b/awesome/rc.lua index 38ad7da..a46cfdc 100644 --- a/awesome/rc.lua +++ b/awesome/rc.lua @@ -1,12 +1,40 @@ ---@diagnostic disable: lowercase-global ------------------------------------------------------------------------------------------ --- █████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███╗ ███╗███████╗██╗ ██╗███╗ ███╗ -- --- ██╔══██╗██║ ██║██╔════╝██╔════╝██╔═══██╗████╗ ████║██╔════╝██║ ██║████╗ ████║ -- --- ███████║██║ █╗ ██║█████╗ ███████╗██║ ██║██╔████╔██║█████╗ ██║ █╗ ██║██╔████╔██║ -- --- ██╔══██║██║███╗██║██╔══╝ ╚════██║██║ ██║██║╚██╔╝██║██╔══╝ ██║███╗██║██║╚██╔╝██║ -- --- ██║ ██║╚███╔███╔╝███████╗███████║╚██████╔╝██║ ╚═╝ ██║███████╗╚███╔███╔╝██║ ╚═╝ ██║ -- --- ╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ -- ------------------------------------------------------------------------------------------ +--[[ + +╭─────────────────────────────────────────────────────────────────╮ +│ ______ ___ ________ │ +│ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ │ +│ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ │ +│ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ │ +│ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ │ +│ /____/ │ +╰─────────────────────────────────────────────────────────────────╯ + +]] +--#region prints +io.stdout:write([[ +]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ /____/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[╰─────────────────────────────────────────────────────────────────╯ +]] .. '\27[0m\n') + +io.stderr:write([[ +]] .. '\n\27[32m' .. [[╭─────────────────────────────────────────────────────────────────╮ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ ______ ___ ________ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / ____/______ __/ (_)___ _ /_ __/ /_ ___ ____ ___ ___ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / / / ___/ / / / / / __ `/ / / / __ \/ _ \/ __ `__ \/ _ \ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ / /___/ / / /_/ / / / /_/ / / / / / / / __/ / / / / / __/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ \____/_/ \__, /_/_/\__,_/ /_/ /_/ /_/\___/_/ /_/ /_/\___/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[│]] .. '\27[1;36m' .. [[ /____/ ]] .. '\27[32m' .. [[│ +]] .. '\27[32m' .. [[╰─────────────────────────────────────────────────────────────────╯ +]] .. '\27[0m\n') +--#endregion + -- Initialising, order is important! awesome = awesome client = client @@ -20,18 +48,20 @@ tag = tag -- Do not touch as this is used to share some variable settings files Global_config = {} -require("src.core.error_handling") -require("src.theme.user_config") -require("src.theme.theme_config") -require("src.tools.gio_icon_lookup") -require("src.theme.init") -require("src.tools.hex_to_rgba") -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.init") -require("src.tools.auto_starter")(User_config.autostart) +require('src.core.error_handling') +require('src.theme.user_config') +require('src.theme.theme_config') +require('src.tools.gio_icon_lookup') +require('src.theme.init') +require('src.tools.hex_to_rgba') +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.init') +--require('src.tools.auto_starter')(User_config.autostart) -require("src.config.setup")() +--require('src.core.setup')() + +--require('src.tools.helpers.pulseaudio')() diff --git a/awesome/src/assets/CT.svg b/awesome/src/assets/CT.svg new file mode 100644 index 0000000..3cdeb42 --- /dev/null +++ b/awesome/src/assets/CT.svg @@ -0,0 +1 @@ + diff --git a/awesome/src/assets/icons/ArchLogo.png b/awesome/src/assets/icons/ArchLogo.png deleted file mode 100644 index 143dc535d606be0629e5d0b22a2f8611d945892b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20595 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 + + + diff --git a/awesome/src/assets/icons/setup/titlebar_left.png b/awesome/src/assets/icons/setup/titlebar_left.png new file mode 100644 index 0000000000000000000000000000000000000000..96cb4120ed8efe1d898a3cac7613bd9141520909 GIT binary patch literal 39014 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 FV1kQ#pXvYr literal 0 HcmV?d00001 diff --git a/awesome/src/assets/icons/setup/titlebar_top.png b/awesome/src/assets/icons/setup/titlebar_top.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6267fb9d420895d27308f72505409b60dd42c6 GIT binary patch literal 38475 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 V!{X2-1*ZT2002ovPDHLkV1hFU!rK4< literal 0 HcmV?d00001 diff --git a/awesome/src/assets/icons/start.png b/awesome/src/assets/icons/start.png new file mode 100644 index 0000000000000000000000000000000000000000..ee692b0855dd0bf4e54db5534ea120a75a222480 GIT binary patch literal 98986 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 X&DIZrJW>I100000NkvXXu0mjfVrgHF literal 0 HcmV?d00001 diff --git a/awesome/src/assets/userpfp/crylia.png b/awesome/src/assets/userpfp/crylia.png deleted file mode 100644 index f7f5c0d1f1e706d091d555fa52c718816ce30eeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 316886 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 v729xU;{%v;V~A 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 diff --git a/awesome/src/assets/userpfp/userpfp.png b/awesome/src/assets/userpfp/userpfp.png new file mode 100644 index 0000000000000000000000000000000000000000..cc2d872dcfed4cf4ef7284241e4352686276eb51 GIT binary patch literal 312349 zcmXtQC1TGz>lwB0Q%p+o9v4(XXwkjF#!oVTn5RTL)N5&;(%S zN={zqjqbV#i-&cE)Bc;*kcW9HFarSOz@Y#r4jlC20~C&pryd`mh*i#-AEzSj{M;_z zM2krXglRxzO-%mYQ&>X8(F+qq0(2y>n|qO=YwPF`fIu1`C^>Hx5*jKEVUz$D8eMlul#*aro-_yX6B+^n~baE3kWFP_n2ZEt_VAeo{trq}6r&rfxRLTzM()#P1 zOC6c_J6f`wdQ9T>Wt4hSI&;Q*kr z0^-&K5<37f0RW@-Wt8ZM!{E%NB|_U;NbTFoFDKIS&F!4+Es38DGAN#DlSrwCURuBVLeRc})9@I=bdIuba9kQ9*xE zo}|hs`Vv@iMrv2?hgTJQ$4bbF+<_{(7$7R?KF;er2RwxQX(Ip`F&wo-|1iQw2#Cc0 z`?F0K7|0ICQxY(c4N zFlrVbDG?iuz(&Cg&^3s=b2%iNNmVY0z({1$f%MU82-19SCy_dbXW=PZ!j~_SzG*9r z%qolr4U9rK zDxL2MGkOxSqOI+_{G^K~u|L?{HVOocdiIVo!C3iViO0V#&0D`Yd%g8?eBQS%D-|zi z03!K~{{quY4jHZG4DEw}%Lh=he;~4qxI8oppMf!+m_S&4(o=2RK*PZ)xoF+ZZ=as< zlkz@$Ztyv6RCN>&g(yPxLF7ZjW8%-~9{(xqp%hC>HncG~ z@Ib~fk%c8s&o+a~T*k#-4NL!~ap9<@iu!riV=1{CQb-!XYr?nG^oiYQ;SB1S!Pt3- z&(^U71o5!6R92N?1R*GdROX)#QK)q4S)g+2uoL$(MRvwW%79`9lof(ZdP=I6Eg|-t zAGh~aJ6^^M)jFt@?nH@>Tr6%p0v2DbDhnV}*BP&~UD4pIUd(2aR2U7`uFmysBo{Ya z#&lv@P3nCz%tV*DXz#1|ZE>jV7g@mqk3XOO{)`YnPy#gvv_k5MY6P0s%sbAL%znW%d_T-sxq77rJ!MqlmmQBTKSS{91{ zlu0m->MY?XXe0mZqj6xF1Z?4a-_iFv6klxVR6O&eI z7iNOCNx>NpY>8Nmp=h`;PT;Ro74p#amksKyNiWwOgc3(LZ{ZdD5CWGGkQDV#KuUHf zNr9Syk=gzoAxlsPJf=c4I^XKop@-O_b^h$z$(!L8_ok{k@0s26^x>&{>3!Rq;AWcEc|mmfjs%&iy%o#uyDBCtya(jFEoQ4 z$pDenmDa|=En`iLOdMItUv~7r+z2~to_$L#gn#iaA!_ugar5!e71ijlaee$#wSOu? zgcz6wz9ku5_%f_5ki3ZCOTn8MEacyd;9Ce&SosKvpo%mlnuWLjd#Z_<~8>-k`0mBU@iz zOB?SZ11AB>;h;OTX{ROsQw35*RM7_6Coa>>RI$v;s92Rzl9xJf)FA4=MPX(qzu5Ib zjBr_P1Wadh{ndIQ2d@qF$NgwQ@|lgLj;`}`^1;qwo7)nKHe+dP4k@T^@HnjvI>3mo ztqlp#h_ekQ@H1_fq+~<==*)~sh8@)p+;;mwU~z#duajeut?VGQ6tEV zAiqQw_xIN?t6hH7 zRO=n$vG!?vfvvrKmGX5YTZGK&NxMm*s6nx^=*bP5Ng14qok9?7iQ) zTQoXs2=cZ2V088cVt)T`<+A6rI;C>6jGt6JJWf$oJ04K~#Tu6fh|<0T|5vUdlC)q? z9M7>K$O{W~h%yIxvQ&FS^;XW-)o%?qr?Z2W3ls0nX-S95R?}eGH`ww07+R5=*}lgO zPWM*}A!S(TnfkZwign}5-V>#Vb@pMq_;h;?;yY7#RANm*a|DcBLstA(GGFxBi3hdD z-G~ya6Sdq5$5Jk(F`nKd2(5og~JcAc%u6o8yn{*U6aW*H8sQghAkup>BD3}%C*Kc z>0)kwhpsq6b{Io?a`fdS)1jB3{6IHgMV1K~)xqdUBS>4Zx7=3ef0#uOo>?I$(f`Jp z`*qv-LS*7;q=v=hDf(=qwhh<-Iksd$Nze{uxNSZ9`2xsJ`Xq9o>$O+61rT$xtFQ21 zDr)R+-OoE!v|jX1wOruQE~B@g*03-#9_mrEU38F6iFumr4R-_zeP2isCmsH}Jz(4W}RT71mAh{b4LLCx{U-kS+ZHMuJfWR)E zrw-`$Bn*A)TWin%bhK1dR4iuFoGZVzl z^6sLe0s#d9t3P=rW|fkCkx+7?X?yvK>#)j}^Yc-Ycjc0OGD$YD?$l}`8}4CK?~}P# z%hZy-jgzrW6{IY8L17n8ZKoR@bD7r%K^q5LRb*D!>s8y~$FmJ-{HNoQM61_M71O&tx#WTg@j%SUFjz#19?&T_}aj8;I zi#=(*gFiElFk=TRqoAzAs`-mfbhI=$3DO_)1iZaAuDB)Kwok5HMV!d7q>`ngL{+_^ z?O`*97*^IKMNjBfhh<0?>+5KP|dBcMX}#g6}H8zmvK6gvQ8E3fzW zPS~MD^I1o4W~^8A3;c40ug2{Ec+@6)s7$ZNwqK?6ZhSFXJii{et5|P3JDZ%kwzIUa zo_?1%+DfOY{MZD!M~1VX>M_46?05LG=7JG?Q?-lsgbzXV9n1kEWH?d3mS&3YGxU}L zN|Mm{OYDf{_T9aI+1Gql&=7F0a#KwW$0a}z0TIGaEGRM}P+;`|IPrYnTS69%>P7L= zX+o;lXp)qXr{c$J>w_ty8&5>!gSO})IctCgL|RH%H(D32jR7b5psSPN2F{@&1)b5_cRbEpmJej(-1Dk9~Q&`C4oj2XU6b717s zmFt2aN8T1y`R%q$;x9$u)t=zU{+M>apJ?+r4Y4=9HgvS>_?}Wg77FAPcp+ZkzO6fF zWfJd%wu#*y!=y?T*pLy$kdks{dKfE;0h|-S_}a*6>Hf^#!|ycxE{ucT?rR)Hj#tRS zN>AiCnWJj9zlD#h@;m=u&+E_TpG_b5)L%HidHBn)!y>}Xs$EnxVq((h`O(#SWN@v; zAwZ>!V=(PmO2MuNq`h_+>B>{xhb(M5-Mk@Q^+wHMHs}J!RuGFG^1}C{;o;;tkPJ_ zV|^#2OpiNTRB+mnX@ymHLYZ9bo6s9YMsT3^?Kpw3yoIcNBBK&C2{-p;BiS(y33h|B ztxv5>-N*X2CfAD*`^vlPv*qUB4rjkcV~4XS(oLFgyQ_=7ierWF9tA=a({z#@R(cj| zVwdjr)%=NR4pfp{uVl#s1q+xc_f(xBN2OSNwL zP2hd7!EbsuVmgx9634xPx!*Nubl7~Bc-Zm~Nq6{kd6$-&V(|1){Yzd=ZkpUa+pP3& z5cTC^RW8+w5>RF(PSoNiCSvt&&q6_wNLFNCM1+=2#jAuF!!mZ1Oup)CbDY59CAyxCQYhBo95J+xu;3`|UJE_b`us9TbT_pHe)QY3su=x* zAN^k^q(!lT>P6)=KA2xf$nRip_SNP{ra>w`xsd`U6~{%a`?H;<-A5rAq5YKfx2TMT zg&a@llaM^=19$HrlhJ3)(C-=!^ZO>mEbE%Hqz) zSl@}h>1McvhC}0#;HiMNn^2)X>;?a__X<>TwuT z%8~M9)?vy3b45JcceLO)lav_-qbxCm7z83lXZb^n-VYWvE3zUW(x@8SKX1HComGxf zd)?}JKh_gTHu6*l`(u9p-}CE}An*C~-Tfd5)jU@&I-Z*VvU$eD{wTGm$ditHzlmL& z>IR?I3CG$;1Li`kVm57ChSw(3av2Rsj#YX1zdDY5Y{SC6>Ir}*x|cRx#_xjGx~q{& zzw`O*d)u3-3PNDGUpb(PPrCL5~N)_Tb>$mQ)a@Zko@2_5Fu4Gj%7->aKiThEGhC3hZAN5gj>Hk;ox4sowr4|O6NUh>lQ z#1n;ePhrv8B%x=Nf+>s4GFcH+s}!nX2_iP*SQZG%o{`I0*@khoTV-n>*PXG#M=fyG zo&1WdtPq?lv0$?3>-?;A|H2OQ(T!oIvO1+G!tP~|+`G6w>oUy$UHYkvV$^;Tk17mP z+U)z4L#;O0GOwFptV(;l?>d&J^N`$M9OA5rQHl&kvTv1#jeXs3xl1>_U%^~{_qCi; zmwEJQhKthohK5?-Z^yThqxU}_)+IN-7n(loof$bT`(1WabY(6Y>wivfI$G1>e(k?f zc-2#8Zq5f91hot)6D7Yg?KCs zGe|n$L{eDTcEUc>kwwV@a_kce%XGs=w)bALbAEzK$eYT7;!p%gUZEMS{Ze-<%q$Ax z?=o}YO*c357td(@F1LPT8i@^_xmS!ki8+U8=88WT5_+abPIdSX!{cD-wW)W~lV(?5 zQ}z^JN%cg~V(dlCQn%>3+0^{hpW9iM@fWZ#CwN^eKU{Zgx%@qjgZPqThg zb=`dI>d8bB7GLkPlTmjdpWfn8sWo+yF=0i;`i|!Y4*eXL)dn$TIu}C&X%W2|3!Nf{@Rfg9dk7c#j z&F}9fwqK3A*_4wPS!L>f@M~8k)S$OuTm>?Vp>P6rBz8#xs+hHC)&Q)rDVu>NWuaPB ziLz~*-*Fd>wys`u6tjtM7umd`4$dl8$(s=gL(1lAxsO~j+lzC@ctw5EfDw+xbOg}T zzbCx#%9P)Cu3Hq{x$vscWl*&kv1v%f{~n_G;kL7I_eqhex3q1PQi83&)8?Yb^4zkQ zKzyN_O^V6=Mje-Fn*l}oj;s1!?Ji8oiw z^XvPQzvfHMvF-{Y_1T)n*E?A7zZmxLKOS6mprxh}%@Foq-;3TP<(7zl8pEV2}#J)kJZ3!=$EBbK621Y$cAhryY04{KgCJ>HFY|*@SedptKcX;F{QBV zM4b<+a!h9^X~Bv^J#A@qFpH{oHybE~8G6g3^G?h8u3&nHnug}!!+eD>C6u+A-kK3% zp+Ta9uvUK|y9fH%o`pa#6yu8HMhU`r^}#CFnHwDk_q_w>J3$p^VP{^$^dB2sKkiJ- zrjMHX9IU?@ZLNR5KRd3Moz>#ZASq&+Wl%oCsa>==u*xsn+;+9qktr5dW7v!Tg{3!g zmXkr0;7u)3mqclN1WjH>Q3Rf86k7^aR4hkrFMQN_^FnqlgK@+FwE8hG70a!!V)E^xn(g2ni`ozHZpc4E3r&fLWPF*wFvaS zHvwZwSC8Idzk+m3SVXityZSjin0ffx7f$aRH+%jaN-Grepu63o^Y`=om1R)xys?lRsppi@^xoIi zowtv)!fdad4e{}9AARPR=NTEVJi)?WUv~ebWl+RCBLtOV7mL;e6&s0(7Ej`(pLtO_ zQQXt>Rcpw(U`t62tr6TPMnNH11Muz1z8W;j;0&oTyE?quTD_DMCrRU$w(7QVB87&| z%kApTY_Ee}y;k?_Su#~q@14%*bQ`YMWvZi?SEXL&d3$j*adcKs3I{GPFS|WIz~;R@ z4!%}ae9TJA%ILES?4IrJ-TSEF5N$4tut2}f9UXG$zRev-==lZmzo z0r_N~UM<|-4%OJFY>;gbul?N_xH)X8u5Q67zLNR7P@?r1mJD?H6+OCtT|7}0_U@t; z?lumt--USvl|_U-eNxwyTK%o=6v+Q-twu@%UFLcKaGkoyB2CCB2Y!P;t2g|e_Uoee z;dEu|O(dP5hfvXAvOU??s|@e@<_3>?4W~m4zdu)LlVL`5zCWVkUh6kDdY*dpJ(Xx4Uuvf|OS z;20sG7(Gq(Wz+?2Qs?qIK$SAV&K9q!@h8rs&L#FpWzu32@62MTmT_R--oF7D-qPf795&+Tfu!b{TN z>AScI`G!QOpEh4Q;jkiENR%!R%JfR=MFZ-;F;Z(KQU>_x?ccrHug_Z2h^Ib)mka*q z?Xvo3SkM1xO3hz*X1?D2eqnt2>xF1gGNyg()H94)S|$}CzcOB7QCqdq$Fe?~oxOUp zetfkZQdrWUwYHh$3yefzdFQh$K#lVamrlToh(@L*Q2vt|_ ze53Zd(Q{+x?1`F$$K5M#ldG}F)uPc5%kd;OQEr$JkinYAyH^FrMzW(U3}>+v{e<*5 zW0PMpSuD*O&oAloxPQt@WxqP6d>4^|pNV2SHu7q!zK=XFBSGuz=+U0ru)XShOsas4{%mO;TA z3>p8=0{Atzwt@xaH%`Xa z$X;1ir;U-PI{#@8pkF1zL^?z%0Due}cvpGN940MZ7u0rYRWGdxrnK)m)D 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%0Dz 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 z z(UluJds~y~+R9;QqDmm=G$jDkgy^z>Dy!-T|M1e^{OMnA-MszyBgc;q*H@3M4JOUe z@zHH5#*;?2CSDPfSh;&j*)TW9J0E@~K>#J(m-D~m0d#5sb>TO3fkczQ$)E#Oq@0F9 z2xUG>iz=-S(>Q0}S_#gRg(WIX?#%=!g80 ztpV)ZzD_;^ELz9`Kqkbq3)p@FI~@QDvjk{FS5hh`%{)ctN*N=a3`_s+L*Vx#c0Fc1O~Fe8AbBu̯C1l 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

Y&}+|1NSl`)g2--D~v19A23 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 z�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 literal 0 HcmV?d00001 diff --git a/awesome/src/bindings/bind_to_tags.lua b/awesome/src/bindings/bind_to_tags.lua index 78f6f59..c231428 100644 --- a/awesome/src/bindings/bind_to_tags.lua +++ b/awesome/src/bindings/bind_to_tags.lua @@ -1,7 +1,12 @@ -- Awesome Libs -local awful = require("awful") -local gears = require("gears") -local globalkeys = require("src.bindings.global_keys") +local akey = require('awful.key') +local ascreen = require('awful.screen') +local atag = require('awful.tag') +local gtable = require('gears.table') + +-- Local libs +local globalkeys = require('src.bindings.global_keys') + local modkey = User_config.modkey local capi = { @@ -10,63 +15,34 @@ local capi = { } for i = 1, 9 do - globalkeys = gears.table.join(globalkeys, + globalkeys = gtable.join(globalkeys, + akey({ modkey }, '#' .. i + 9, function() + local screen = ascreen.focused() + local tag = screen.tags[i] + if tag then + tag:view_only() + end + capi.client.emit_signal('tag::switched') + end, { description = 'Switch to tag ' .. i, group = 'Tag' }), - -- View tag only - awful.key( - { modkey }, - "#" .. i + 9, + akey({ modkey, 'Control' }, '#' .. i + 9, function() - local screen = awful.screen.focused() + local screen = ascreen.focused() local tag = screen.tags[i] if tag then - tag:view_only() + atag.viewtoggle(tag) end - capi.client.emit_signal("tag::switched") - end, - { description = "View Tag " .. i, group = "Tag" } - ), - -- Brings the window over without chaning the tag, reverts automatically on tag change - awful.key( - { modkey, "Control" }, - "#" .. i + 9, - function() - local screen = awful.screen.focused() + end, { description = 'View tag ' .. i, group = 'Tag' }), + + akey({ modkey, 'Shift' }, '#' .. i + 9, function() + local screen = ascreen.focused() + if capi.client.focus then local tag = screen.tags[i] if tag then - awful.tag.viewtoggle(tag) + capi.client.focus:move_to_tag(tag) end - end, - { description = "Toggle Tag " .. i, group = "Tag" } - ), - -- Brings the window over without chaning the tag, reverts automatically on tag change - awful.key( - { modkey, "Shift" }, - "#" .. i + 9, - function() - local screen = awful.screen.focused() - if capi.client.focus then - local tag = screen.tags[i] - if tag then - capi.client.focus:move_to_tag(tag) - end - end - end, - { description = "Move focused client on tag " .. i, group = "Tag" } - ), - -- Brings the window over without chaning the tag, reverts automatically on tag change - awful.key( - { modkey, "Control", "Shift" }, - "#" .. i + 9, - function() - local screen = awful.screen.focused() - local tag = screen.tags[i] - if tag then - awful.tag.viewtoggle(tag) - end - end, - { description = "Move focused client on tag " .. i, group = "Tag" } - ) + end + end, { description = 'Move focused client to tag ' .. i, group = 'Tag' }) ) end capi.root.keys(globalkeys) diff --git a/awesome/src/bindings/client_buttons.lua b/awesome/src/bindings/client_buttons.lua index d24d617..2860eaf 100644 --- a/awesome/src/bindings/client_buttons.lua +++ b/awesome/src/bindings/client_buttons.lua @@ -1,19 +1,20 @@ -- Awesome Libs -local awful = require("awful") -local gears = require("gears") +local abutton = require('awful.button') +local gtable = require('gears.table') +local amouse = require('awful.mouse') local modkey = User_config.modkey -return gears.table.join( - awful.button({}, 1, function(c) - c:emit_signal("request::activate", "mouse_click", { raise = true }) +return gtable.join { + abutton({}, 1, function(c) + c:emit_signal('request::activate', 'mouse_click', { raise = true }) end), - awful.button({ modkey }, 1, function(c) - c:emit_signal("request::activate", "mouse_click", { raise = true }) - awful.mouse.client.move(c) + abutton({ modkey }, 1, function(c) + c:emit_signal('request::activate', 'mouse_click', { raise = true }) + amouse.client.move(c) end), - awful.button({ modkey }, 3, function(c) - c:emit_signal("request::activate", "mouse_click", { raise = true }) - awful.mouse.client.resize(c) - end) -) + abutton({ modkey }, 3, function(c) + c:emit_signal('request::activate', 'mouse_click', { raise = true }) + amouse.client.resize(c) + end), +} diff --git a/awesome/src/bindings/client_keys.lua b/awesome/src/bindings/client_keys.lua index 8e98b82..46aac49 100644 --- a/awesome/src/bindings/client_keys.lua +++ b/awesome/src/bindings/client_keys.lua @@ -1,61 +1,156 @@ -- Awesome Libs -local awful = require("awful") -local gears = require("gears") - -local capi = { - client = client -} +local aclient = require('awful.client') +local akey = require('awful.key') +local ascreen = require('awful.screen') +local gtable = require('gears.table') local modkey = User_config.modkey -return gears.table.join( - awful.key( - { modkey }, - "#41", - function(c) - c.fullscreen = not c.fullscreen - c:raise() - end, - { description = "Toggle fullscreen", group = "Client" } - ), - awful.key( - { modkey }, - "#24", - function(c) - c:kill() - end, - { description = "Close focused client", group = "Client" } - ), - awful.key( - { modkey }, - "#42", - awful.client.floating.toggle, - { description = "Toggle floating window", group = "Client" } - ), - awful.key( - { modkey }, - "#58", - function(c) - c.maximized = not c.maximized - c:raise() - end, - { description = "(un)maximize", group = "Client" } - ), - awful.key( - { modkey }, - "#57", - function(c) - if c == capi.client.focus then - c.minimized = true - else - c.minimized = false - if not c:isvisible() and c.first_tag then - c.first_tag:view_only() - end - c:emit_signal('request::activate') - c:raise() - end - end, - { description = "(un)hide", group = "Client" } - ) +return gtable.join( +--#region Basic interactions + akey({ modkey }, '#24', function(c) + c:kill() + end, { description = 'Close client', group = 'Client' }), + + akey({ modkey }, '#41', function(c) + c.fullscreen = not c.fullscreen + c:raise() + end, { description = 'Toggle fullscreen', group = 'Client' }), + + akey({ modkey }, '#42', + aclient.floating.toggle, + { description = 'Toggle floating', group = 'Client' }), + + akey({ modkey }, '#57', function(c) + c.minimized = true + end, { description = 'Minimize', group = 'Client' }), + + akey({ modkey }, '#58', function(c) + c.maximized = not c.maximized + c:raise() + end, { description = 'Toggle maximize', group = 'Client' }), + --#endregion + + --#region Client focus movement + akey({ modkey }, '#44', function(c) + aclient.focus.global_bydirection('up', c) + end, { description = 'Move client a screen up', group = 'Client' }), + + akey({ modkey }, '#111', function(c) + aclient.focus.global_bydirection('up', c) + end, { description = 'Move client a screen up', group = 'Client' }), + + akey({ modkey }, '#43', function(c) + aclient.focus.global_bydirection('left', c) + end, { description = 'Move client a screen left', group = 'Client' }), + + akey({ modkey }, '#113', function(c) + aclient.focus.global_bydirection('left', c) + end, { description = 'Move client a screen left', group = 'Client' }), + + akey({ modkey }, '#46', function(c) + aclient.focus.global_bydirection('right', c) + end, { description = 'Move client a screen right', group = 'Client' }), + + akey({ modkey }, '#114', function(c) + aclient.focus.global_bydirection('right', c) + end, { description = 'Move client a screen right', group = 'Client' }), + + akey({ modkey }, '#45', function(c) + aclient.focus.global_bydirection('down', c) + end, { description = 'Move client a screen down', group = 'Client' }), + + akey({ modkey }, '#116', function(c) + aclient.focus.global_bydirection('down', c) + end, { description = 'Move client a screen down', group = 'Client' }), + --#endregion + + --#region Screen movement + akey({ modkey, 'Shift' }, '#44', function(c) + local s = ascreen.focus_bydirection('Up', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen up', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#111', function(c) + local s = ascreen.focus_bydirection('Up', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + c:activate { + --switch_to_tag = true, + raise = true, + context = 'somet_reason', + } + end, { description = 'Move client a screen up', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#43', function(c) + c:move_to_screen(ascreen.focus_bydirection('left', c.screen)) + c.first_tag:view_only() + client.focus = c + c:raise() + c:activate { + --switch_to_tag = true, + raise = true, + context = 'somet_reason', + } + end, { description = 'Move client a screen left', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#113', function(c) + local s = ascreen.focus_bydirection('left', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen left', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#46', function(c) + local s = ascreen.focus_bydirection('Right', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen right', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#114', function(c) + local s = ascreen.focus_bydirection('Right', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen right', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#45', function(c) + local s = ascreen.focus_bydirection('Down', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen down', group = 'Client' }), + + akey({ modkey, 'Shift' }, '#116', function(c) + local s = ascreen.focus_bydirection('Down', c.screen) + c:move_to_screen(s) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + c:emit_signal('request::activate') + c:raise() + end, { description = 'Move client a screen down', group = 'Client' }) +--#endregion ) diff --git a/awesome/src/bindings/global_buttons.lua b/awesome/src/bindings/global_buttons.lua index 266067d..68adb02 100644 --- a/awesome/src/bindings/global_buttons.lua +++ b/awesome/src/bindings/global_buttons.lua @@ -1,12 +1,13 @@ -- Awesome Libs -local gears = require("gears") -local awful = require("awful") +local gtable = require('gears.table') +local abutton = require('awful.button') +local atag = require('awful.tag') local capi = { root = root } -capi.root.buttons = gears.table.join( - awful.button({}, 4, awful.tag.viewnext), - awful.button({}, 5, awful.tag.viewprev) +capi.root.buttons = gtable.join( + abutton({}, 4, atag.viewnext), + abutton({}, 5, atag.viewprev) ) diff --git a/awesome/src/bindings/global_keys.lua b/awesome/src/bindings/global_keys.lua index 46e7a63..61fe4be 100644 --- a/awesome/src/bindings/global_keys.lua +++ b/awesome/src/bindings/global_keys.lua @@ -1,11 +1,21 @@ -- Awesome libs -local gears = require("gears") -local awful = require("awful") -local hotkeys_popup = require("awful.hotkeys_popup") -local ruled = require("ruled") +local akeygrabber = require('awful.keygrabber') +local akey = require('awful.key') +local gtable = require('gears.table') +local atag = require('awful.tag') +local aclient = require('awful.client') +local aspawn = require('awful.spawn') +local alayout = require('awful.layout') +local ascreen = require('awful.screen') +local hotkeys_popup = require('awful.hotkeys_popup') +local ruled = require('ruled') --- Third party libs -local json = require("src.lib.json-lua.json-lua") +-- Local libs +local config = require('src.tools.config') +local audio_helper = require('src.tools.helpers.audio') +local backlight_helper = require('src.tools.helpers.backlight') +local powermenu = require('src.modules.powermenu.init') +local kb_helper = require('src.tools.helpers.kb_helper') local capi = { awesome = awesome, @@ -15,301 +25,290 @@ local capi = { local modkey = User_config.modkey -awful.keygrabber { - keybindings = { - awful.key { - modifiers = { "Mod1" }, - key = "Tab", +akeygrabber { + keybindings = { + akey { + modifiers = { 'Mod1' }, + key = 'Tab', on_press = function() - capi.awesome.emit_signal("window_switcher::select_next") - end - } + capi.awesome.emit_signal('window_switcher::select_next') + end, + }, }, - root_keybindings = { - awful.key { - modifiers = { "Mod1" }, - key = "Tab", + root_keybindings = { + akey { + modifiers = { 'Mod1' }, + key = 'Tab', on_press = function() - end - } + end, + }, }, - stop_key = "Mod1", - stop_event = "release", - start_callback = function() - capi.awesome.emit_signal("toggle_window_switcher") + stop_key = 'Mod1', + stop_event = 'release', + start_callback = function() + capi.awesome.emit_signal('toggle_window_switcher') end, - stop_callback = function() - capi.awesome.emit_signal("window_switcher::raise") - capi.awesome.emit_signal("toggle_window_switcher") + stop_callback = function() + capi.awesome.emit_signal('window_switcher::raise') + capi.awesome.emit_signal('toggle_window_switcher') end, export_keybindings = true, } -return gears.table.join( - awful.key( +return gtable.join( + akey( { modkey }, - "#39", + '#39', hotkeys_popup.show_help, - { description = "Cheat sheet", group = "Awesome" } + { description = 'Cheat sheet', group = 'Awesome' } ), - -- Tag browsing - awful.key( + --[[ akey( { modkey }, - "#113", - awful.tag.viewprev, - { description = "View previous tag", group = "Tag" } + '#113', + atag.viewprev, + { description = 'View previous tag', group = 'Tag' } ), - awful.key( + akey( { modkey }, - "#114", - awful.tag.viewnext, - { description = "View next tag", group = "Tag" } - ), - awful.key( + '#114', + atag.viewnext, + { description = 'View next tag', group = 'Tag' } + ), ]] + akey( { modkey }, - "#66", - awful.tag.history.restore, - { description = "Go back to last tag", group = "Tag" } + '#66', + atag.history.restore, + { description = 'Go back to last tag', group = 'Tag' } ), - awful.key( + akey( { modkey }, - "#44", + '#44', function() - awful.client.focus.byidx(1) + aclient.focus.byidx(1) end, - { description = "Focus next client by index", group = "Client" } + { description = 'Focus next client by index', group = 'Client' } ), - awful.key( + akey( { modkey }, - "#45", + '#45', function() - awful.client.focus.byidx(-1) + aclient.focus.byidx(-1) end, - { description = "Focus previous client by index", group = "Client" } + { description = 'Focus previous client by index', group = 'Client' } ), - awful.key( - { modkey, "Shift" }, - "#44", + akey( + { modkey, 'Shift' }, + '#44', function() - awful.client.swap.byidx(1) + aclient.swap.byidx(1) end, - { description = "Swap with next client by index", group = "Client" } + { description = 'Swap with next client by index', group = 'Client' } ), - awful.key( - { modkey, "Shift" }, - "#45", + akey( + { modkey, 'Shift' }, + '#45', function() - awful.client.swap.byidx(-1) + aclient.swap.byidx(-1) end, - { description = "Swap with previous client by index", group = "Client" } + { description = 'Swap with previous client by index', group = 'Client' } ), - awful.key( - { modkey, "Control" }, - "#44", + akey( + { modkey, 'Control' }, + '#44', function() - awful.screen.focus_relative(1) + ascreen.focus_relative(1) end, - { description = "Focus the next screen", group = "Screen" } + { description = 'Focus the next screen', group = 'Screen' } ), - awful.key( - { modkey, "Control" }, - "#45", + akey( + { modkey, 'Control' }, + '#45', function() - awful.screen.focus_relative(-1) + ascreen.focus_relative(-1) end, - { description = "Focus the previous screen", group = "Screen" } + { description = 'Focus the previous screen', group = 'Screen' } ), - awful.key( + akey( { modkey }, - "#30", - awful.client.urgent.jumpto, - { description = "Jump to urgent client", group = "Client" } + '#30', + aclient.urgent.jumpto, + { description = 'Jump to urgent client', group = 'Client' } ), - awful.key( + akey( { modkey }, - "#36", + '#36', function() - awful.spawn(User_config.terminal) + aspawn(User_config.terminal) end, - { description = "Open terminal", group = "Applications" } + { description = 'Open terminal', group = 'Applications' } ), - awful.key( - { modkey, "Control" }, - "#27", + akey( + { modkey, 'Control' }, + '#27', capi.awesome.restart, - { description = "Reload awesome", group = "Awesome" } + { description = 'Reload awesome', group = 'Awesome' } ), - awful.key( + akey( { modkey }, - "#46", + '#46', function() - awful.tag.incmwfact(0.05) + atag.incmwfact(0.05) end, - { description = "Increase client width", group = "Layout" } + { description = 'Increase client width', group = 'Layout' } ), - awful.key( + akey( { modkey }, - "#43", + '#43', function() - awful.tag.incmwfact(-0.05) + atag.incmwfact(-0.05) end, - { description = "Decrease client width", group = "Layout" } + { description = 'Decrease client width', group = 'Layout' } ), - awful.key( - { modkey, "Control" }, - "#43", + akey( + { modkey, 'Control' }, + '#43', function() - awful.tag.incncol(1, nil, true) + atag.incncol(1, nil, true) end, - { description = "Increase the number of columns", group = "Layout" } + { description = 'Increase the number of columns', group = 'Layout' } ), - awful.key( - { modkey, "Control" }, - "#46", + akey( + { modkey, 'Control' }, + '#46', function() - awful.tag.incncol(-1, nil, true) + atag.incncol(-1, nil, true) end, - { description = "Decrease the number of columns", group = "Layout" } + { description = 'Decrease the number of columns', group = 'Layout' } ), - awful.key( - { modkey, "Shift" }, - "#65", + akey( + { modkey, 'Shift' }, + '#65', function() - awful.layout.inc(-1) + alayout.inc(-1) end, - { description = "Select previous layout", group = "Layout" } + { description = 'Select previous layout', group = 'Layout' } ), - awful.key( - { modkey, "Shift" }, - "#36", + akey( + { modkey, 'Shift' }, + '#36', function() - awful.layout.inc(1) + alayout.inc(1) end, - { description = "Select next layout", group = "Layout" } + { description = 'Select next layout', group = 'Layout' } ), - awful.key( + akey( { modkey }, - "#40", + '#40', function() - capi.awesome.emit_signal("application_launcher::show") + capi.awesome.emit_signal('application_launcher::show') end, - { descripton = "Application launcher", group = "Application" } + { descripton = 'Application launcher', group = 'Application' } ), - awful.key( + akey( { modkey }, - "#26", + '#26', function() - awful.spawn(User_config.file_manager) + aspawn(User_config.file_manager) end, - { descripton = "Open file manager", group = "System" } + { descripton = 'Open file manager', group = 'System' } ), - awful.key( - { modkey, "Shift" }, - "#26", + akey( + { modkey, 'Shift' }, + '#26', function() - capi.awesome.emit_signal("module::powermenu:show") + powermenu:toggle() end, - { descripton = "Session options", group = "System" } + { descripton = 'Session options', group = 'System' } ), - awful.key( + akey( {}, - "#107", + '#107', function() - awful.spawn(User_config.screenshot_program) + aspawn(User_config.screenshot_program) end, - { description = "Screenshot", group = "Applications" } + { description = 'Screenshot', group = 'Applications' } ), - awful.key( + akey( {}, - "XF86AudioLowerVolume", + 'XF86AudioLowerVolume', function(c) - awful.spawn.easy_async_with_shell("pactl set-sink-volume @DEFAULT_SINK@ -2%", function() - capi.awesome.emit_signal("widget::volume_osd:rerun") - end) + audio_helper.sink_volume_down() end, - { description = "Lower volume", group = "System" } + { description = 'Lower volume', group = 'System' } ), - awful.key( + akey( {}, - "XF86AudioRaiseVolume", + 'XF86AudioRaiseVolume', function(c) - awful.spawn.easy_async_with_shell("pactl set-sink-volume @DEFAULT_SINK@ +2%", function() - capi.awesome.emit_signal("widget::volume_osd:rerun") - end) + audio_helper.sink_volume_up() end, - { description = "Increase volume", group = "System" } + { description = 'Increase volume', group = 'System' } ), - awful.key( + akey( {}, - "XF86AudioMute", + 'XF86AudioMute', function(c) - awful.spawn("pactl set-sink-mute @DEFAULT_SINK@ toggle") - capi.awesome.emit_signal("widget::volume_osd:rerun") + audio_helper.sink_toggle_mute() end, - { description = "Mute volume", group = "System" } + { description = 'Mute volume', group = 'System' } ), - awful.key( + akey( {}, - "XF86MonBrightnessUp", + 'XF86MonBrightnessUp', function(c) backlight_helper.brightness_increase() end, - { description = "Raise backlight brightness", group = "System" } + { description = 'Raise backlight brightness', group = 'System' } ), - awful.key( + akey( {}, - "XF86MonBrightnessDown", + 'XF86MonBrightnessDown', function(c) backlight_helper.brightness_decrease() end, - { description = "Lower backlight brightness", group = "System" } + { description = 'Lower backlight brightness', group = 'System' } ), - awful.key( + akey( {}, - "XF86AudioPlay", + 'XF86AudioPlay', function(c) - awful.spawn("playerctl play-pause") + aspawn('playerctl play-pause') end, - { description = "Play / Pause audio", group = "System" } + { description = 'Play / Pause audio', group = 'System' } ), - awful.key( + akey( {}, - "XF86AudioNext", + 'XF86AudioNext', function(c) - awful.spawn("playerctl next") + aspawn('playerctl next') end, - { description = "Play / Pause audio", group = "System" } + { description = 'Play / Pause audio', group = 'System' } ), - awful.key( + akey( {}, - "XF86AudioPrev", + 'XF86AudioPrev', function(c) - awful.spawn("playerctl previous") + aspawn('playerctl previous') end, - { description = "Play / Pause audio", group = "System" } + { description = 'Play / Pause audio', group = 'System' } ), - awful.key( + akey( { modkey }, - "#65", + '#65', function() - capi.awesome.emit_signal("kblayout::toggle") + kb_helper:cycle_layout() end, - { description = "Toggle keyboard layout", group = "System" } + { description = 'Cycle keyboard layout', group = 'System' } ), - awful.key( + akey( { modkey }, - "#22", + '#22', function() capi.mousegrabber.run( function(m) if m.buttons[1] then - - local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r") - if not handler then return end - local data_table = json:decode(handler:read("a")) or {} - handler:close() - - if type(data_table) ~= "table" then return end + local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json') + if type(data) ~= 'table' then return end local c = capi.mouse.current_client if not c then return end @@ -320,8 +319,8 @@ return gears.table.join( WM_INSTANCE = c.instance, } - -- Check if data_table already had the client then return - for _, v in ipairs(data_table) do + -- 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 @@ -329,43 +328,33 @@ return gears.table.join( end end - table.insert(data_table, client_data) + table.insert(data, client_data) ruled.client.append_rule { rule = { class = c.class, instance = c.instance }, properties = { - floating = true + floating = true, }, } c.floating = true - handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "w") - if not handler then return end - handler:write(json:encode(data_table)) - handler:close() + config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data) capi.mousegrabber.stop() end return true end, - "crosshair" + 'crosshair' ) end ), - awful.key( - { modkey, "Shift" }, - "#22", + akey( + { modkey, 'Shift' }, + '#22', function() capi.mousegrabber.run( function(m) if m.buttons[1] then - - local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r") - if not handler then return end - local data_table = json:decode(handler:read("a")) or {} - handler:close() - - if type(data_table) ~= "table" then return end - + local data = config.read_json('/home/crylia/.config/awesome/src/config/floating.json') local c = capi.mouse.current_client if not c then return end @@ -376,14 +365,14 @@ return gears.table.join( } -- Remove client_data from data_table - for k, v in ipairs(data_table) do + for k, v in ipairs(data) do if v.WM_CLASS == client_data.WM_CLASS and v.WM_INSTANCE == client_data.WM_INSTANCE then - table.remove(data_table, k) + table.remove(data, k) ruled.client.remove_rule { rule = { class = c.class, instance = c.instance }, properties = { - floating = true + floating = true, }, } c.floating = false @@ -391,15 +380,12 @@ return gears.table.join( end end - handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "w") - if not handler then return end - handler:write(json:encode(data_table)) - handler:close() + config.write_json('/home/crylia/.config/awesome/src/config/floating.json', data) capi.mousegrabber.stop() end return true end, - "crosshair" + 'crosshair' ) end ) diff --git a/awesome/src/core/error_handling.lua b/awesome/src/core/error_handling.lua index 01124da..dca877a 100644 --- a/awesome/src/core/error_handling.lua +++ b/awesome/src/core/error_handling.lua @@ -2,33 +2,38 @@ -- This class is to output an error if you fuck up the config -- ---------------------------------------------------------------- -- Awesome Libs -local naughty = require("naughty") +local naughty = require('naughty') +local gfilesystem = require('gears.filesystem') 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 }) + 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", + 'debug::error', function(err) if in_error then return end in_error = true - naughty.notify({ + naughty.notification { preset = naughty.config.presets.critical, - title = "ERROR", - text = tostring(err) - }) + title = 'ERROR', + app_name = 'System Notification', + message = tostring(err), + icon = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg', + } in_error = false end ) diff --git a/awesome/src/core/notifications.lua b/awesome/src/core/notifications.lua index 77c1606..5e2fdc5 100644 --- a/awesome/src/core/notifications.lua +++ b/awesome/src/core/notifications.lua @@ -2,347 +2,331 @@ -- The Notification defaults -- ------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local menubar = require('menubar') -local naughty = require("naughty") -local wibox = require("wibox") -local rubato = require("src.lib.rubato") +local aspawn = require('awful.spawn') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local gshape = require('gears.shape') +local naughty = require('naughty') +local wibox = require('wibox') +local abutton = require('awful.button') +local gtable = require('gears.table') + +local rubato = require('src.lib.rubato') +local hover = require('src.tools.hover') local capi = { client = client, screen = screen, } -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/" +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 = Theme_config.notification.timeout -naughty.config.defaults.title = "System Notification" +naughty.config.defaults.timeout = 5 +naughty.config.defaults.title = 'System Notification' naughty.config.defaults.margin = dpi(10) naughty.config.defaults.position = Theme_config.notification.position -naughty.config.defaults.shape = Theme_config.notification.shape naughty.config.defaults.border_width = Theme_config.notification.border_width naughty.config.defaults.border_color = Theme_config.notification.border_color naughty.config.defaults.spacing = Theme_config.notification.spacing Theme.notification_spacing = Theme_config.notification.corner_spacing -naughty.connect_signal('request::icon', function(n, context, hints) - if context ~= 'app_icon' then - return - end - local path = menubar.utils.lookup_icon(hints.app_icon) or menubar.utils.lookup_icon(hints.app_icon:lower()) - if path then - n.icon = path - end -end) - -naughty.connect_signal("request::display", function(n) +naughty.connect_signal('request::display', function(n) if User_config.dnd then n:destroy() else - if n.urgency == "critical" then - n.title = string.format("%s", - Theme_config.notification.fg_urgent_title, n.title) or "" - n.message = string.format("%s", Theme_config.notification.fg_urgent_message, - n.message) or "" - n.app_name = string.format("%s", Theme_config.notification.fg_urgent_app_name, - n.app_name) or "" - n.bg = Theme_config.notification.bg_urgent - else - n.title = string.format("%s", - Theme_config.notification.fg_normal_title, n.title) or "" - n.message = string.format("%s", Theme_config.notification.fg_normal_message, - n.message) or "" - n.bg = Theme_config.notification.bg_normal - n.timeout = n.timeout or Theme_config.notification.timeout or 3 + 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 + + local color = Theme_config.notification.bg_normal + if n.urgency == 'critical' then + color = Theme_config.notification.fg_urgent_message end - local use_image = false - - if n.app_name == "Spotify" then + if n.app_name == 'Spotify' then n.actions = { naughty.action { - program = "Spotify", - id = "skip-prev", - icon = gears.color.recolor_image(icondir .. "skip-prev.svg", - Theme_config.notification.spotify_button_icon_color) + program = 'Spotify', + id = 'skip-prev', + name = 'Previous', + position = 1, }, naughty.action { - program = "Spotify", - id = "play-pause", - icon = gears.color.recolor_image(icondir .. "play-pause.svg", - Theme_config.notification.spotify_button_icon_color) + program = 'Spotify', + id = 'play-pause', + name = 'Play/Pause', + position = 2, }, naughty.action { - program = "Spotify", - id = "skip-next", - icon = gears.color.recolor_image(icondir .. "skip-next.svg", - Theme_config.notification.spotify_button_icon_color) - } + program = 'Spotify', + id = 'skip-next', + name = 'Next', + position = 3, + }, } - use_image = true + n.resident = true end - local action_template_widget - - if use_image then - action_template_widget = wibox.template { - { - { - { - { - id = "icon_role", - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - id = "centered", - valign = "center", - halign = "center", - widget = wibox.container.place - }, - margins = dpi(5), - widget = wibox.container.margin - }, - forced_height = dpi(35), - forced_width = dpi(35), - bg = Theme_config.notification.action_bg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background, - id = "bgrnd" - }, - id = "mrgn", - top = dpi(10), - bottom = dpi(10), - widget = wibox.container.margin - } - else - action_template_widget = wibox.template { - { - { - { - { - id = "text_role", - font = "JetBrainsMono Nerd Font, Regular 12", - widget = wibox.widget.textbox - }, - id = "centered", - widget = wibox.container.place - }, - margins = dpi(5), - widget = wibox.container.margin - }, - fg = Theme_config.notification.action_fg, - bg = Theme_config.notification.action_bg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background, - id = "bgrnd" - }, - id = "mrgn", - top = dpi(10), - bottom = dpi(10), - widget = wibox.container.margin - } + 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 actions_template = wibox.widget { + local action_template = wibox.widget { notification = n, base_layout = wibox.widget { - spacing = dpi(40), - layout = wibox.layout.fixed.horizontal + 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 = Theme_config.notification.bg, + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, }, - widget_template = action_template_widget, style = { underline_normal = false, - underline_selected = true + underline_selected = false, + shape_normal = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + --Don't remove or it will break + bg_normal = color, + bg_selected = color, + fg_normal = Theme_config.notification.bg, + fg_selected = Theme_config.notification.bg, }, - widget = naughty.list.actions + widget = naughty.list.actions, } - local arc_start = n.timeout + -- 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 - arc_start = 10 + start_timer = 5 end - local w_template = wibox.template { + local notification = wibox.template { widget = wibox.widget { { { { - { + { -- Title { { - { - { - { - { - image = gears.color.recolor_image(icondir .. "notification-outline.svg", - Theme_config.notification.icon_color), - resize = false, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - right = dpi(5), - widget = wibox.container.margin - }, - { - markup = n.app_name or 'System Notification', - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - layout = wibox.layout.fixed.horizontal - }, - fg = Theme_config.notification.fg_appname, - widget = wibox.container.background - }, - margins = dpi(10), - widget = wibox.container.margin - }, - nil, - { - { - { - text = os.date("%H:%M"), - widget = wibox.widget.textbox - }, - id = "background", - fg = Theme_config.notification.fg_time, - widget = wibox.container.background - }, - { + { -- Icon { { { { - font = User_config.font.specify .. ", 10", - text = "✕", - align = "center", - valign = "center", - widget = wibox.widget.textbox + notification = n, + widget = naughty.widget.icon, + image = n.icon, + resize = true, }, - start_angle = 4.71239, - thickness = dpi(2), - min_value = 0, - max_value = arc_start, - value = arc_start, - widget = wibox.container.arcchart, - id = "arc_chart" + widget = wibox.container.background, + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(4)) + end, }, - id = "background1", - fg = Theme_config.notification.fg_close, - bg = Theme_config.notification.bg_close, - widget = wibox.container.background + widget = wibox.container.place, }, - strategy = "exact", + widget = wibox.container.constraint, + strategy = 'exact', width = dpi(20), height = dpi(20), + }, + { -- Title + { + notification = n, + widget = naughty.widget.title, + markup = [[]] .. (n.app_name or + 'Unknown App') .. [[ | ]] .. (n.title or 'System Notification') .. [[]], + halign = 'left', + valign = 'center', + }, widget = wibox.container.constraint, - id = "const1" + width = dpi(430), + height = dpi(35), + strategy = 'max', }, - margins = dpi(10), - widget = wibox.container.margin, - id = "arc_margin" + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, }, - layout = wibox.layout.fixed.horizontal, - id = "arc_app_layout_2" + widget = wibox.container.margin, + left = dpi(10), }, - id = "arc_app_layout", - layout = wibox.layout.align.horizontal - }, - id = "arc_app_bg", - border_color = Theme_config.notification.title_border_color, - border_width = Theme_config.notification.title_border_width, - widget = wibox.container.background - }, - { - { + nil, { { - { - image = n.icon, - resize = true, - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - clip_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 10) - end + { -- Clock + widget = wibox.widget.textclock, + format = '%H:%M', + font = 'JetBrainsMono Nerd Font, Bold 16', + fg = Theme_config.notification.bg, + halign = 'right', + valign = 'center', }, - width = naughty.config.defaults.icon_size, - height = naughty.config.defaults.icon_size, - strategy = "exact", - widget = wibox.container.constraint + { -- Close button + { + { + { + { + widget = wibox.widget.imagebox, + image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.notification.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 = Theme_config.notification.bg_close, + 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, }, - halign = "center", - valign = "top", - widget = wibox.container.place + right = dpi(5), + widget = wibox.container.margin, }, - left = dpi(20), - bottom = dpi(15), - top = dpi(15), - right = dpi(10), - widget = wibox.container.margin + layout = wibox.layout.align.horizontal, + }, + widget = wibox.container.background, + bg = color, + fg = '#212121', + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + }, + { -- 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 = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(10)) + end, + }, + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(128), + width = dpi(128), }, { { - { - widget = naughty.widget.title, - align = "left" - }, - { - widget = naughty.widget.message, - align = "left" - }, - { - actions_template, - widget = wibox.container.place - }, - layout = wibox.layout.fixed.vertical + notification = n, + widget = naughty.widget.message, + font = 'JetBrainsMono Nerd Font, Regular 10', + halign = 'left', + valign = 'center', }, - left = dpi(10), - bottom = dpi(10), - top = dpi(10), - right = dpi(20), - widget = wibox.container.margin + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(128), }, - layout = wibox.layout.fixed.horizontal + spacing = dpi(15), + layout = wibox.layout.fixed.horizontal, }, - id = "widget_layout", - layout = wibox.layout.fixed.vertical + { -- Spacer + { + widget = wibox.container.background, + bg = Theme_config.notification.action_bg, + }, + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(2), + }, + action_template, + spacing = dpi(15), + id = 'main_layout', + layout = wibox.layout.fixed.vertical, }, - id = "min_size", - strategy = "min", - width = dpi(100), - widget = wibox.container.constraint + widget = wibox.container.margin, + margins = dpi(15), }, - id = "max_size", - strategy = "max", - width = Theme.notification_max_width or dpi(500), - widget = wibox.container.constraint + bg = '#212121', + border_color = '#414141', + border_width = dpi(2), + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + widget = wibox.container.background, }, - id = "background", - bg = Theme_config.notification.bg, - border_color = Theme_config.notification.border_color, - border_width = Theme_config.notification.border_width, - shape = Theme_config.notification.shape_inside, - widget = wibox.container.background + widget = wibox.container.constraint, + strategy = 'exact', + width = dpi(600), }, - update_callback = function() - - end } - local close = w_template:get_widget().max_size.min_size.widget_layout.arc_app_bg.arc_app_layout.arc_app_layout_2.arc_margin - .const1.background1 - local arc = close.arc_chart + + 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 @@ -352,45 +336,36 @@ naughty.connect_signal("request::display", function(n) duration = n.timeout, pos = n.timeout, easing = rubato.linear, + clamp_position = true, subscribed = function(value) arc.value = value - end + end, } rubato_timer.target = 0 - w_template:get_widget():connect_signal( - "mouse::enter", - function() - n.timeout = 99999 - rubato_timer.pause = true - end - ) + notification:get_widget():connect_signal('mouse::enter', function() + n.timeout = 99999 + rubato_timer.pause = true + end) - w_template:get_widget():connect_signal( - "mouse::leave", - function() - n.timeout = rubato_timer.pos - rubato_timer.pause = false - rubato_timer.target = 0 - 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_signal(close) + hover.bg_hover { widget = arc_bg } - close:connect_signal("button::press", function() + arc_bg:connect_signal('button::press', function() n:destroy() end) - w_template:get_widget():connect_signal("button::press", function(_, _, _, key) - if key == 3 then - n:destroy() - end - -- Raise the client on click - if key == 1 then + notification:get_widget():buttons { gtable.join( + abutton({}, 1, function() for _, client in ipairs(capi.client.get()) do - if client.name:match(n.app_name) then + 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 @@ -398,44 +373,209 @@ naughty.connect_signal("request::display", function(n) client:raise() end end - end - end) + end), + abutton({}, 3, function() + n:destroy() + end) + ), } local box = naughty.layout.box { notification = n, timeout = 5, - type = "notification", + type = 'notification', screen = capi.screen.primary, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 10) - end, - widget_template = w_template + widget_template = notification, } - box.buttons = {} n.buttons = {} + + -- This is stupid but there is on way to clone the notifaction widget and being able to modify only the clone + --[=[ naughty.emit_signal('notification_surface', wibox.template { + widget = wibox.widget { + { + { + { + { -- Title + { + { + { -- Icon + { + { + { + { + notification = n, + widget = naughty.widget.icon, + --image = n.icon or '', + resize = true, + }, + widget = wibox.container.background, + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(4)) + end, + }, + widget = wibox.container.place, + }, + widget = wibox.container.constraint, + strategy = 'exact', + width = dpi(20), + height = dpi(20), + }, + { -- Title + { + notification = n, + widget = naughty.widget.title, + markup = [[]] .. (n.app_name or + 'Unknown App') .. [[ | ]] .. (n.title or 'System Notification') .. [[]], + halign = 'left', + valign = 'center', + }, + widget = wibox.container.constraint, + width = dpi(280), + height = dpi(35), + strategy = 'max', + }, + spacing = dpi(10), + 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 = Theme_config.notification.bg, + halign = 'right', + valign = 'center', + }, + { -- Close button + { + { + { + { + widget = wibox.widget.imagebox, + image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.notification.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 = Theme_config.notification.bg_close, + 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 = '#212121', + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + }, + { -- Main body + { -- Image + { + { + notification = n, + --image = n.icon or '', + valign = 'center', + halign = 'center', + upscale = true, + resize_strategy = 'scale', + widget = naughty.widget.icon, + }, + widget = wibox.container.background, + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(10)) + end, + }, + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(128), + width = dpi(128), + }, + { + { + notification = n, + widget = naughty.widget.message, + text = n.message, + font = 'JetBrainsMono Nerd Font, Regular 8', + halign = 'left', + valign = 'center', + }, + widget = wibox.container.constraint, + strategy = 'exact', + height = dpi(128), + }, + spacing = dpi(15), + layout = wibox.layout.fixed.horizontal, + }, + }, + widget = wibox.container.margin, + margins = dpi(15), + }, + bg = '#212121', + border_color = '#414141', + border_width = dpi(2), + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + widget = wibox.container.background, + }, + widget = wibox.container.constraint, + strategy = 'exact', + width = dpi(600), + }, + }) ]=] end end) - -naughty.connect_signal( - "destroyed", - function() - end -) - -naughty.connect_signal( - "invoked", - function(_, action) - if action.program == "Spotify" then - if action.id == "skip-prev" then - awful.spawn("playerctl previous") - end - if action.id == "play-pause" then - awful.spawn("playerctl play-pause") - end - if action.id == "skip-next" then - awful.spawn("playerctl next") - end - 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, + }, + }, +} + ]] diff --git a/awesome/src/core/rules.lua b/awesome/src/core/rules.lua index e5aa85e..a5f2f48 100644 --- a/awesome/src/core/rules.lua +++ b/awesome/src/core/rules.lua @@ -3,56 +3,98 @@ ------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") -local beautiful = require("beautiful") -local ruled = require("ruled") +local aclient = require('awful.client') +local aplacement = require('awful.placement') +local ascreen = require('awful.screen') +local ruled = require('ruled') -local json = require("src.lib.json-lua.json-lua") +local config = require('src.tools.config') -awful.rules.rules = { - { +awesome.register_xproperty('_NET_WM_BYPASS_COMPOSITOR', 'boolean') + +ruled.client.connect_signal('request::rules', function() + ruled.client.append_rule { rule = {}, properties = { - border_width = beautiful.border_width, - border_color = beautiful.border_normal, - focus = awful.client.focus.filter, - raise = true, - keys = require("src.bindings.client_keys"), - buttons = require("src.bindings.client_buttons"), - screen = awful.screen.preferred, - placement = awful.placement.under_mouse + awful.placement.no_overlap + awful.placement.no_offscreen + - awful.placement.centered - } - }, - { - id = "titlebar", + border_width = Theme.border_width, + border_color = Theme.border_normal, + 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 = { type = { - "normal", - "dialog", - "modal", - "utility" - } + 'normal', + 'dialog', + }, }, properties = { - titlebars_enabled = true - } + titlebars_enabled = true, + }, } -} -local handler = io.open("/home/crylia/.config/awesome/src/config/floating.json", "r") - -if not handler then return end -local data = json:decode(handler:read("a")) -handler:close() - -if type(data) ~= "table" then return end - -for _, c in ipairs(data) do ruled.client.append_rule { - rule = { class = c.WM_CLASS, instance = c.WM_INSTANCE }, + rule_any = { + class = { + 'proton-bridge', + '1password', + 'protonvpn', + 'Steam', + }, + }, properties = { - floating = true + 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, + } + +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 diff --git a/awesome/src/core/setup.lua b/awesome/src/core/setup.lua index 3d7d24f..75d444c 100644 --- a/awesome/src/core/setup.lua +++ b/awesome/src/core/setup.lua @@ -2,61 +2,62 @@ --- the config files manually. --Awesome Libs -local abutton = require("awful.button") -local aplacement = require("awful.placement") -local apopup = require("awful.popup") -local aspawn = require("awful.spawn") -local atooltip = require("awful.tooltip") -local awidget = require("awful.widget") -local dpi = require("beautiful").xresources.apply_dpi -local gcolor = require("gears.color") -local gtable = require("gears.table") -local wibox = require("wibox") +local abutton = require('awful.button') +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +local aspawn = require('awful.spawn') +local atooltip = require('awful.tooltip') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gtable = require('gears.table') +local wibox = require('wibox') +local gfilesystem = require('gears.filesystem') --Own Libs -local toggle_button = require("awful.widget.toggle_widget") +local toggle_button = require('awful.widget.toggle_widget') 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 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 = {} } local widget_list = { - "Audio", - "Battery", - "Bluetooth", - "Clock", - "Cpu Frequency", - "Cpu Temperature", - "Cpu Usage", - "Date", - "Gpu Temperature", - "Gpu Usage", - "Keyboard Layout", - "Tiling Layout", - "Network", - "Power Button", - "Ram Usage", - "Systray", - "Taglist", - "Tasklist", + 'Audio', + 'Battery', + 'Bluetooth', + 'Clock', + 'Cpu Frequency', + 'Cpu Temperature', + 'Cpu Usage', + 'Date', + 'Gpu Temperature', + 'Gpu Usage', + 'Keyboard Layout', + 'Tiling Layout', + 'Network', + 'Power Button', + 'Ram Usage', + 'Systray', + 'Taglist', + 'Tasklist', } local statusbar_list = { - "Battery", - "Backlight", - "CPU Temp", - "CPU Usage", - "GPU Temp", - "GPU Usage", - "Microphone", - "RAM", - "Volume" + 'Battery', + 'Backlight', + 'CPU Temp', + 'CPU Usage', + 'GPU Temp', + 'GPU Usage', + 'Microphone', + 'RAM', + 'Volume', } --[[ @@ -79,7 +80,7 @@ local function create_pages() table.insert(pages, setup:notification_page()) table.insert(pages, setup:programs_page()) table.insert(pages, setup:layouts_page()) - table.insert(pages, setup:titlebar_page()) + --table.insert(pages, setup:titlebar_page()) table.insert(pages, setup:font_page()) table.insert(pages, setup:final_page()) return pages @@ -95,52 +96,51 @@ function setup:welcome_page() { { widget = wibox.widget.textbox, - markup = "Welcome to Crylia-Theme", - font = "Raleway Bold 36", - halign = "left", - valign = "center" + markup = 'Welcome to Crylia-Theme', + font = 'Raleway Bold 36', + halign = 'left', + valign = 'center', }, { widget = wibox.widget.textbox, - markup = "Thank you for downloading Crylia-Theme, a beautiful and customizable config for AwesomeWM", - font = "Comforta Regular 28", - halign = "left", - valign = "center" + markup = 'Thank you for downloading Crylia-Theme, a beautiful and customizable config for AwesomeWM', + font = 'Comforta Regular 28', + halign = 'left', + valign = 'center', }, spacing = dpi(40), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.margin, left = dpi(50), }, widget = wibox.container.place, - valign = "center" + valign = 'center', }, widget = wibox.container.constraint, width = dpi((capi.screen.primary.geometry.width * 0.6) / 2), - strategy = "exact", + strategy = 'exact', }, { -- Right side with image { { widget = wibox.widget.imagebox, - image = "/home/crylia/Bilder/57384097.jpg", + image = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg', resize = true, - valign = "center", - halign = "center" + valign = 'center', + halign = 'center', }, - widget = wibox.container.constraint, - width = dpi((capi.screen.primary.geometry.width * 0.6) / 8), - strategy = "exact", + widget = wibox.container.margin, + margins = dpi(50), }, forced_width = dpi((capi.screen.primary.geometry.width * 0.6) / 2), - widget = wibox.container.place + widget = wibox.container.place, }, layout = wibox.layout.fixed.horizontal, }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } end @@ -148,10 +148,10 @@ end function setup:wallpaper_page() local path_promt = awidget.inputbox { - hint_text = "Path to image...", - halign = "left", - valign = "center", - font = "JetBrainsMono Regular 12", + hint_text = 'Path to image...', + halign = 'left', + valign = 'center', + font = 'JetBrainsMono Regular 12', } local widget = wibox.widget { @@ -161,16 +161,16 @@ function setup:wallpaper_page() { widget = wibox.widget.imagebox, resize = true, - image = assets_dir .. "space.jpg", - valign = "center", - halign = "center", + image = assets_dir .. 'space.jpg', + valign = 'center', + halign = 'center', clip_shape = Theme_config.setup.wallpaper.clip_shape, - id = "wallpaper" + id = 'wallpaper', }, widget = wibox.container.constraint, width = dpi(600), height = dpi(600 * 9 / 16), - strategy = "exact", + strategy = 'exact', }, { -- Button { @@ -180,42 +180,42 @@ function setup:wallpaper_page() { { widget = wibox.widget.imagebox, - image = icon_dir .. "choose.svg", - valign = "center", - halign = "center", - resize = true + image = icon_dir .. 'choose.svg', + valign = 'center', + halign = 'center', + resize = true, }, widget = wibox.container.constraint, width = dpi(36), height = dpi(36), - strategy = "exact" + strategy = 'exact', }, widget = wibox.container.margin, left = dpi(10), }, { widget = wibox.widget.textbox, - markup = "Choose Wallpaper", - halign = "center", - valign = "center" + markup = 'Choose Wallpaper', + halign = 'center', + valign = 'center', }, spacing = dpi(20), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, widget = wibox.container.background, bg = Theme_config.setup.wallpaper.button_bg, fg = Theme_config.setup.wallpaper.button_fg, shape = Theme_config.setup.wallpaper.button_shape, - id = "choose_image" + id = 'choose_image', }, widget = wibox.container.constraint, width = dpi(300), height = dpi(60), - strategy = "exact" + strategy = 'exact', }, - valign = "center", - halign = "center", - widget = wibox.container.place + valign = 'center', + halign = 'center', + widget = wibox.container.place, }, { -- Path { @@ -227,24 +227,24 @@ function setup:wallpaper_page() widget = wibox.container.constraint, width = dpi(600), height = dpi(50), - strategy = "exact" + strategy = 'exact', }, widget = wibox.container.place, - halign = "center", - valign = "center", + halign = 'center', + valign = 'center', }, { -- Button { widget = wibox.widget.imagebox, - image = icon_dir .. "close.svg", + image = icon_dir .. 'close.svg', rezise = true, - id = "close" + id = 'close', }, widget = wibox.container.background, bg = gcolor.transparent, fg = Theme_config.setup.wallpaper.close_fg, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.background, bg = Theme_config.setup.wallpaper.path_bg, @@ -254,36 +254,36 @@ function setup:wallpaper_page() widget = wibox.container.constraint, width = dpi(600), height = dpi(50), - strategy = "exact" + strategy = 'exact', }, spacing = dpi(28), layout = wibox.layout.fixed.vertical, }, widget = wibox.container.place, - halign = "center", - valign = "center", + halign = 'center', + valign = 'center', }, widget = wibox.container.constraint, width = (capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } --Wallpaper - local wallpaper = widget:get_children_by_id("wallpaper")[1] + local wallpaper = widget:get_children_by_id('wallpaper')[1] --Choose Image button - local choose_image_button = widget:get_children_by_id("choose_image")[1] + local choose_image_button = widget:get_children_by_id('choose_image')[1] --Close button - local close_button = widget:get_children_by_id("close")[1] + local close_button = widget:get_children_by_id('close')[1] choose_image_button:buttons(gtable.join( abutton({}, 1, function() aspawn.easy_async_with_shell( "zenity --file-selection --title='Select an Image File' --file-filter='Image File | *.jpg *.png'", function(stdout) - stdout = stdout:gsub("\n", "") - if stdout ~= "" then + stdout = stdout:gsub('\n', '') + if stdout ~= '' then wallpaper:set_image(stdout) path_promt:set_text(stdout) self.wallpaper = stdout @@ -294,13 +294,11 @@ function setup:wallpaper_page() close_button:buttons(gtable.join( abutton({}, 1, function() - path_promt:set_text("") + path_promt:set_text('') wallpaper:set_image(nil) end) )) - Hover_signal(choose_image_button) - return widget end @@ -321,9 +319,9 @@ local function get_widgets() { widget = wibox.widget.textbox, text = widget, - halign = "left", - valign = "center", - font = User_config.font.specify .. " Regular, 10" + halign = 'left', + valign = 'center', + font = User_config.font.specify .. ' Regular, 10', }, widget = wibox.container.margin, margins = dpi(5), @@ -333,15 +331,15 @@ local function get_widgets() fg = Theme_config.setup.bar.widget_fg, shape = Theme_config.setup.bar.widget_shape, border_color = Theme_config.setup.bar.widget_border_color, - border_width = Theme_config.setup.bar.widget_border_width + border_width = Theme_config.setup.bar.widget_border_width, }, { tb, widget = wibox.container.margin, left = dpi(10), }, - id = "toggle_button", - layout = wibox.layout.align.horizontal + id = 'toggle_button', + layout = wibox.layout.align.horizontal, } table.insert(widgets, w) @@ -358,12 +356,12 @@ function setup:bar_page() { -- Title { widget = wibox.widget.textbox, - text = "Top Bar", - halign = "center", - valign = "center", + text = 'Top Bar', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, { -- Bar preview { @@ -372,7 +370,7 @@ function setup:bar_page() { widget = wibox.widget.checkbox, checked = true, - id = "topbar_checkbox", + id = 'topbar_checkbox', shape = Theme_config.setup.bar.shape, color = Theme_config.setup.bar.color, padding = Theme_config.setup.bar.padding, @@ -380,27 +378,27 @@ function setup:bar_page() widget = wibox.container.constraint, width = 30, height = 30, - strategy = "exact" + strategy = 'exact', }, widget = wibox.container.place, - halign = "right", - valign = "center" + halign = 'right', + valign = 'center', }, { { widget = wibox.widget.imagebox, - image = "/home/crylia/Downloads/2022-12-08_23-19.png", --icon_dir .. "topbar.svg", + image = '/home/crylia/Downloads/2022-12-08_23-19.png', --icon_dir .. "topbar.svg", resize = true, clip_shape = Theme_config.setup.bar.bar_image_shape, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact" + strategy = 'exact', }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, widget = wibox.container.margin, left = dpi(70), @@ -414,16 +412,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Left Widgets", - halign = "center", - valign = "center", + text = 'Left Widgets', + halign = 'center', + valign = 'center', }, { - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "left_top_widget_selector", + id = 'left_top_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -441,16 +439,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Center Widgets", - halign = "center", - valign = "center", + text = 'Center Widgets', + halign = 'center', + valign = 'center', }, { - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "center_top_widget_selector", + id = 'center_top_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -468,16 +466,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Right Widgets", - halign = "center", - valign = "center", + text = 'Right Widgets', + halign = 'center', + valign = 'center', }, { - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "right_top_widget_selector", + id = 'right_top_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -490,27 +488,27 @@ function setup:bar_page() border_width = Theme_config.setup.bar.border_width, shape = Theme_config.setup.bar.bar_shape, }, - expand = "none", + expand = 'none', forced_width = dpi(capi.screen.primary.geometry.width * 0.6) * 0.4, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.constraint, height = dpi(capi.screen.primary.geometry.width * 0.6 * 9 / 16) * 0.3, - strategy = "exact", + strategy = 'exact', }, widget = wibox.container.margin, left = dpi(140), right = dpi(140), }, spacing = dpi(20), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, { widget = wibox.container.background, bg = gcolor.transparent, - id = "top_overlay" + id = 'top_overlay', }, - layout = wibox.layout.stack + layout = wibox.layout.stack, }, { { -- Bottom bar @@ -522,16 +520,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Left Widgets", - halign = "center", - valign = "center", + text = 'Left Widgets', + halign = 'center', + valign = 'center', }, { - widget = require("src.lib.overflow_widget.overflow").vertical, + widget = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "left_bottom_widget_selector", + id = 'left_bottom_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -549,16 +547,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Center Widgets", - halign = "center", - valign = "center", + text = 'Center Widgets', + halign = 'center', + valign = 'center', }, { - widget = require("src.lib.overflow_widget.overflow").vertical, + widget = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "center_bottom_widget_selector", + id = 'center_bottom_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -576,16 +574,16 @@ function setup:bar_page() { { widget = wibox.widget.textbox, - text = "Right Widgets", - halign = "center", - valign = "center", + text = 'Right Widgets', + halign = 'center', + valign = 'center', }, { - widget = require("src.lib.overflow_widget.overflow").vertical, + widget = require('src.lib.overflow_widget.overflow').vertical, spacing = dpi(10), step = dpi(50), scrollbar_width = 0, - id = "right_bottom_widget_selector", + id = 'right_bottom_widget_selector', }, spacing = dpi(10), layout = wibox.layout.fixed.vertical, @@ -598,13 +596,13 @@ function setup:bar_page() border_width = Theme_config.setup.bar.border_width, shape = Theme_config.setup.bar.bar_shape, }, - expand = "none", + expand = 'none', forced_width = dpi(capi.screen.primary.geometry.width * 0.6) * 0.4, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.constraint, height = dpi(capi.screen.primary.geometry.width * 0.6 * 9 / 16) * 0.3, - strategy = "exact", + strategy = 'exact', }, widget = wibox.container.margin, left = dpi(140), @@ -617,7 +615,7 @@ function setup:bar_page() { widget = wibox.widget.checkbox, checked = false, - id = "bottombar_checkbox", + id = 'bottombar_checkbox', shape = Theme_config.setup.bar.shape, color = Theme_config.setup.bar.color, padding = Theme_config.setup.bar.padding, @@ -625,27 +623,27 @@ function setup:bar_page() widget = wibox.container.constraint, width = 30, height = 30, - strategy = "exact" + strategy = 'exact', }, widget = wibox.container.place, - halign = "right", - valign = "center" + halign = 'right', + valign = 'center', }, { { widget = wibox.widget.imagebox, - image = "/home/crylia/Downloads/2022-12-08_23-19.png", --icon_dir .. "topbar.svg", + image = '/home/crylia/Downloads/2022-12-08_23-19.png', --icon_dir .. "topbar.svg", resize = true, clip_shape = Theme_config.setup.bar.bar_image_shape, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact" + strategy = 'exact', }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, widget = wibox.container.margin, left = dpi(70), @@ -654,34 +652,34 @@ function setup:bar_page() { -- Title { widget = wibox.widget.textbox, - text = "Bottom Bar", - halign = "center", - valign = "center", + text = 'Bottom Bar', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, spacing = dpi(20), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, { widget = wibox.container.background, - bg = gcolor("#212121BB"), - id = "bottom_overlay" + bg = gcolor('#212121BB'), + id = 'bottom_overlay', }, - layout = wibox.layout.stack + layout = wibox.layout.stack, }, spacing_widget = wibox.widget.separator, spacing = dpi(5), forced_width = dpi(capi.screen.primary.geometry.width * 0.6), - layout = wibox.layout.flex.vertical + layout = wibox.layout.flex.vertical, } - local top_checkbox, bottom_checkbox = widget:get_children_by_id("topbar_checkbox")[1], - widget:get_children_by_id("bottombar_checkbox")[1] + local top_checkbox, bottom_checkbox = widget:get_children_by_id('topbar_checkbox')[1], + widget:get_children_by_id('bottombar_checkbox')[1] - local top_overlay, bottom_overlay = widget:get_children_by_id("top_overlay")[1], - widget:get_children_by_id("bottom_overlay")[1] + local top_overlay, bottom_overlay = widget:get_children_by_id('top_overlay')[1], + widget:get_children_by_id('bottom_overlay')[1] top_checkbox:buttons(gtable.join( abutton({}, 1, nil, function() @@ -689,9 +687,9 @@ function setup:bar_page() bottom_checkbox.checked = not top_checkbox.checked if top_checkbox.checked then top_overlay.bg = gcolor.transparent - bottom_overlay.bg = gcolor("#212121BB") + bottom_overlay.bg = gcolor('#212121BB') else - top_overlay.bg = gcolor("#212121BB") + top_overlay.bg = gcolor('#212121BB') bottom_overlay.bg = gcolor.transparent end end @@ -703,22 +701,22 @@ function setup:bar_page() bottom_checkbox.checked = not bottom_checkbox.checked top_checkbox.checked = not bottom_checkbox.checked if bottom_checkbox.checked then - top_overlay.bg = gcolor("#212121BB") + top_overlay.bg = gcolor('#212121BB') bottom_overlay.bg = gcolor.transparent else top_overlay.bg = gcolor.transparent - bottom_overlay.bg = gcolor("#212121BB") + bottom_overlay.bg = gcolor('#212121BB') end end ) )) - widget:get_children_by_id("left_top_widget_selector")[1].children = get_widgets() - widget:get_children_by_id("center_top_widget_selector")[1].children = get_widgets() - widget:get_children_by_id("right_top_widget_selector")[1].children = get_widgets() - widget:get_children_by_id("left_bottom_widget_selector")[1].children = get_widgets() - widget:get_children_by_id("center_bottom_widget_selector")[1].children = get_widgets() - widget:get_children_by_id("right_bottom_widget_selector")[1].children = get_widgets() + widget:get_children_by_id('left_top_widget_selector')[1].children = get_widgets() + widget:get_children_by_id('center_top_widget_selector')[1].children = get_widgets() + widget:get_children_by_id('right_top_widget_selector')[1].children = get_widgets() + widget:get_children_by_id('left_bottom_widget_selector')[1].children = get_widgets() + widget:get_children_by_id('center_bottom_widget_selector')[1].children = get_widgets() + widget:get_children_by_id('right_bottom_widget_selector')[1].children = get_widgets() return widget @@ -728,8 +726,8 @@ local function get_status_bars() local widgets = wibox.widget { layout = wibox.layout.flex.horizontal, spacing = dpi(100), - { layout = wibox.layout.fixed.vertical, id = "left", spacing = dpi(10) }, - { layout = wibox.layout.fixed.vertical, id = "right", spacing = dpi(10) } + { layout = wibox.layout.fixed.vertical, id = 'left', spacing = dpi(10) }, + { layout = wibox.layout.fixed.vertical, id = 'right', spacing = dpi(10) }, } for i, widget in pairs(statusbar_list) do @@ -744,9 +742,9 @@ local function get_status_bars() { widget = wibox.widget.textbox, text = widget, - halign = "left", - valign = "center", - font = User_config.font.specify .. " Regular, 14" + halign = 'left', + valign = 'center', + font = User_config.font.specify .. ' Regular, 14', }, widget = wibox.container.margin, margins = dpi(5), @@ -756,13 +754,13 @@ local function get_status_bars() widget = wibox.container.margin, left = dpi(10), }, - id = "toggle_button", - layout = wibox.layout.align.horizontal + id = 'toggle_button', + layout = wibox.layout.align.horizontal, } if i <= math.ceil(#statusbar_list / 2) then - widgets:get_children_by_id("left")[1]:add(w) + widgets:get_children_by_id('left')[1]:add(w) else - widgets:get_children_by_id("right")[1]:add(w) + widgets:get_children_by_id('right')[1]:add(w) end end @@ -773,15 +771,15 @@ end function setup:notification_page() local secrets = { api_key = awidget.inputbox { - hint_text = "API Key...", - valign = "center", - halign = "left" + hint_text = 'API Key...', + valign = 'center', + halign = 'left', }, city_id = awidget.inputbox { - hint_text = "City ID...", - valign = "center", - halign = "left" - } + hint_text = 'City ID...', + valign = 'center', + halign = 'left', + }, } local widget = wibox.widget { @@ -789,55 +787,55 @@ function setup:notification_page() { { widget = wibox.widget.textbox, - text = "Notification Center Setup", - font = User_config.font.specify .. " Regular, 24", - halign = "center", - valign = "center", + text = 'Notification Center Setup', + font = User_config.font.specify .. ' Regular, 24', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, { { -- Status bars { -- Title { widget = wibox.widget.textbox, - text = "Status bars", - font = User_config.font.specify .. " Regular, 16", - halign = "center", + text = 'Status bars', + font = User_config.font.specify .. ' Regular, 16', + halign = 'center', }, widget = wibox.container.margin, top = dpi(5), - bottom = dpi(100) + bottom = dpi(100), }, { { -- Icon widget = wibox.widget.imagebox, - image = icon_dir .. "status_bars.png", + image = icon_dir .. 'status_bars.png', resize = false, forced_width = dpi(250), - halign = "center", - id = "sb_icon" + halign = 'center', + id = 'sb_icon', }, { get_status_bars(), widget = wibox.container.margin, left = dpi(100), - right = dpi(100) + right = dpi(100), }, - expand = "none", - layout = wibox.layout.flex.vertical + expand = 'none', + layout = wibox.layout.flex.vertical, }, nil, - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, { -- OpenWeatherMap API { -- Title { widget = wibox.widget.textbox, - text = "OpenWeatherMap API", - font = User_config.font.specify .. " Regular, 16", - halign = "center", + text = 'OpenWeatherMap API', + font = User_config.font.specify .. ' Regular, 16', + halign = 'center', }, widget = wibox.container.margin, top = dpi(5), @@ -847,24 +845,24 @@ function setup:notification_page() { -- Icon { widget = wibox.widget.imagebox, - image = icon_dir .. "openweathermap.png", + image = icon_dir .. 'openweathermap.png', resize = true, - halign = "center", - id = "opw_icon" + halign = 'center', + id = 'opw_icon', }, widget = wibox.container.constraint, width = dpi(250), - strategy = "exact" + strategy = 'exact', }, { -- Secrets { -- API Key { { widget = wibox.widget.textbox, - text = "API Key", - font = User_config.font.specify .. " Regular, 16", - halign = "center", - valign = "center", + text = 'API Key', + font = User_config.font.specify .. ' Regular, 16', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -873,9 +871,9 @@ function setup:notification_page() { secrets.api_key, widget = wibox.container.margin, - left = dpi(10) + left = dpi(10), }, - id = "api_key_input", + id = 'api_key_input', forced_height = dpi(50), forced_width = dpi(400), widget = wibox.container.background, @@ -883,16 +881,16 @@ function setup:notification_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, { -- City ID { { widget = wibox.widget.textbox, - text = "City ID", - font = User_config.font.specify .. " Regular, 16", - halign = "center", - valign = "center", + text = 'City ID', + font = User_config.font.specify .. ' Regular, 16', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -903,7 +901,7 @@ function setup:notification_page() widget = wibox.container.margin, left = dpi(10), }, - id = "city_id_input", + id = 'city_id_input', forced_height = dpi(50), forced_width = dpi(400), widget = wibox.container.background, @@ -911,7 +909,7 @@ function setup:notification_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, spacing = dpi(40), layout = wibox.layout.flex.vertical, @@ -926,25 +924,25 @@ function setup:notification_page() color = Theme_config.setup.notification.checkbox_color, paddings = Theme_config.setup.notification.checkbox_paddings, shape = Theme_config.setup.notification.checkbox_shape, - id = "celsius_selector", + id = 'celsius_selector', }, widget = wibox.container.constraint, width = dpi(24), height = dpi(24), }, widget = wibox.container.place, - halign = "center", - valign = "center", + halign = 'center', + valign = 'center', }, { widget = wibox.widget.textbox, - text = "Celsius °C", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Celsius °C', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, spacing = dpi(10), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, { -- Fahrenheit { @@ -955,34 +953,34 @@ function setup:notification_page() color = Theme_config.setup.notification.checkbox_color, paddings = Theme_config.setup.notification.checkbox_paddings, shape = Theme_config.setup.notification.checkbox_shape, - id = "Fahrenheit_selector", + id = 'Fahrenheit_selector', }, widget = wibox.container.constraint, width = dpi(24), - height = dpi(24) + height = dpi(24), }, widget = wibox.container.place, - halign = "center", - valign = "center", + halign = 'center', + valign = 'center', }, { widget = wibox.widget.textbox, - text = "Fahrenheit °F", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Fahrenheit °F', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, spacing = dpi(10), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - layout = wibox.layout.flex.horizontal + layout = wibox.layout.flex.horizontal, }, spacing = dpi(100), layout = wibox.layout.fixed.vertical, }, widget = wibox.container.place, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, nil, layout = wibox.layout.align.vertical, @@ -994,16 +992,16 @@ function setup:notification_page() layout = wibox.layout.flex.horizontal, }, nil, - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } -- Toggle both checkboxes so they act as radio buttons - local celsius_selector = widget:get_children_by_id("celsius_selector")[1] - local fahrenheit_selector = widget:get_children_by_id("Fahrenheit_selector")[1] + local celsius_selector = widget:get_children_by_id('celsius_selector')[1] + local fahrenheit_selector = widget:get_children_by_id('Fahrenheit_selector')[1] celsius_selector:buttons(gtable.join( abutton({}, 1, nil, function() celsius_selector.checked = true @@ -1017,15 +1015,15 @@ function setup:notification_page() end) )) - local opw_icon = widget:get_children_by_id("opw_icon")[1] + local opw_icon = widget:get_children_by_id('opw_icon')[1] opw_icon:buttons(gtable.join( abutton({}, 1, nil, function() - aspawn.with_shell("xdg-open https://openweathermap.org/") + aspawn.with_shell('xdg-open https://openweathermap.org/') end) )) - local api_key_input = widget:get_children_by_id("api_key_input")[1] - local city_id_input = widget:get_children_by_id("city_id_input")[1] + local api_key_input = widget:get_children_by_id('api_key_input')[1] + local city_id_input = widget:get_children_by_id('city_id_input')[1] api_key_input:buttons(gtable.join( abutton({}, 1, nil, function() secrets.api_key:focus() @@ -1055,16 +1053,16 @@ function setup:notification_page() end end - api_key_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - api_key_input:connect_signal("mouse::leave", mouse_leave) - city_id_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - city_id_input:connect_signal("mouse::leave", mouse_leave) - opw_icon:connect_signal("mouse::enter", function() mouse_enter("hand1") end) - opw_icon:connect_signal("mouse::leave", mouse_leave) - celsius_selector:connect_signal("mouse::enter", function() mouse_enter("hand1") end) - celsius_selector:connect_signal("mouse::leave", mouse_leave) - fahrenheit_selector:connect_signal("mouse::enter", function() mouse_enter("hand1") end) - fahrenheit_selector:connect_signal("mouse::leave", mouse_leave) + api_key_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + api_key_input:connect_signal('mouse::leave', mouse_leave) + city_id_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + city_id_input:connect_signal('mouse::leave', mouse_leave) + opw_icon:connect_signal('mouse::enter', function() mouse_enter('hand1') end) + opw_icon:connect_signal('mouse::leave', mouse_leave) + celsius_selector:connect_signal('mouse::enter', function() mouse_enter('hand1') end) + celsius_selector:connect_signal('mouse::leave', mouse_leave) + fahrenheit_selector:connect_signal('mouse::enter', function() mouse_enter('hand1') end) + fahrenheit_selector:connect_signal('mouse::leave', mouse_leave) --#endregion @@ -1074,14 +1072,14 @@ end --- The fifth page, to customize the default programs function setup:programs_page() local applications = { - power_manager = awidget.inputbox { hint_text = "e.g. xfce4-power-manager-settings" }, - web_browser = awidget.inputbox { hint_text = "e.g. firefox" }, - terminal = awidget.inputbox { hint_text = "e.g. kitty" }, - text_editor = awidget.inputbox { hint_text = "e.g. code" }, - music_player = awidget.inputbox { hint_text = "e.g. flatpak run com.spotify.Client" }, - gtk_settings = awidget.inputbox { hint_text = "e.g. lxappearance" }, - file_manager = awidget.inputbox { hint_text = "e.g. nautilus" }, - screen_manager = awidget.inputbox { hint_text = "e.g. arandr" } + power_manager = awidget.inputbox { hint_text = 'e.g. xfce4-power-manager-settings' }, + web_browser = awidget.inputbox { hint_text = 'e.g. firefox' }, + terminal = awidget.inputbox { hint_text = 'e.g. kitty' }, + text_editor = awidget.inputbox { hint_text = 'e.g. code' }, + music_player = awidget.inputbox { hint_text = 'e.g. flatpak run com.spotify.Client' }, + gtk_settings = awidget.inputbox { hint_text = 'e.g. lxappearance' }, + file_manager = awidget.inputbox { hint_text = 'e.g. nautilus' }, + screen_manager = awidget.inputbox { hint_text = 'e.g. arandr' }, } local widget = wibox.widget { @@ -1089,13 +1087,13 @@ function setup:programs_page() { -- Title { widget = wibox.widget.textbox, - text = "Default Applications", - font = User_config.font.specify .. " Regular, 24", - halign = "center", - valign = "center", + text = 'Default Applications', + font = User_config.font.specify .. ' Regular, 24', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, { { -- Left side Applications @@ -1104,10 +1102,10 @@ function setup:programs_page() { { widget = wibox.widget.textbox, - text = "Power Manager", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Power Manager', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1117,9 +1115,9 @@ function setup:programs_page() { applications.power_manager, widget = wibox.container.margin, - left = dpi(10) + left = dpi(10), }, - id = "power_manager_input", + id = 'power_manager_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1127,17 +1125,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- web_browser { { widget = wibox.widget.textbox, - text = "Web Browser", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Web Browser', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1149,7 +1147,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "web_browser_input", + id = 'web_browser_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1157,17 +1155,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- terminal { { widget = wibox.widget.textbox, - text = "Terminal", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Terminal', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1179,7 +1177,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "terminal_input", + id = 'terminal_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1187,17 +1185,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- text_editor { { widget = wibox.widget.textbox, - text = "Text Editor", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Text Editor', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1209,7 +1207,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "text_editor_input", + id = 'text_editor_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1217,15 +1215,15 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, spacing = dpi(40), layout = wibox.layout.fixed.vertical, }, widget = wibox.container.place, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, { -- Right side Applications { @@ -1233,10 +1231,10 @@ function setup:programs_page() { { widget = wibox.widget.textbox, - text = "Music Player", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Music Player', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1246,9 +1244,9 @@ function setup:programs_page() { applications.music_player, widget = wibox.container.margin, - left = dpi(10) + left = dpi(10), }, - id = "music_player_input", + id = 'music_player_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1256,17 +1254,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- gtk settings { { widget = wibox.widget.textbox, - text = "GTK Settings", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'GTK Settings', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1278,7 +1276,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "gtk_settings_input", + id = 'gtk_settings_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1286,17 +1284,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- file manager { { widget = wibox.widget.textbox, - text = "File Manager", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'File Manager', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1308,7 +1306,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "file_manager_input", + id = 'file_manager_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1316,17 +1314,17 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, { -- Screen Manager { { widget = wibox.widget.textbox, - text = "Screen Manager", - font = User_config.font.specify .. " Regular, 14", - halign = "center", - valign = "center", + text = 'Screen Manager', + font = User_config.font.specify .. ' Regular, 14', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, right = dpi(20), @@ -1338,7 +1336,7 @@ function setup:programs_page() widget = wibox.container.margin, left = dpi(10), }, - id = "screen_manager_input", + id = 'screen_manager_input', forced_height = dpi(50), forced_width = dpi(350), widget = wibox.container.background, @@ -1346,74 +1344,74 @@ function setup:programs_page() border_width = Theme_config.setup.notification.border_width, shape = Theme_config.setup.notification.shape, }, - expand = "none", - layout = wibox.layout.align.horizontal + expand = 'none', + layout = wibox.layout.align.horizontal, }, spacing = dpi(40), layout = wibox.layout.fixed.vertical, }, widget = wibox.container.place, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, - layout = wibox.layout.flex.horizontal + layout = wibox.layout.flex.horizontal, }, nil, - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } - local power_manager_input = widget:get_children_by_id("power_manager_input")[1] - local web_browser_input = widget:get_children_by_id("web_browser_input")[1] - local terminal_input = widget:get_children_by_id("terminal_input")[1] - local text_editor_input = widget:get_children_by_id("text_editor_input")[1] - local music_player_input = widget:get_children_by_id("music_player_input")[1] - local gtk_settings_input = widget:get_children_by_id("gtk_settings_input")[1] - local file_manager_input = widget:get_children_by_id("file_manager_input")[1] - local screen_manager_input = widget:get_children_by_id("screen_manager_input")[1] + local power_manager_input = widget:get_children_by_id('power_manager_input')[1] + local web_browser_input = widget:get_children_by_id('web_browser_input')[1] + local terminal_input = widget:get_children_by_id('terminal_input')[1] + local text_editor_input = widget:get_children_by_id('text_editor_input')[1] + local music_player_input = widget:get_children_by_id('music_player_input')[1] + local gtk_settings_input = widget:get_children_by_id('gtk_settings_input')[1] + local file_manager_input = widget:get_children_by_id('file_manager_input')[1] + local screen_manager_input = widget:get_children_by_id('screen_manager_input')[1] applications.power_manager:buttons(gtable.join { abutton({}, 1, function() applications.power_manager:focus() - end) + end), }) applications.web_browser:buttons(gtable.join { abutton({}, 1, function() applications.web_browser:focus() - end) + end), }) applications.terminal:buttons(gtable.join { abutton({}, 1, function() applications.terminal:focus() - end) + end), }) applications.text_editor:buttons(gtable.join { abutton({}, 1, function() applications.text_editor:focus() - end) + end), }) applications.music_player:buttons(gtable.join { abutton({}, 1, function() applications.music_player:focus() - end) + end), }) applications.gtk_settings:buttons(gtable.join { abutton({}, 1, function() applications.gtk_settings:focus() - end) + end), }) applications.file_manager:buttons(gtable.join { abutton({}, 1, function() applications.file_manager:focus() - end) + end), }) applications.screen_manager:buttons(gtable.join { abutton({}, 1, function() applications.screen_manager:focus() - end) + end), }) --#region Mouse changes @@ -1433,22 +1431,22 @@ function setup:programs_page() end end - power_manager_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - power_manager_input:connect_signal("mouse::leave", mouse_leave) - web_browser_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - web_browser_input:connect_signal("mouse::leave", mouse_leave) - terminal_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - terminal_input:connect_signal("mouse::leave", mouse_leave) - text_editor_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - text_editor_input:connect_signal("mouse::leave", mouse_leave) - music_player_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - music_player_input:connect_signal("mouse::leave", mouse_leave) - gtk_settings_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - gtk_settings_input:connect_signal("mouse::leave", mouse_leave) - file_manager_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - file_manager_input:connect_signal("mouse::leave", mouse_leave) - screen_manager_input:connect_signal("mouse::enter", function() mouse_enter("xterm") end) - screen_manager_input:connect_signal("mouse::leave", mouse_leave) + power_manager_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + power_manager_input:connect_signal('mouse::leave', mouse_leave) + web_browser_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + web_browser_input:connect_signal('mouse::leave', mouse_leave) + terminal_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + terminal_input:connect_signal('mouse::leave', mouse_leave) + text_editor_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + text_editor_input:connect_signal('mouse::leave', mouse_leave) + music_player_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + music_player_input:connect_signal('mouse::leave', mouse_leave) + gtk_settings_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + gtk_settings_input:connect_signal('mouse::leave', mouse_leave) + file_manager_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + file_manager_input:connect_signal('mouse::leave', mouse_leave) + screen_manager_input:connect_signal('mouse::enter', function() mouse_enter('xterm') end) + screen_manager_input:connect_signal('mouse::leave', mouse_leave) --#endregion @@ -1457,22 +1455,22 @@ end local function get_layouts() local layouts = { - ["cornerne"] = Theme.layout_cornerne, - ["cornernw"] = Theme.layout_cornernw, - ["cornerse"] = Theme.layout_cornerse, - ["cornersw"] = Theme.layout_cornersw, - ["dwindle"] = Theme.layout_dwindle, - ["fairh"] = Theme.layout_fairh, - ["fairv"] = Theme.layout_fairv, - ["floating"] = Theme.layout_floating, - ["fullscreen"] = Theme.layout_fullscreen, - ["magnifier"] = Theme.layout_magnifier, - ["max"] = Theme.layout_max, - ["spiral"] = Theme.layout_spiral, - ["tile bottom"] = Theme.layout_cornerse, - ["tile left"] = Theme.layout_cornernw, - ["tile top"] = Theme.layout_cornersw, - ["tile"] = Theme.layout_cornerne, + ['cornerne'] = Theme.layout_cornerne, + ['cornernw'] = Theme.layout_cornernw, + ['cornerse'] = Theme.layout_cornerse, + ['cornersw'] = Theme.layout_cornersw, + ['dwindle'] = Theme.layout_dwindle, + ['fairh'] = Theme.layout_fairh, + ['fairv'] = Theme.layout_fairv, + ['floating'] = Theme.layout_floating, + ['fullscreen'] = Theme.layout_fullscreen, + ['magnifier'] = Theme.layout_magnifier, + ['max'] = Theme.layout_max, + ['spiral'] = Theme.layout_spiral, + ['tile bottom'] = Theme.layout_cornerse, + ['tile left'] = Theme.layout_cornernw, + ['tile top'] = Theme.layout_cornersw, + ['tile'] = Theme.layout_cornerne, } local list = {} @@ -1490,23 +1488,23 @@ local function get_layouts() }, widget = wibox.container.constraint, width = dpi(64), - height = dpi(64) + height = dpi(64), }, margins = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.setup.layout.bg, shape = Theme_config.setup.layout.shape, - widget = wibox.container.background + widget = wibox.container.background, }, margins = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, border_color = Theme_config.setup.layout.border_color, border_width = Theme_config.setup.layout.border_width, shape = Theme_config.setup.layout.shape, - selected = false + selected = false, } w:buttons(gtable.join { @@ -1518,16 +1516,16 @@ local function get_layouts() w.border_color = Theme_config.setup.layout.border_color_selected w.selected = true end - end) + end), }) atooltip { objects = { w }, - mode = "inside", - align = "bottom", + mode = 'inside', + align = 'bottom', timeout = 0.5, text = layout, - preferred_positions = { "right", "left", "top", "bottom" }, + preferred_positions = { 'right', 'left', 'top', 'bottom' }, margin_leftright = dpi(8), margin_topbottom = dpi(8), } @@ -1547,13 +1545,13 @@ function setup:layouts_page() { -- Title { widget = wibox.widget.textbox, - text = "Layouts", - font = User_config.font.specify .. " Regular, 24", - halign = "center", - valign = "center", + text = 'Layouts', + font = User_config.font.specify .. ' Regular, 24', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, { { @@ -1563,21 +1561,21 @@ function setup:layouts_page() horizontal_homogeneous = true, vertical_homogeneous = true, layout = wibox.layout.grid, - id = "layout_grid" + id = 'layout_grid', }, widget = wibox.container.place, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, nil, - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } - local layout_grid = widget:get_children_by_id("layout_grid")[1] + local layout_grid = widget:get_children_by_id('layout_grid')[1] for _, layout in ipairs(layouts) do layout_grid:add(layout) @@ -1586,14 +1584,165 @@ function setup:layouts_page() return widget end +local function create_titlebar(pos) + if pos == 'right' then + return wibox.container.background + elseif pos == 'left' then + return wibox.container.background + elseif pos == 'top' then + return wibox.container.background + end +end + +local function create_selectboxes() + return wibox.container.background +end + --- The seventh page, to customize the titlebar function setup:titlebar_page() + local titlebar_right = create_titlebar('right') + local titlebar_left = create_titlebar('left') + local titlebar_center = create_titlebar('top') + + local selectbox_right = create_selectboxes() + local selectbox_left = create_selectboxes() + local selectbox_center = create_selectboxes() + local widget = wibox.widget { + { + { -- Title + { + widget = wibox.widget.textbox, + text = 'Layouts', + font = User_config.font.specify .. ' Regular, 24', + halign = 'center', + valign = 'center', + }, + widget = wibox.container.margin, + margins = dpi(10), + }, + { -- Main content + { -- Titlebar pos selection + { + { -- Top tb + { -- Radio button + { + { + widget = wibox.widget.checkbox, + checked = true, + id = 'top_tb_radio', + shape = Theme_config.setup.titlebar.checkbox_shape, + color = Theme_config.setup.titlebar.checkbox_color, + paddings = Theme_config.setup.titlebar.checkbox_padding, + }, + width = dpi(45), + height = dpi(45), + strategy = 'exact', + widget = wibox.container.constraint, + }, + widget = wibox.container.place, + }, + { -- Image + { + image = icon_dir .. 'titlebar_top.png', + resize = true, + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + width = dpi(500), + strategy = 'exact', + widget = wibox.container.constraint, + }, + id = 'top_tb', + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + { -- Left tb + { + { -- Radio button + { + { + widget = wibox.widget.checkbox, + checked = false, + id = 'left_tb_radio', + shape = Theme_config.setup.titlebar.checkbox_shape, + color = Theme_config.setup.titlebar.checkbox_color, + paddings = Theme_config.setup.titlebar.checkbox_padding, + }, + width = dpi(45), + height = dpi(45), + strategy = 'exact', + widget = wibox.container.constraint, + }, + widget = wibox.container.place, + }, + { -- Image + { + image = icon_dir .. 'titlebar_left.png', + resize = true, + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + width = dpi(500), + strategy = 'exact', + widget = wibox.container.constraint, + }, + id = 'left_tb', + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + layout = wibox.layout.flex.vertical, + }, + { + { -- Right side + titlebar_right, + --[[ selectbox_right, ]] + layout = wibox.layout.fixed.vertical, + }, + { -- Center + --[[ titlebar_center, + selectbox_center, ]] + layout = wibox.layout.fixed.vertical, + }, + { -- Left side + --[[ titlebar_left, + selectbox_left, ]] + layout = wibox.layout.fixed.vertical, + }, + layout = wibox.layout.flex.vertical, + }, + spacing_widget = wibox.widget.separator { + color = Theme_config.setup.titlebar.seperator_color, + }, + spacing = dpi(5), + layout = wibox.layout.flex.horizontal, + }, + nil, + layout = wibox.layout.align.vertical, + }, widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } + local top_tb = widget:get_children_by_id('top_tb')[1] + local left_tb = widget:get_children_by_id('left_tb')[1] + local top_tb_radio = widget:get_children_by_id('top_tb_radio')[1] + local left_tb_radio = widget:get_children_by_id('left_tb_radio')[1] + + top_tb:buttons(gtable.join(abutton({}, 1, function() + top_tb_radio.checked = true + left_tb_radio.checked = false + end))) + left_tb:buttons(gtable.join(abutton({}, 1, function() + top_tb_radio.checked = false + left_tb_radio.checked = true + end))) + return widget end @@ -1602,7 +1751,7 @@ function setup:font_page() local widget = wibox.widget { widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } return widget @@ -1613,7 +1762,7 @@ function setup:final_page() local widget = wibox.widget { widget = wibox.container.constraint, width = dpi(capi.screen.primary.geometry.width * 0.6), - strategy = "exact", + strategy = 'exact', } return widget @@ -1641,72 +1790,72 @@ function setup.new(args) nil, { { -- Main content - widget = require("src.lib.overflow_widget.overflow").horizontal, + widget = require('src.lib.overflow_widget.overflow').horizontal, scrollbar_width = 0, - step = 1.08, - id = "main_content" + step = 1.075, + id = 'main_content', }, { -- Left button { { { widget = wibox.widget.imagebox, - image = icon_dir .. "left.svg", - rezise = true + image = icon_dir .. 'left.svg', + rezise = true, }, widget = wibox.container.background, - id = "page_left", - bg = Theme_config.setup.bg .. "88", + id = 'page_left', + bg = Theme_config.setup.bg .. '88', }, widget = wibox.container.constraint, width = dpi(64), height = dpi(64), - strategy = "exact" + strategy = 'exact', }, - valign = "center", - halign = "left", - widget = wibox.container.place + valign = 'center', + halign = 'left', + widget = wibox.container.place, }, { -- Right button { { { widget = wibox.widget.imagebox, - image = icon_dir .. "right.svg", - rezise = true + image = icon_dir .. 'right.svg', + rezise = true, }, widget = wibox.container.background, - id = "page_right", - bg = Theme_config.setup.bg .. "88", + id = 'page_right', + bg = Theme_config.setup.bg .. '88', }, widget = wibox.container.constraint, width = dpi(64), height = dpi(64), - strategy = "exact" + strategy = 'exact', }, - valign = "center", - halign = "right", - widget = wibox.container.place + valign = 'center', + halign = 'right', + widget = wibox.container.place, }, - layout = wibox.layout.stack + layout = wibox.layout.stack, }, { { -- Current Page widget = wibox.widget.textbox, - halign = "center", - valign = "center", - id = "current_page" + halign = 'center', + valign = 'center', + id = 'current_page', }, widget = wibox.container.margin, margins = dpi(10), }, - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, widget = wibox.container.constraint, width = dpi(screen.geometry.width * 0.6), height = dpi(screen.geometry.width * 0.6 * 9 / 16), - strategy = "exact" + strategy = 'exact', }, screen = screen, bg = Theme_config.setup.bg, @@ -1719,36 +1868,36 @@ function setup.new(args) gtable.crush(self, setup, true) - self.main_content = self.widget:get_children_by_id("main_content")[1] + self.main_content = self.widget:get_children_by_id('main_content')[1] self.main_content.children = create_pages() self.page = 1 -- Current page - local current_page = self.widget:get_children_by_id("current_page")[1] + local current_page = self.widget:get_children_by_id('current_page')[1] - current_page:set_text(self.page .. " / " .. #self.main_content.children) + current_page:set_text(self.page .. ' / ' .. #self.main_content.children) -- Left button - local page_left = self.widget:get_children_by_id("page_left")[1] + local page_left = self.widget:get_children_by_id('page_left')[1] page_left:buttons(gtable.join( abutton({}, 1, function() if self.page == 1 then return end self:prev() self.page = self.page - 1 - current_page:set_text(self.page .. " / " .. #self.main_content.children) + current_page:set_text(self.page .. ' / ' .. #self.main_content.children) end) )) -- Right button - local page_right = self.widget:get_children_by_id("page_right")[1] + local page_right = self.widget:get_children_by_id('page_right')[1] page_right:buttons(gtable.join( abutton({}, 1, function() if self.page == #self.main_content.children then return end self:next() self.page = self.page + 1 - current_page:set_text(self.page .. " / " .. #self.main_content.children) + current_page:set_text(self.page .. ' / ' .. #self.main_content.children) end) )) diff --git a/awesome/src/core/signals.lua b/awesome/src/core/signals.lua index 8971e4d..63cabcb 100644 --- a/awesome/src/core/signals.lua +++ b/awesome/src/core/signals.lua @@ -1,256 +1,74 @@ ---@diagnostic disable: undefined-field -- Awesome Libs -local awful = require("awful") -local gears = require("gears") +local aplacement = require('awful.placement') +local gtimer = require('gears.timer') +local ascreen = require('awful.screen') +local ruled = require('ruled') -local color = require("src.lib.color") -local rubato = require("src.lib.rubato") +local config = require('src.tools.config') local capi = { awesome = awesome, mouse = mouse, screen = screen, client = client, - tag = tag + tag = tag, } -capi.screen.connect_signal("added", function() +capi.screen.connect_signal('added', function() capi.awesome.restart() end) -capi.screen.connect_signal("removed", function() +capi.screen.connect_signal('removed', function() capi.awesome.restart() end) -capi.client.connect_signal("manage", function(c) +capi.client.connect_signal('manage', function(c) if capi.awesome.startup and not c.size_hints.user_porition and not c.size_hints.program_position then - awful.placement.no_offscreen(c) - end - if c.class == "Brave-browser" then - c.floating = false + aplacement.no_offscreen(c) end if c.transient_for then c.floating = true end if c.fullscreen then - gears.timer.delayed_call(function() + gtimer.delayed_call(function() if c.valid then c:geometry(c.screen.geometry) 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 #awful.screen.focused().clients > 0 then - awful.screen.focused().clients[1]:emit_signal( - 'request::activate', - 'mouse_enter', { - raise = true + 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 #awful.screen.focused().clients > 0 then - awful.screen.focused().clients[1]:emit_signal( - 'request::activate', - 'mouse_enter', { - raise = true + 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) +--[[ client.connect_signal('mouse::enter', function(c) c:emit_signal( - "request::activate", - "mouse_enter",{ - raise = true - }) + 'request::activate', + 'mouse_enter', { + raise = true, + }) end) ]] - ---- Takes a wibox.container.background and connects four signals to it ----@param widget wibox.container.background a background widget ----@param bg_override string | nil overrides the default bg hover color ----@param fg_override string | nil overrides the default fg hover color ----@param border_override string | nil overrides the default border hover color ----@param icon_override string | nil the old icon color ----@param icon_override_hover string | nil the hover effect color -function Hover_signal(widget, bg_override, fg_override, border_override, icon_override, icon_override_hover) - local old_wibox, old_cursor, old_bg, old_fg, old_border - widget.bg = widget.bg or "#000000" - widget.fg = widget.fg or "#000000" - widget.border_color = widget.border_color or "#000000" - local icon = nil - if icon_override and icon_override_hover then - icon = widget:get_children_by_id("icon")[1].icon - widget.icon = widget:get_children_by_id("icon")[1] - end - - local _, rb, gb, bb = widget.bg:get_rgba() - local _, rf, gf, bf = widget.fg:get_rgba() - local rbo, gbo, bbo = color.utils.hex_to_rgba(widget.border_color) - - local r_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(rb * 255), rate = 24 } - local g_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(gb * 255), rate = 24 } - local b_timed_bg = rubato.timed { duration = 0.3, pos = math.floor(bb * 255), rate = 24 } - - local r_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(rf * 255), rate = 24 } - local g_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(gf * 255), rate = 24 } - local b_timed_fg = rubato.timed { duration = 0.3, pos = math.floor(bf * 255), rate = 24 } - - local r_timed_border = rubato.timed { duration = 0.3, pos = math.floor(rbo), rate = 24 } - local g_timed_border = rubato.timed { duration = 0.3, pos = math.floor(gbo), rate = 24 } - local b_timed_border = rubato.timed { duration = 0.3, pos = math.floor(bbo), rate = 24 } - - local function update_bg() - widget:set_bg("#" .. - color.utils.rgba_to_hex { math.min(r_timed_bg.pos, 255), math.min(g_timed_bg.pos, 255), - math.min(b_timed_bg.pos, 255) }) - end - - local function update_fg() - widget:set_fg("#" .. color.utils.rgba_to_hex { math.min(r_timed_fg.pos, 255), math.min(g_timed_fg.pos, 255), - math.min(b_timed_fg.pos, 255) }) - end - - local function update_border() - widget:set_border_color("#" .. - color.utils.rgba_to_hex { math.min(r_timed_border.pos, 255), math.min(g_timed_border.pos, 255), - math.min(b_timed_border.pos, 255) }) - end - - 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) - - local function set_bg(newbg) - r_timed_bg.target, g_timed_bg.target, b_timed_bg.target = newbg[1], newbg[2], newbg[3] - end - - local function set_fg(newfg) - r_timed_fg.target, g_timed_fg.target, b_timed_fg.target = newfg[1], newfg[2], newfg[3] - end - - local function set_border(newborder) - r_timed_border.target, g_timed_border.target, b_timed_border.target = newborder[1], newborder[2], newborder[3] - end - - local _, rbg, gbg, bbg, abg = widget.bg:get_rgba() - old_bg = RGB_to_hex(rbg, gbg, bbg) - local _, rfg, gfg, bfg, afg = widget.fg:get_rgba() - old_fg = RGB_to_hex(rfg, gfg, bfg) - old_border = widget.border_color - local rborder, gborder, bborder = color.utils.hex_to_rgba(old_border) - - local function match_hex(hex1, hex2) - local r1, g1, b1 = color.utils.hex_to_rgba(hex1) - local r2, g2, b2 = color.utils.hex_to_rgba(hex2) - return math.abs(r1 - r2) <= 100 and math.abs(g1 - g2) <= 100 and math.abs(b1 - b2) <= 100 - end - - --[[ - local button_release = function() - if old_bg or bg_override then - if bg_override then - bg_override = bg_override .. "dd" - end - widget.bg = bg_override or old_bg .. "dd" - end - if fg_override or old_fg then - if fg_override then - fg_override = fg_override .. "dd" - end - widget.fg = fg_override or old_fg .. "dd" - end - end ]] - - local mouse_leave = function() - - if old_bg then - local r, g, b = color.utils.hex_to_rgba(old_bg) - set_bg({ r, g, b }) - end - if old_fg then - local r, g, b = color.utils.hex_to_rgba(old_fg) - set_fg({ r, g, b }) - end - if old_border then - local r, g, b = color.utils.hex_to_rgba(old_border) - set_border({ r, g, b }) - end - if old_wibox then - old_wibox.cursor = old_cursor - old_wibox = nil - end - if widget.icon and icon_override and icon_override_hover then - widget.icon.image = gears.color.recolor_image(icon, icon_override) - end - end - - local mouse_enter = function() - _, rbg, gbg, bbg, abg = widget.bg:get_rgba() - if not match_hex(RGB_to_hex(rbg, gbg, bbg), old_bg) then - old_bg = RGB_to_hex(rbg, gbg, bbg) - set_bg({ rbg * 0.9 * 255, gbg * 0.9 * 255, bbg * 0.9 * 255 }) - end - if old_bg then - if bg_override then - rbg, gbg, bbg = color.utils.hex_to_rgba(bg_override) - set_bg({ rbg, gbg, bbg }) - else - set_bg({ rbg * 0.9 * 255, gbg * 0.9 * 255, bbg * 0.9 * 255 }) - end - end - - _, rfg, gfg, bfg, afg = widget.fg:get_rgba() - if not match_hex(RGB_to_hex(rfg, gfg, bfg), old_fg) then - old_fg = RGB_to_hex(rfg, gfg, bfg) - set_fg({ rfg * 0.9 * 255, gfg * 0.9 * 255, bfg * 0.9 * 255 }) - end - if fg_override or old_fg then - if fg_override then - rfg, gfg, bfg = color.utils.hex_to_rgba(fg_override) - set_fg({ rfg, gfg, bfg }) - else - set_fg({ rfg * 0.9 * 255, gfg * 0.9 * 255, bfg * 0.9 * 255 }) - end - end - - if not match_hex(old_border, widget.border_color) then - old_border = widget.border_color - rborder, gborder, bborder = color.utils.hex_to_rgba(old_border) - end - if border_override or old_border then - if border_override then - rborder, gborder, bborder = color.utils.hex_to_rgba(border_override) - set_border({ rborder, gborder, bborder }) - else - set_border({ rborder * 0.9, gborder * 0.9, bborder * 0.9 }) - end - end - if icon and widget.icon and icon_override and icon_override_hover then - widget.icon.image = gears.color.recolor_image(icon, icon_override_hover) - end - local w = capi.mouse.current_wibox - if w then - old_cursor, old_wibox = w.cursor, w - w.cursor = "hand1" - end - --widget:connect_signal("mouse::leave", mouse_leave) - end - - widget:connect_signal("mouse::enter", mouse_enter) - --widget:connect_signal("button::press", button_press) - --widget:connect_signal("button::release", button_release) - widget:connect_signal("mouse::leave", mouse_leave) -end diff --git a/awesome/src/core/titlebar.lua b/awesome/src/core/titlebar.lua new file mode 100644 index 0000000..23cba12 --- /dev/null +++ b/awesome/src/core/titlebar.lua @@ -0,0 +1,627 @@ +local math = math + +-- Awesome libs +local abutton = require('awful.button') +local atitlebar = require('awful.titlebar') +local atooltip = require('awful.tooltip') +local cairo = require('lgi').cairo +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gdk = require('lgi').Gdk +local gfilesystem = require('gears.filesystem') +local gsurface = require('gears.surface') +local gtimer = require('gears.timer') +local wibox = require('wibox') + +local json = require('src.lib.json-lua.json-lua') + +gdk.init {} + +local capi = { + mouse = mouse, + client = client, +} + +local instance = nil + +local titlebar = {} + +local titlebar_position = User_config.titlebar_position + +-- Converts the given hex color to hsv +local function hex2hsv(color) + local r, g, b = gcolor.parse_color(color) + local C_max = math.max(r, g, b) + local C_min = math.min(r, g, b) + local delta = C_max - C_min + local H, S, V + if delta == 0 then + H = 0 + elseif C_max == r then + H = 60 * (((g - b) / delta) % 6) + elseif C_max == g then + H = 60 * (((b - r) / delta) + 2) + elseif C_max == b then + H = 60 * (((r - g) / delta) + 4) + end + if C_max == 0 then + S = 0 + else + S = delta / C_max + end + V = C_max + return H, S * 100, V * 100 +end + +-- Converts the given hsv color to hex +local function hsv2hex(H, S, V) + S = S / 100 + V = V / 100 + if H > 360 then H = 360 end + if H < 0 then H = 0 end + local C = V * S + local X = C * (1 - math.abs(((H / 60) % 2) - 1)) + local m = V - C + local r_, g_, b_ = 0, 0, 0 + if H >= 0 and H < 60 then + r_, g_, b_ = C, X, 0 + elseif H >= 60 and H < 120 then + r_, g_, b_ = X, C, 0 + elseif H >= 120 and H < 180 then + r_, g_, b_ = 0, C, X + elseif H >= 180 and H < 240 then + r_, g_, b_ = 0, X, C + elseif H >= 240 and H < 300 then + r_, g_, b_ = X, 0, C + elseif H >= 300 and H < 360 then + r_, g_, b_ = C, 0, X + end + local r, g, b = (r_ + m) * 255, (g_ + m) * 255, (b_ + m) * 255 + return ('#%02x%02x%02x'):format(math.floor(r), math.floor(g), math.floor(b)) +end + +-- Calculates the relative luminance of the given color +local function relative_luminance(color) + local r, g, b = gcolor.parse_color(color) + local function from_sRGB(u) return u <= 0.0031308 and 25 * u / 323 or ((200 * u + 11) / 211) ^ (12 / 5) end + + return 0.2126 * from_sRGB(r) + 0.7152 * from_sRGB(g) + 0.0722 * from_sRGB(b) +end + +-- Rotates the hue of the given hex color by the specified angle (in degrees) +local function rotate_hue(color, angle) + local H, S, V = hex2hsv(color) + angle = math.max(math.min(angle or 0, 360), 0) + H = (H + angle) % 360 + return hsv2hex(H, S, V) +end + +-- Lightens a given hex color by the specified amount +local function lighten(color, amount) + local r, g, b + r, g, b = gcolor.parse_color(color) + r = 255 * r + g = 255 * g + b = 255 * b + r = r + math.floor(2.55 * amount) + g = g + math.floor(2.55 * amount) + b = b + math.floor(2.55 * amount) + r = r > 255 and 255 or r + g = g > 255 and 255 or g + b = b > 255 and 255 or b + return ('#%02x%02x%02x'):format(r, g, b) +end + +-- Darkens a given hex color by the specified amount +local function darken(color, amount) + local r, g, b + r, g, b = gcolor.parse_color(color) + r = 255 * r + g = 255 * g + b = 255 * b + r = math.max(0, r - math.floor(r * (amount / 100))) + g = math.max(0, g - math.floor(g * (amount / 100))) + b = math.max(0, b - math.floor(b * (amount / 100))) + return ('#%02x%02x%02x'):format(r, g, b) +end + +-- Returns a vertical gradient pattern going from cololr_1 -> color_2 +local function duotone_gradient_vertical(color_1, color_2, height, offset_1, offset_2) + local fill_pattern = cairo.Pattern.create_linear(0, 0, 0, height) + local r, g, b, a + r, g, b, a = gcolor.parse_color(color_1) + fill_pattern:add_color_stop_rgba(offset_1 or 0, r, g, b, a) + r, g, b, a = gcolor.parse_color(color_2) + fill_pattern:add_color_stop_rgba(offset_2 or 1, r, g, b, a) + return fill_pattern +end + +-- Returns a horizontal gradient pattern going from cololr_1 -> color_2 +local function duotone_gradient_horizontal(color_1, color_2, width, offset_1, offset_2) + local fill_pattern = cairo.Pattern.create_linear(0, 0, width, 0) + local r, g, b, a + r, g, b, a = gcolor.parse_color(color_1) + fill_pattern:add_color_stop_rgba(offset_1 or 0, r, g, b, a) + r, g, b, a = gcolor.parse_color(color_2) + fill_pattern:add_color_stop_rgba(offset_2 or 1, r, g, b, a) + return fill_pattern +end + +local function save(tbl, filename) + local handler = io.open(filename, 'w') + if not handler then return nil end + handler:write(json:encode(tbl)) + handler:close() +end + +local function load(file) + local handler = io.open(file, 'r') + if not handler then return nil end + local data = json:decode(handler:read('*a')) + assert(data, 'Failed to load file: ' .. file) + handler:close() + return data +end + +local function set_color_rule(c, color) + if (not c) or (not c.instance) then return end + titlebar.color_rules[c.instance .. titlebar_position] = color + save(titlebar.color_rules, titlebar.color_rules_filepath) +end + +local function get_color_rule(c) + if (not c) or (not c.instance) then return end + return titlebar.color_rules[c.instance .. titlebar_position] +end + +---Gets the dominant color of a client for the purpose of setting the titlebar color +---@param client any +---@return string hex color +local function get_dominant_color(client) + local tally = {} + local content = gsurface(client.content) + local cgeo = client:geometry() + local x_offset, y_offset = 2, 2 + local color + + if titlebar_position == 'top' then + for x_pos = 0, math.floor(cgeo.width / 2), 2 do + for y_pos = 0, 8, 1 do + color = '#' .. gdk.pixbuf_get_from_surface(content, x_offset + x_pos, y_offset + y_pos, 1, 1 + ):get_pixels():gsub('.', function(c) + return ('%02x'):format(c:byte()) + end) + if not tally[color] then + tally[color] = 1 + else + tally[color] = tally[color] + 1 + end + end + end + elseif titlebar_position == 'left' then + x_offset = 0 + for y_pos = 0, math.floor(cgeo.height / 2), 2 do + for x_pos = 0, 8, 1 do + color = '#' .. gdk.pixbuf_get_from_surface(content, x_offset + x_pos, y_offset + y_pos, 1, 1 + ):get_pixels():gsub('.', function(c) + return ('%02x'):format(c:byte()) + end) + if not tally[color] then + tally[color] = 1 + else + tally[color] = tally[color] + 1 + end + end + end + end + + local mode_c = 0 + for kolor, kount in pairs(tally) do + if kount > mode_c then + mode_c = kount + color = kolor + end + end + set_color_rule(client, color) + return color +end + +local function create_button_image(name, is_focused, event, is_on) + titlebar.key = titlebar.key or {} + + titlebar.key.close_color = Theme_config.titlebar.close + titlebar.key.minimize_color = Theme_config.titlebar.minimize + titlebar.key.maximize_color = Theme_config.titlebar.maximize + titlebar.key.floating_color = Theme_config.titlebar.floating + titlebar.key.ontop_color = Theme_config.titlebar.ontop + titlebar.key.sticky_color = Theme_config.titlebar.sticky + + local focus_state = is_focused and 'focused' or 'unfocused' + local key_img + if is_on ~= nil then + local toggle_state = is_on and 'on' or 'off' + key_img = ('%s_%s_%s_%s'):format(name, toggle_state, focus_state, event) + else + key_img = ('%s_%s_%s'):format(name, focus_state, event) + end + if titlebar.key[key_img] then return titlebar.key[key_img] end + local key_color = key_img .. '_color' + if not titlebar.key[key_color] then + local key_base_color = name .. '_color' + local base_color = titlebar.key[key_base_color] or rotate_hue(hsv2hex(math.random(0, 360), 70, 90), 33) + titlebar.key[key_base_color] = base_color + local button_color = base_color + local H = hex2hsv(base_color) + if not is_focused and event ~= 'hover' then + button_color = hsv2hex(H, 0, 50) + end + button_color = (event == 'hover') and lighten(button_color, 25) or + (event == 'press') and darken(button_color, 25) or button_color + titlebar.key[key_color] = button_color + end + local button_size = Theme_config.titlebar.button_size + local surface = cairo.ImageSurface.create('ARGB32', button_size, button_size) + local cr = cairo.Context.create(surface) + cr:arc(button_size / 2, button_size / 2, button_size / 2, math.rad(0), math.rad(360)) + cr:set_source_rgba(gcolor.parse_color(titlebar.key[key_color] or '#fefefa')) + cr.antialias = cairo.Antialias.BEST + cr:fill() + titlebar.key[key_img] = surface + return titlebar.key[key_img] +end + +---Returns a button widget for the titlebar +---@param c client +---@param name string Name for the tooltip and the correct button image +---@param button_callback function callback function called when the button is pressed +---@param property string|nil client state, e.g. active or inactive +---@return wibox.widget button widget +local function create_titlebar_button(c, name, button_callback, property) + local button_img = wibox.widget.imagebox(nil, false) + local tooltip = atooltip { + text = name, + delay_show = 0.5, + margins_leftright = 12, + margins_topbottom = 6, + timeout = 0.25, + align = 'bottom_right', + } + tooltip:add_to_object(button_img) + local is_on, is_focused + local event = 'normal' + local function update() + is_focused = c.active + -- If the button is for a property that can be toggled + if property then + is_on = c[property] + button_img.image = create_button_image(name, is_focused, event, is_on) + else + button_img.image = create_button_image(name, is_focused, event) + end + end + + c:connect_signal('unfocus', update) + c:connect_signal('focus', update) + if property then c:connect_signal('property::' .. property, update) end + button_img:connect_signal('mouse::enter', function() + event = 'hover' + update() + end) + button_img:connect_signal('mouse::leave', function() + event = 'normal' + update() + end) + + button_img.buttons = abutton({}, 1, function() + event = 'press' + update() + end, function() + if button_callback then + event = 'normal' + button_callback() + else + event = 'hover' + end + update() + end) + + button_img.id = 'button_image' + update() + return wibox.widget { + { + { + button_img, + widget = wibox.container.constraint, + height = Theme_config.titlebar.button_size, + width = Theme_config.titlebar.button_size, + strategy = 'exact', + }, + widget = wibox.container.margin, + margins = dpi(5), + }, + widget = wibox.container.place, + } +end + +---Get the mouse bindings for the titlebar +---@param c client +---@return table all mouse bindings for the titlebar +local function get_titlebar_mouse_bindings(c) + local clicks = 0 + local tolerance = 4 + local buttons = { abutton({}, 1, function() + local cx, cy = capi.mouse.coords().x, capi.mouse.coords().y + local delta = 250 / 1000 + clicks = clicks + 1 + if clicks == 2 then + local nx, ny = capi.mouse.coords().x, capi.mouse.coords().y + if math.abs(cx - nx) <= tolerance and math.abs(cy - ny) <= tolerance then + c.maximized = not c.maximized + end + else + c:activate { context = 'titlebar', action = 'mouse_move' } + end + -- Start a timer to clear the click count + gtimer.weak_start_new(delta, function() clicks = 0 end) + end), abutton({}, 2, function() + c.color = get_dominant_color(c) + set_color_rule(c, c.color) + add_titlebar(c) + end), abutton({}, 3, function() + c:activate { context = 'mouse_click', action = 'mouse_resize' } + end), } + return buttons +end + +---Creates a title widget for the titlebar +---@param c client +---@return wibox.widget The title widget +local function create_titlebar_title(c) + local title_widget = wibox.widget { + halign = 'center', + ellipsize = 'middle', + opacity = c.active and 1 or 0.7, + valign = 'center', + widget = wibox.widget.textbox, + } + + local function update() + title_widget.markup = ("%s"):format( + (((relative_luminance('#fefefa') + 0.05) / (relative_luminance(c.color) + 0.05)) >= 7 and true) + and '#fefefa' or '#242424', c.name) + end + + c:connect_signal('property::name', update) + c:connect_signal('unfocus', function() + title_widget.opacity = 0.7 + end) + c:connect_signal('focus', function() title_widget.opacity = 1 end) + update() + return { + title_widget, + widget = wibox.container.margin, + margins = Theme_config.titlebar.title_margin, + } +end + +---Creates the widget for a titlebar item +---@param c client +---@param name string The name of the item +---@return wibox.widget|nil widget The titlebar item widget +local function get_titlebar_item(c, name) + if titlebar_position == 'top' then + if name == 'close' then return create_titlebar_button(c, name, function() c:kill() end) + elseif name == 'maximize' then + return create_titlebar_button(c, name, function() c.maximized = not c.maximized end, 'maximized') + elseif name == 'minimize' then + return create_titlebar_button(c, name, function() c.minimized = true end) + elseif name == 'ontop' then + return create_titlebar_button(c, name, function() c.ontop = not c.ontop end, 'ontop') + elseif name == 'floating' then + return create_titlebar_button(c, name, function() + c.floating = not c.floating + if c.floating then + c.maximized = false + end + end, 'floating') + elseif name == 'sticky' then + return create_titlebar_button(c, name, function() + c.sticky = not c.sticky + return c.sticky + end, 'sticky') + elseif name == 'title' then + return create_titlebar_title(c) + elseif name == 'icon' then + return wibox.widget { + atitlebar.widget.iconwidget(c), + widget = wibox.container.margin, + margins = dpi(5), + } + end + elseif titlebar_position == 'left' then + if name == 'close' then + return create_titlebar_button(c, name, function() c:kill() end) + elseif name == 'maximize' then + return create_titlebar_button(c, name, function() c.maximized = not c.maximized end, 'maximized') + elseif name == 'minimize' then + return create_titlebar_button(c, name, function() c.minimized = true end) + elseif name == 'ontop' then + return create_titlebar_button(c, name, function() c.ontop = not c.ontop end, 'ontop') + elseif name == 'floating' then + return create_titlebar_button(c, name, function() + c.floating = not c.floating + if c.floating then + c.maximized = false + end + end, 'floating') + elseif name == 'sticky' then + return create_titlebar_button(c, name, function() + c.sticky = not c.sticky + return c.sticky + end, 'sticky') + elseif name == 'icon' then + return wibox.widget { + atitlebar.widget.iconwidget(c), + widget = wibox.container.margin, + margins = dpi(5), + } + end + end +end + +---Groups together the titlebar items for left, center, right placement +---@param c client +---@param group table|string The name of the group or a table of item names +---@return wibox.widget|nil widget The titlebar item widget +local function create_titlebar_items(c, group) + if not group then return nil end + if type(group) == 'string' then return create_titlebar_title(c) end + local layout + + if titlebar_position == 'left' then + layout = wibox.widget { + layout = wibox.layout.fixed.vertical, + } + elseif titlebar_position == 'top' then + layout = wibox.widget { + layout = wibox.layout.fixed.horizontal, + } + end + + local item + for _, name in ipairs(group) do + item = get_titlebar_item(c, name) + if item then layout:add(item) end + end + 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, { + size = Theme_config.titlebar.size, + bg = gcolor.transparent, + position = 'top', + }):setup { + { + { + create_titlebar_items(c, User_config.titlebar_items.left_and_bottom), + widget = wibox.container.margin, + left = dpi(5), + }, + { + create_titlebar_items(c, User_config.titlebar_items.middle), + buttons = get_titlebar_mouse_bindings(c), + layout = wibox.layout.flex.horizontal, + }, + { + create_titlebar_items(c, User_config.titlebar_items.right_and_top), + widget = wibox.container.margin, + right = dpi(5), + }, + layout = wibox.layout.align.horizontal, + }, + widget = wibox.container.background, + bg = duotone_gradient_vertical( + lighten(c.color, 1), + c.color, + Theme_config.titlebar.size, + 0, + 0.5 + ), + } + elseif titlebar_position == 'left' then + atitlebar(c, { + size = Theme_config.titlebar.size, + bg = gcolor.transparent, + position = 'left', + }):setup { + { + { + create_titlebar_items(c, User_config.titlebar_items.right_and_top), + widget = wibox.container.margin, + top = dpi(5), + }, + { + create_titlebar_items(c, User_config.titlebar_items.middle), + buttons = get_titlebar_mouse_bindings(c), + layout = wibox.layout.flex.vertical, + }, + { + create_titlebar_items(c, User_config.titlebar_items.left_and_bottom), + widget = wibox.container.margin, + left = dpi(5), + }, + layout = wibox.layout.align.vertical, + }, + widget = wibox.container.background, + bg = duotone_gradient_horizontal( + lighten(c.color, 1), + c.color, + Theme_config.titlebar.size, + 0, + 0.5 + ), + } + end + + if not c.floating then + atitlebar.hide(c, titlebar_position) + end + c:connect_signal('property::maximized', function() + if not c.floating then + --if not client or not client.focus then return end + atitlebar.hide(c, titlebar_position) + elseif c.floating and (not (c.maximized or c.fullscreen)) then + atitlebar.show(c, titlebar_position) + end + end) + c:connect_signal('property::floating', function() + if not c.floating then + --if not client or not client.focus then return end + atitlebar.hide(c, titlebar_position) + elseif c.floating and (not (c.maximized or c.fullscreen)) then + atitlebar.show(c, titlebar_position) + end + end) +end + +if not instance then + instance = setmetatable(titlebar, { __call = function() + + titlebar.color_rules_filepath = gfilesystem.get_configuration_dir() .. '/src/config/' .. 'color_rules.json' + titlebar.color_rules = load(titlebar.color_rules_filepath) or {} + + capi.client.connect_signal('request::titlebars', function(c) + c._cb_add_window_decorations = function() + gtimer.weak_start_new(0.5, function() + c.color = get_dominant_color(c) + add_titlebar(c) + c:disconnect_signal('request::activate', c._cb_add_window_decorations) + end) + end + + local color = get_color_rule(c) + if color then + c.color = color + add_titlebar(c) + else + c.color = Theme_config.titlebar.color + add_titlebar(c) + c:connect_signal('request::activate', c._cb_add_window_decorations) + end + end) + + capi.client.connect_signal('request::manage', function(c) + if not c.floating then + --if not client or not client.focus then return end + atitlebar.hide(c, titlebar_position) + elseif c.floating and (not (c.maximized or c.fullscreen)) then + atitlebar.show(c, titlebar_position) + end + end) + end, }) +end +return instance diff --git a/awesome/src/lib/dbus_proxy b/awesome/src/lib/dbus_proxy new file mode 160000 index 0000000..c9253bd --- /dev/null +++ b/awesome/src/lib/dbus_proxy @@ -0,0 +1 @@ +Subproject commit c9253bde3fa5a64261953d1b196c57fabf9f8561 diff --git a/awesome/src/lib/nice b/awesome/src/lib/nice deleted file mode 160000 index 32d082e..0000000 --- a/awesome/src/lib/nice +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 32d082e19ab68eb35ec7384467e90eaf72c5d124 diff --git a/awesome/src/modules/__test.lua b/awesome/src/modules/__test.lua deleted file mode 100644 index e60ff2c..0000000 --- a/awesome/src/modules/__test.lua +++ /dev/null @@ -1,60 +0,0 @@ -local setmetatable = setmetatable -local base = require("wibox.widget.base") -local gtable = require("gears.table") -local wibox = require("wibox") - -local module = { mt = {} } - -function module:layout(_, width, height) - if self._private.widget then - return { base.place_widget_at(self._private.widget, 0, 0, width, height) } - end -end - -function module:fit(context, width, height) - local w, h = 0, 0 - if self._private.widget then - w, h = base.fit_widget(self, context, self._private.widget, width, height) - end - return w, h -end - -module.set_widget = base.set_widget_common - -function module:set_widget_template(widget_template) - self._private.widget_template = widget_template - self:set_widget(widget_template) -end - -function module:get_widget() - return self._private.widget -end - -function module:get_children() - return { self._private.widget } -end - -function module:set_children(children) - self:set_widget(children[1]) -end - -function module:reset() - self._private.widget_template = nil - self:set_widget(nil) -end - -local function new(args) - local self = base.make_widget(nil, nil, { enable_properties = true }) - - gtable.crush(self, module, true) - - self:set_widget(wibox.widget.textbox("Hello World!")) - - return self -end - -function module.mt:__call(...) - return new(...) -end - -return setmetatable(module, module.mt) diff --git a/awesome/src/modules/application_launcher/application.lua b/awesome/src/modules/application_launcher/application.lua index 4607e5a..91f5893 100644 --- a/awesome/src/modules/application_launcher/application.lua +++ b/awesome/src/modules/application_launcher/application.lua @@ -3,26 +3,31 @@ -------------------------------------- -- Awesome libs -local abutton = require("awful.button") -local aspawn = require("awful.spawn") -local base = require("wibox.widget.base") -local dpi = require("beautiful").xresources.apply_dpi -local gcolor = require("gears.color") -local gfilesystem = require("gears").filesystem -local Gio = require("lgi").Gio -local gtable = require("gears.table") -local wibox = require("wibox") +local abutton = require('awful.button') +local aspawn = require('awful.spawn') +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears').filesystem +local Gio = require('lgi').Gio +local gtable = require('gears.table') +local wibox = require('wibox') -- Third party libs -local json = require("src.lib.json-lua.json-lua") -local cm = require("src.modules.context_menu.init") + +local cm = require('src.modules.context_menu.init') +local dock = require('src.modules.crylia_bar.dock') + +-- Local libs +local config = require('src.tools.config') +local hover = require('src.tools.hover') local capi = { awesome = awesome, mouse = mouse, } -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/' local application_grid = { mt = {} } @@ -31,11 +36,11 @@ local application_grid = { mt = {} } This is done here once because it would be unnecessary to do it for every instance ]] do - local dir = gfilesystem.get_configuration_dir() .. "src/config" + local dir = gfilesystem.get_configuration_dir() .. 'src/config' gfilesystem.make_directories(dir) - dir = dir .. "/applications.json" + dir = dir .. '/applications.json' if not gfilesystem.file_readable(dir) then - aspawn("touch " .. dir) + aspawn('touch ' .. dir) end end @@ -125,55 +130,55 @@ local function get_applications_from_file() { { { -- Icon - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', image = Get_gicon_path(app_info.get_icon(app)) or Get_gicon_path(app_info.get_icon(app), - Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "", + Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '', resize = true, - widget = wibox.widget.imagebox + widget = wibox.widget.imagebox, }, height = dpi(64), width = dpi(64), - strategy = "exact", - widget = wibox.container.constraint + strategy = 'exact', + widget = wibox.container.constraint, }, { { -- Name text = app_info.get_name(app), - align = "center", - valign = "center", - widget = wibox.widget.textbox + align = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, - strategy = "exact", + strategy = 'exact', width = dpi(170), -- Prevents widget from overflowing height = dpi(40), - widget = wibox.container.constraint + widget = wibox.container.constraint, }, - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - halign = "center", - valign = "center", - widget = wibox.container.place + halign = 'center', + valign = 'center', + widget = wibox.container.place, }, margins = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, name = app_info.get_name(app), - comment = Gio.DesktopAppInfo.get_string(desktop_app_info, "Comment") or "", - exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"), - keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, "Keywords") or "", - categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or "", - terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, "Terminal") == "true", + comment = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Comment') or '', + exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'), + keywords = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Keywords') or '', + categories = Gio.DesktopAppInfo.get_categories(desktop_app_info) or '', + terminal = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Terminal') == 'true', actions = Gio.DesktopAppInfo.list_actions(desktop_app_info), - desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or "", + desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '', border_color = Theme_config.application_launcher.application.border_color, border_width = Theme_config.application_launcher.application.border_width, bg = Theme_config.application_launcher.application.bg, fg = Theme_config.application_launcher.application.fg, shape = Theme_config.application_launcher.application.shape, - widget = wibox.container.background + widget = wibox.container.background, } local context_menu = cm { widget_template = wibox.widget { @@ -183,122 +188,113 @@ local function get_applications_from_file() { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role", + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, }, spacing = dpi(10), entries = { { - name = "Execute as sudo", - icon = gcolor.recolor_image(icondir .. "launch.svg", + name = 'Execute as sudo', + icon = gcolor.recolor_image(icondir .. 'launch.svg', Theme_config.application_launcher.application.cm_icon_color), callback = function() - capi.awesome.emit_signal("application_launcher::show") - aspawn("/home/crylia/.config/awesome/src/scripts/start_as_admin.sh " .. app_widget.exec) - end + capi.awesome.emit_signal('application_launcher::show') + aspawn('/home/crylia/.config/awesome/src/scripts/start_as_admin.sh ' .. app_widget.exec) + end, }, { - name = "Pin to dock", - icon = gcolor.recolor_image(icondir .. "pin.svg", + name = 'Pin to dock', + icon = gcolor.recolor_image(icondir .. 'pin.svg', Theme_config.application_launcher.application.cm_icon_color), callback = function() -- Open dock.js and read all its content into a table, add the new app into the table and write it back - local file_path = gfilesystem.get_configuration_dir() .. "src/config/dock.json" - local handler = io.open(file_path, "r") - if not handler then return end + --[[ async.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', function(data) + table.insert(data, { + name = app_widget.name or '', + icon = Get_gicon_path(app_info.get_icon(app)) or + Get_gicon_path(app_info.get_icon(app), + Gio.DesktopAppInfo.get_string(desktop_app_info, 'X-AppImage-Old-Icon')) or '', + comment = app_widget.comment or '', + exec = app_widget.exec or '', + keywords = app_widget.keywords or '', + categories = app_widget.categories or '', + terminal = app_widget.terminal or '', + actions = app_widget.actions or '', + desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '' + }) - local dock_table = json:decode(handler:read("a")) or {} - - handler:close() - assert(type(dock_table) == "table", "dock_table is not a table") - - table.insert(dock_table, { - name = app_widget.name or "", - icon = Get_gicon_path(app_info.get_icon(app)) or - Get_gicon_path(app_info.get_icon(app), - Gio.DesktopAppInfo.get_string(desktop_app_info, "X-AppImage-Old-Icon")) or "", - comment = app_widget.comment or "", - exec = app_widget.exec or "", - keywords = app_widget.keywords or "", - categories = app_widget.categories or "", - terminal = app_widget.terminal or "", - actions = app_widget.actions or "", - desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or "" - }) - - local dock_encoded = json:encode(dock_table) - handler = io.open(file_path, "w") - - if not handler then return end - - handler:write(dock_encoded) - handler:close() - capi.awesome.emit_signal("dock::changed") - end + async.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock.json', data, function() + capi.awesome.emit_signal('dock::changed') + end) + end) ]] + dock:get_dock_for_screen(capi.mouse.screen):pin_element { + desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '', + } + end, }, { - name = "Add to desktop", - icon = gcolor.recolor_image(icondir .. "desktop.svg", + name = 'Add to desktop', + icon = gcolor.recolor_image(icondir .. 'desktop.svg', Theme_config.application_launcher.application.cm_icon_color), callback = function() - capi.awesome.emit_signal("application_launcher::show") - capi.awesome.emit_signal("desktop::add_to_desktop", { + capi.awesome.emit_signal('application_launcher::show') + capi.awesome.emit_signal('desktop::add_to_desktop', { label = app_info.get_name(app), - icon = Get_gicon_path(app_info.get_icon(app)) or "", - exec = Gio.DesktopAppInfo.get_string(desktop_app_info, "Exec"), - desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or "" + icon = Get_gicon_path(app_info.get_icon(app)) or '', + exec = Gio.DesktopAppInfo.get_string(desktop_app_info, 'Exec'), + desktop_file = Gio.DesktopAppInfo.get_filename(desktop_app_info) or '', }) - end - } - } + end, + }, + }, } -- Hide context menu when the mouse leaves it - context_menu:connect_signal("mouse::leave", function() + context_menu:connect_signal('mouse::leave', function() context_menu.visible = false end) -- Execute command on left click and hide launcher, right click to show context menu app_widget:buttons( gtable.join( - abutton({ + abutton { modifiers = {}, button = 1, on_release = function() Gio.AppInfo.launch_uris_async(app) - capi.awesome.emit_signal("application_launcher::show") - end - }), - abutton({ + capi.awesome.emit_signal('application_launcher::show') + end, + }, + abutton { modifiers = {}, button = 3, on_release = function() context_menu:toggle() - end - }) + end, + } ) ) - Hover_signal(app_widget) + hover.bg_hover { widget = app_widget } table.insert(list, app_widget) end end @@ -308,48 +304,41 @@ end ---Takes the search filter and returns a list of applications in the correct order ---@param search_filter any function application_grid:set_applications(search_filter) - local filter = search_filter or self.filter or "" + local filter = search_filter or self.filter or '' -- Reset to first position self._private.curser = { x = 1, - y = 1 + y = 1, } local grid = wibox.widget { homogenous = true, expand = false, spacing = dpi(10), - id = "grid", + id = 'grid', -- 200 is the application element width + 10 spacing forced_num_cols = math.floor((capi.mouse.screen.geometry.width / 100 * 60) / 200), forced_num_rows = 7, - orientation = "vertical", - layout = wibox.layout.grid + orientation = 'vertical', + layout = wibox.layout.grid, } -- Read the dock.json file and get all apps, these are needed to read/write the launch count - local handler = io.open(gfilesystem.get_configuration_dir() .. "src/config/applications.json", "r") - if not handler then return end - - local dock_encoded = handler:read("a") or "{}" - local dock = json:decode(dock_encoded) - - assert(type(dock) == "table", "dock is not a table") - + local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json') local mylist = {} for _, application in ipairs(self.app_list) do -- Match the filter for the name, categories and keywords - if string.match(string.lower(application.name or ""), string.lower(filter)) or - string.match(string.lower(application.categories or ""), string.lower(filter)) or - string.match(string.lower(application.keywords or ""), string.lower(filter)) then + if string.match(string.lower(application.name or ''), string.lower(filter)) or + string.match(string.lower(application.categories or ''), string.lower(filter)) or + string.match(string.lower(application.keywords or ''), string.lower(filter)) then -- If there are no elements in the table, set everything to 0 - if #dock == 0 then + if #data == 0 then application.counter = 0 end -- Read the counter for the matching app - for _, app in ipairs(dock) do + for _, app in ipairs(data) do if app.desktop_file == application.desktop_file then application.counter = app.counter or 0 break; @@ -380,7 +369,7 @@ function application_grid:set_applications(search_filter) -- Check if the curser is currently at the same position as the app capi.awesome.connect_signal( - "update::selected", + 'update::selected', function() if self._private.curser.y == pos.row and self._private.curser.x == pos.col then app.border_color = Theme_config.application_launcher.application.border_color_active @@ -391,7 +380,7 @@ function application_grid:set_applications(search_filter) ) end - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') self:set_widget(grid) end @@ -401,7 +390,7 @@ function application_grid:move_up() if self._private.curser.y < 1 then self._private.curser.y = 1 end - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') end -- Move the curser down by one, making sure it doesn't go out of bounds @@ -411,7 +400,7 @@ function application_grid:move_down() if self._private.curser.y > grid_rows then self._private.curser.y = grid_rows end - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') end -- Move the curser left by one, making sure it doesn't go out of bounds @@ -420,7 +409,7 @@ function application_grid:move_left() if self._private.curser.x < 1 then self._private.curser.x = 1 end - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') end -- Move the curser right by one, making sure it doesn't go out of bounds @@ -430,7 +419,7 @@ function application_grid:move_right() if self._private.curser.x > grid_cols then self._private.curser.x = grid_cols end - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') end --- Execute the currently selected app and add to the launch count @@ -441,17 +430,9 @@ function application_grid:execute() -- Launch the application async Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(selected_widget.exec, nil, 0)) - local file_path = gfilesystem.get_configuration_dir() .. "src/config/applications.json" - local handler = io.open(file_path, "r") - if not handler then return end - - local dock_encoded = handler:read("a") or "{}" - local dock = json:decode(dock_encoded) - - assert(type(dock) == "table", "dock is not a table") - + local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json') -- Increase the counter by one then rewrite to the file, its a bit hacky but it works - for _, prog in ipairs(dock) do + for _, prog in ipairs(data) do if prog.desktop_file:match(selected_widget.desktop_file) then prog.counter = prog.counter + 1 -- I don't like goto's, but its the easiest way here(PR is welcome). @@ -462,25 +443,21 @@ function application_grid:execute() local prog = { name = selected_widget.name, desktop_file = selected_widget.desktop_file, - counter = 1 + counter = 1, } - table.insert(dock, prog) + table.insert(data, prog) end ::continue:: - handler:close() - handler = io.open(file_path, "w") - if not handler then return end - handler:write(json:encode_pretty(dock)) - handler:close() + config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/applications.json', data) end -- Reset the grid cursor function application_grid:reset() self._private.curser = { x = 1, - y = 1 + y = 1, } - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') end function application_grid.new(args) @@ -496,8 +473,4 @@ function application_grid.new(args) return w end -function application_grid.mt:__call(...) - return application_grid.new(...) -end - -return setmetatable(application_grid, application_grid.mt) +return setmetatable(application_grid, { __call = function(...) return application_grid.new(...) end }) diff --git a/awesome/src/modules/application_launcher/init.lua b/awesome/src/modules/application_launcher/init.lua index eb3f0c7..2425b64 100644 --- a/awesome/src/modules/application_launcher/init.lua +++ b/awesome/src/modules/application_launcher/init.lua @@ -3,17 +3,17 @@ -------------------------------------- -- Awesome Libs -local abutton = require("awful.button") -local akeygrabber = require("awful.keygrabber") -local aplacement = require("awful.placement") -local apopup = require("awful.popup") -local awidget = require("awful.widget") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local wibox = require("wibox") +local abutton = require('awful.button') +local akeygrabber = require('awful.keygrabber') +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local wibox = require('wibox') -- Own libs -local app_grid = require("src.modules.application_launcher.application") +local app_grid = require('src.modules.application_launcher.application') local capi = { awesome = awesome, @@ -23,18 +23,17 @@ local capi = { -- This grid object is shared to avoid having multipe unnecessary instances local application_grid = app_grid {} -local application_launcher = { mt = {} } +local application_launcher = {} function application_launcher.new(args) args = args or {} -- Create a new inputbox local searchbar = awidget.inputbox { - hint_text = "Search...", - valign = "center", - halign = "left", + hint_text = 'Search...', + valign = 'center', + halign = 'left', } - -- Application launcher popup local application_container = apopup { widget = { @@ -48,7 +47,7 @@ function application_launcher.new(args) margins = 5, }, widget = wibox.container.constraint, - strategy = "exact", + strategy = 'exact', height = dpi(50), }, widget = wibox.container.background, @@ -57,22 +56,22 @@ function application_launcher.new(args) border_color = Theme_config.application_launcher.searchbar.border_color, border_width = Theme_config.application_launcher.searchbar.border_width, shape = Theme_config.application_launcher.searchbar.shape, - id = "searchbar_bg" + id = 'searchbar_bg', }, { application_grid, - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, scrollbar_width = 0, step = dpi(100), }, spacing = dpi(10), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, margins = dpi(20), - widget = wibox.container.margin + widget = wibox.container.margin, }, height = args.screen.geometry.height / 100 * 60, - strategy = "exact", + strategy = 'exact', widget = wibox.container.constraint, }, ontop = true, @@ -82,7 +81,7 @@ function application_launcher.new(args) placement = aplacement.centered, bg = Theme_config.application_launcher.bg, border_color = Theme_config.application_launcher.border_color, - border_width = Theme_config.application_launcher.border_width + border_width = Theme_config.application_launcher.border_width, } gtable.crush(application_container, application_launcher, true) @@ -91,31 +90,31 @@ function application_launcher.new(args) searchbar:buttons(gtable.join { abutton({}, 1, function() searchbar:focus() - end) + end), }) --#region Hover signals to change the cursor to a text cursor local old_cursor, old_wibox - searchbar:connect_signal("mouse::enter", function() + searchbar:connect_signal('mouse::enter', function() local wid = capi.mouse.current_wibox if wid then old_cursor, old_wibox = wid.cursor, wid - wid.cursor = "xterm" + wid.cursor = 'xterm' end end) - searchbar:connect_signal("mouse::leave", function() + searchbar:connect_signal('mouse::leave', function() old_wibox.cursor = old_cursor old_wibox = nil end) --#endregion -- Get a reference to the searchbar background value - local searchbar_bg = application_container.widget:get_children_by_id("searchbar_bg")[1] + local searchbar_bg = application_container.widget:get_children_by_id('searchbar_bg')[1] -- Toggle visible for the application launcher and init the searchbar - capi.awesome.connect_signal("application_launcher::show", function() + capi.awesome.connect_signal('application_launcher::show', function() if capi.mouse.screen == args.screen then - capi.awesome.emit_signal("update::selected") + capi.awesome.emit_signal('update::selected') if capi.mouse.screen == args.screen then application_container.visible = not application_container.visible end @@ -123,76 +122,76 @@ function application_launcher.new(args) searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active searchbar:focus() else - searchbar:set_text("") + searchbar:set_text('') akeygrabber.stop() end end end) -- Execute the currently selected application, reset the searchbar and hide the launcher - searchbar:connect_signal("submit", function(_, text) + searchbar:connect_signal('submit', function(_, text) application_grid:execute() - capi.awesome.emit_signal("application_launcher::show") - searchbar:set_text("") + capi.awesome.emit_signal('application_launcher::show') + searchbar:set_text('') application_grid:set_applications(searchbar:get_text()) searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color end) -- Hide the application launcher when the keygrabber stops and reset the searchbar - searchbar:connect_signal("stopped", function(_, stop_key) - if stop_key == "Escape" then - capi.awesome.emit_signal("application_launcher::show") + searchbar:connect_signal('stopped', function(_, stop_key) + if stop_key == 'Escape' then + capi.awesome.emit_signal('application_launcher::show') end - searchbar:set_text("") + searchbar:set_text('') application_grid:set_applications(searchbar:get_text()) searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_color end) -- When started change the background for the searchbar - searchbar:connect_signal("started", function() + searchbar:connect_signal('started', function() searchbar_bg.border_color = Theme_config.application_launcher.searchbar.border_active end) -- On every keypress in the searchbar check for certain inputs - searchbar:connect_signal("inputbox::key_pressed", function(_, modkey, key) - if key == "Escape" then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar + searchbar:connect_signal('inputbox::key_pressed', function(_, modkey, key) + if key == 'Escape' then -- Escape to stop the keygrabber, hide the launcher and reset the searchbar searchbar:stop() - capi.awesome.emit_signal("application_launcher::show") + capi.awesome.emit_signal('application_launcher::show') application_grid:reset() - searchbar:set_text("") - elseif key == "Down" or key == "Right" then --If down or right is pressed initiate the grid navigation - if key == "Down" then + searchbar:set_text('') + elseif key == 'Down' or key == 'Right' then --If down or right is pressed initiate the grid navigation + if key == 'Down' then application_grid:move_down() - elseif key == "Right" then + elseif key == 'Right' then application_grid:move_right() end searchbar:stop() --New keygrabber to allow for key navigation akeygrabber.run(function(mod, key2, event) - if event == "press" then - if key2 == "Down" then + if event == 'press' then + if key2 == 'Down' then application_grid:move_down() - elseif key2 == "Up" then + elseif key2 == 'Up' then local old_y = application_grid._private.curser.y application_grid:move_up() if old_y - application_grid._private.curser.y == 0 then searchbar:focus() end - elseif key2 == "Left" then + elseif key2 == 'Left' then application_grid:move_left() - elseif key2 == "Right" then + elseif key2 == 'Right' then application_grid:move_right() - elseif key2 == "Return" then + elseif key2 == 'Return' then akeygrabber.stop() application_grid:execute() - capi.awesome.emit_signal("application_launcher::show") + capi.awesome.emit_signal('application_launcher::show') application_grid:reset() - searchbar:set_text("") + searchbar:set_text('') application_grid:set_applications(searchbar:get_text()) - elseif key2 == "Escape" then - capi.awesome.emit_signal("application_launcher::show") + elseif key2 == 'Escape' then + capi.awesome.emit_signal('application_launcher::show') application_grid:reset() - searchbar:set_text("") + searchbar:set_text('') application_grid:set_applications(searchbar:get_text()) akeygrabber.stop() end @@ -205,8 +204,4 @@ function application_launcher.new(args) end) end -function application_launcher.mt:__call(...) - return application_launcher.new(...) -end - -return setmetatable(application_launcher, application_launcher.mt) +return setmetatable(application_launcher, { __call = function(_, ...) return application_launcher.new(...) end }) diff --git a/awesome/src/modules/audio/audio_controller.lua b/awesome/src/modules/audio/audio_controller.lua new file mode 100644 index 0000000..6dcb917 --- /dev/null +++ b/awesome/src/modules/audio/audio_controller.lua @@ -0,0 +1,575 @@ +-- Awesome Libs +local abutton = require('awful.button') +local aspawn = require('awful.spawn') +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gshape = require('gears.shape') +local gtable = require('gears.table') +local gfilesystem = require('gears.filesystem') +local wibox = require('wibox') + +-- Third party libs +local rubato = require('src.lib.rubato') + +-- Local libs +local audio_helper = require('src.tools.helpers.audio') +local hover = require('src.tools.hover') + +-- Icon directory path +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/' + +local audio_controller = {} + +--#region wibox.widget.base boilerplate + +function audio_controller:layout(_, width, height) + if self._private.widget then + return { base.place_widget_at(self._private.widget, 0, 0, width, height) } + end +end + +function audio_controller:fit(context, width, height) + local w, h = 0, 0 ---@type number|nil, number|nil + if self._private.widget then + w, h = base.fit_widget(self, context, self._private.widget, width, height) + end + return w, h +end + +--#endregion + +---Set the default source asynchronously +---@param sink any +function audio_controller:set_default_sink(sink) + if not sink then return end + aspawn('pactl set-default-sink ' .. sink) + self:emit_signal('AC::device_changed') +end + +---Set the default source asynchronously +function audio_controller:set_default_source(source) + if not source then return end + aspawn('pactl set-default-source ' .. source) + self:emit_signal('AC::device_changed') +end + +---Get the default sink asynchronously +---@param callback function returns the default sink as string +function audio_controller:get_default_sink_async(callback) + aspawn.easy_async_with_shell('pactl get-default-sink', function(stdout) callback(stdout:gsub('\n', '')) end) +end + +---Takes a sink and name and returns a new device widget, the device_type is for the color +---@param device string sink +---@param name string name of the device +---@param device_type string sink or source +---@return wibox.widget +function audio_controller:get_device_widget(device, name, device_type) + --remove leading spaces from name + name = name:gsub('^%s*(.-)%s*$', '%1') + local icon_color, fg + if device_type == 'source' then + icon_color = Theme_config.volume_controller.device_microphone_fg + fg = Theme_config.volume_controller.device_microphone_fg + elseif device_type == 'sink' then + icon_color = Theme_config.volume_controller.device_headphones_fg + fg = Theme_config.volume_controller.device_headphones_fg + end + + local device_widget = wibox.widget { + { + { + { + { + id = 'icon', + resize = true, + image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color), + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + widget = wibox.container.constraint, + width = dpi(24), + height = dpi(24), + strategy = 'exact', + }, + { + { + id = 'name', + text = name, + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + widget = wibox.container.constraint, + height = dpi(24), + strategy = 'exact', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + bg = Theme_config.volume_controller.device_bg, + fg = fg, + border_color = Theme_config.volume_controller.device_border_color, + border_width = Theme_config.volume_controller.device_border_width, + shape = Theme_config.volume_controller.device_shape, + widget = wibox.container.background, + sink = device, + } + + if device_type == 'sink' then + device_widget:buttons(gtable.join( + abutton({}, 1, function() + self:set_default_sink(device) + end) + )) + elseif device_type == 'source' then + device_widget:buttons(gtable.join( + abutton({}, 1, function() + self:set_default_source(device) + end) + )) + end + + self:connect_signal('AC::device_changed', function(new_sink) + if device_widget.device == new_sink then + device_widget.bg = Theme_config.volume_controller.device_headphones_selected_bg + device_widget.fg = Theme_config.volume_controller.device_headphones_selected_fg + device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.device_headphones_selected_fg) + else + device_widget.bg = Theme_config.volume_controller.device_bg + device_widget.fg = fg + device_widget:get_children_by_id('icon')[1].image = gcolor.recolor_image(icondir .. 'volume-high.svg', icon_color) + end + end) + + hover.bg_hover { widget = device_widget } + + return device_widget +end + +---Get all sink devices +---@param callback function returns a list of sinks +function audio_controller:get_sink_devices_async(callback) + -- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n" + aspawn.easy_async_with_shell([=[ + LC_ALL=C pactl list sinks | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }' + ]=], function(stdout) + local sinks = wibox.layout.fixed.vertical {} + for line in stdout:gmatch('[^\r\n]+') do + -- Call the callback function with the name and description + local s, n = line:match('(.-);(.+)') + table.insert(sinks, self:get_device_widget(s, n, 'sink')) + end + self.sinks = sinks + callback() + end) +end + +---Get all source devices +---@param callback function returns a list of sources +function audio_controller:get_source_devices_async(callback) + -- This command gets all audio sources and their descriptions in this format: "source_name;source_description\n" + aspawn.easy_async_with_shell([=[ + LC_ALL=C pactl list sources | awk '/Name:/ { name=$0 } /Description:/ { sub(/Name: /, "", name); sub(/Description: /, "", $0); print name ";" $0 }' + ]=], function(stdout) + local sources = wibox.layout.fixed.vertical {} + for line in stdout:gmatch('[^\r\n]+') do + local s, n = line:match('(.-);(.+)') + table.insert(sources, self:get_device_widget(s, n, 'source')) + end + self.sources = sources + callback() + end) +end + +---Creates a new audio controller +---@return wibox.widget auio_controller the audio controller widget +function audio_controller.new() + local w = base.make_widget_from_value(wibox.widget { + { + { + { -- sink Device selector + { + { + resize = false, + image = gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + id = 'sink_dd_icon', + }, + { + { + text = 'Output Devices', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + id = 'sink_dd_shape', + bg = Theme_config.volume_controller.list_bg, + fg = Theme_config.volume_controller.list_headphones_fg, + shape = Theme_config.volume_controller.list_shape, + widget = wibox.container.background, + }, + { -- sink dropdown + { + { + { + spacing = dpi(10), + layout = require('src.lib.overflow_widget.overflow').vertical, + scrollbar_width = 0, + step = dpi(50), + id = 'sink_list', + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + border_color = Theme_config.volume_controller.list_border_color, + border_width = Theme_config.volume_controller.list_border_width, + id = 'sink_list_shape', + shape = Theme_config.volume_controller.list_shape, + widget = wibox.container.background, + }, + id = 'sink_height', + strategy = 'exact', + height = 0, + width = dpi(300), + widget = wibox.container.constraint, + }, + { -- Spacer + widget = wibox.container.background, + forced_height = dpi(10), + }, + { -- source Device selector + { + { + resize = false, + image = gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + id = 'source_dd_icon', + }, + { + { + text = 'Input Devices', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + id = 'source_dd_shape', + bg = Theme_config.volume_controller.list_bg, + fg = Theme_config.volume_controller.list_headphones_fg, + shape = Theme_config.volume_controller.list_shape, + widget = wibox.container.background, + }, + { -- source dropdown + { + { + { + spacing = dpi(10), + layout = require('src.lib.overflow_widget.overflow').vertical, + scrollbar_width = 0, + step = dpi(50), + id = 'source_list', + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + border_color = Theme_config.volume_controller.list_border_color, + border_width = Theme_config.volume_controller.list_border_width, + id = 'source_list_shape', + shape = Theme_config.volume_controller.list_shape, + widget = wibox.container.background, + }, + id = 'source_height', + strategy = 'exact', + height = 0, + width = dpi(300), + widget = wibox.container.constraint, + }, + { -- Spacer + widget = wibox.container.background, + forced_height = dpi(10), + }, + { -- sink volume slider + { + { + { + resize = true, + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icondir .. 'volume-high.svg', Theme_config.volume_controller.volume_fg), + id = 'sink_icon', + }, + widget = wibox.container.constraint, + width = dpi(26), + height = dpi(26), + strategy = 'exact', + }, + { + bar_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(5)) + end, + bar_height = dpi(5), + bar_color = Theme_config.volume_controller.border_color, + bar_active_color = Theme_config.volume_controller.volume_fg, + handle_color = Theme_config.volume_controller.volume_fg, + handle_shape = gshape.circle, + handle_border_color = Theme_config.volume_controller.volume_fg, + handle_width = dpi(15), + handle_cursor = 'left_ptr', + maximum = 100, + forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity + value = 50, + widget = wibox.widget.slider, + id = 'sink_slider', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.constraint, + width = dpi(300), + height = dpi(26), + strategy = 'exact', + }, + { -- Spacer + widget = wibox.container.background, + forced_height = dpi(10), + }, + { -- source volume slider + { + { + { + resize = true, + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.volume_fg), + id = 'source_icon', + }, + widget = wibox.container.constraint, + width = dpi(26), + height = dpi(26), + strategy = 'exact', + }, + { + bar_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(5)) + end, + bar_height = dpi(5), + bar_color = Theme_config.volume_controller.border_color, + bar_active_color = Theme_config.volume_controller.volume_fg, + handle_color = Theme_config.volume_controller.volume_fg, + handle_shape = gshape.circle, + handle_border_color = Theme_config.volume_controller.volume_fg, + handle_width = dpi(15), + handle_cursor = 'left_ptr', + maximum = 100, + forced_height = 0, -- No idea why its needed but it makes the widget not go into infinity + value = 50, + widget = wibox.widget.slider, + id = 'source_slider', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + + }, + widget = wibox.container.constraint, + width = dpi(400), + height = dpi(26), + strategy = 'exact', + }, + layout = wibox.layout.fixed.vertical, + }, + margins = dpi(15), + widget = wibox.container.margin, + }, + -- The parent margin doesn't render without an empty widget here??? + widget = wibox.container.margin, + }) + + assert(w, 'Failed to create volume controller widget') + + gtable.crush(w, audio_controller, true) + + local sink_icon = w:get_children_by_id('sink_icon')[1] + local sink_slider = w:get_children_by_id('sink_slider')[1] + + sink_slider:connect_signal('property::value', function(_, value) + audio_helper.set_sink_volume(value) + end) + + -- Set the volume and icon + audio_helper:connect_signal('sink::get', function(_, muted, volume) + volume = tonumber(volume) + assert(type(muted) == 'boolean' and type(volume) == 'number', 'audio::get signal expects boolean and number') + if w.sink_volume == volume and w.sink_muted == muted then return end + w.sink_volume = volume + w.sink_muted = muted + if muted then + sink_icon:set_image(gcolor.recolor_image(icondir .. 'volume-mute.svg', Theme_config.volume_controller.volume_fg)) + else + local icon = icondir .. 'volume' + if volume == 0 then + icon = icon .. '-mute' + elseif volume > 0 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 + + sink_slider:set_value(volume) + sink_icon:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_controller.volume_fg)) + end + end) + + local source_icon = w:get_children_by_id('source_icon')[1] + local source_slider = w:get_children_by_id('source_slider')[1] + + -- Microphone slider change event + source_slider:connect_signal('property::value', function(_, value) + audio_helper.set_source_volume(value) + end) + + --- Set the source volume and icon + audio_helper:connect_signal('source::get', function(_, muted, volume) + volume = tonumber(volume) + assert(type(muted) == 'boolean' and type(volume) == 'number', 'microphone::get signal expects boolean and number') + if w.source_volume == volume and w.source_muted == muted then return end + w.source_volume = volume + w.source_muted = muted + if muted then + source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg)) + else + if not volume then return end + source_slider:set_value(tonumber(volume)) + if volume > 0 then + source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone.svg', Theme_config.volume_controller.microphone_fg)) + else + source_icon:set_image(gcolor.recolor_image(icondir .. 'microphone-off.svg', Theme_config.volume_controller.microphone_fg)) + end + end + end) + + local sink_dd_shape = w:get_children_by_id('sink_dd_shape')[1] + local sink_height = w:get_children_by_id('sink_height')[1] + local sink_dd_icon = w:get_children_by_id('sink_dd_icon')[1] + + local rubato_timer = rubato.timed { + duration = 0.2, + pos = sink_height.height, + clamp_position = true, + subscribed = function(v) + sink_height.height = v + end, + } + + sink_dd_shape:buttons(gtable.join { + abutton({}, 1, function() + if sink_height.height == 0 then + local size = dpi((#w.sinks * 44) + ((#w.sinks - 1) * 10) + 20) + + if #w.sinks > 4 then + size = dpi(226) + end + rubato_timer.target = size + + sink_dd_shape.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + end + + sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color)) + else + rubato_timer.target = 0 + + sink_dd_shape.shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, 4) + end + + sink_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color)) + end + end), + }) + + local source_dd_shape = w:get_children_by_id('source_dd_shape')[1] + local source_height = w:get_children_by_id('source_height')[1] + local source_dd_icon = w:get_children_by_id('source_dd_icon')[1] + + local rubato_timer = rubato.timed { + duration = 0.2, + pos = source_height.height, + clamp_position = true, + subscribed = function(v) + source_height.height = v + end, + } + + source_dd_shape:buttons(gtable.join { + abutton({}, 1, function() + if source_height.height == 0 then + local size = dpi(((#w.sources * 44) + ((#w.sources - 1) * 10) + 20)) + + if #w.sources > 4 then + size = dpi(226) + end + + rubato_timer.target = size + + source_dd_shape.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + end + + source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color)) + else + rubato_timer.target = 0 + + source_dd_shape.shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, 4) + end + + source_dd_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.volume_controller.device_headphones_selected_icon_color)) + end + end), + }) + + local sink_list = w:get_children_by_id('sink_list')[1] + w:get_sink_devices_async(function() + sink_list.children = w.sinks + end) + + local source_list = w:get_children_by_id('source_list')[1] + w:get_source_devices_async(function() + source_list.children = w.sources + end) + + hover.bg_hover { widget = sink_dd_shape } + hover.bg_hover { widget = source_dd_shape } + return w +end + +return setmetatable(audio_controller, { __call = function() return audio_controller.new() end }) diff --git a/awesome/src/modules/audio/volume_controller.lua b/awesome/src/modules/audio/volume_controller.lua deleted file mode 100644 index 47445b0..0000000 --- a/awesome/src/modules/audio/volume_controller.lua +++ /dev/null @@ -1,553 +0,0 @@ ------------------------------------ --- This is the volume controller -- ------------------------------------ - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local gobject = require("gears.object") - -local capi = { - awesome = awesome, - mousegrabber = mousegrabber, -} - -local rubato = require("src.lib.rubato") - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/" - -local volume_controler = { mt = {} } - -function volume_controler.get_device_widget() - local device = wibox.widget { - { - { - { - id = "icon", - resize = false, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - spacing = dpi(10), - { - text = name, - id = "node", - widget = wibox.widget.textbox - }, - id = "device_layout", - layout = wibox.layout.fixed.horizontal - }, - id = "device_margin", - margins = dpi(9), - widget = wibox.container.margin - }, - id = "background", - bg = Theme_config.volume_controller.device_bg, - border_color = Theme_config.volume_controller.device_border_color, - border_width = Theme_config.volume_controller.device_border_width, - shape = Theme_config.volume_controller.device_shape, - widget = wibox.container.background - } - if true then - device:connect_signal( - "button::press", - function(_, _, _, key) - if key == 1 then - if node then - --awful.spawn("./.config/awesome/src/scripts/vol.sh set_sink " .. node) - --capi.awesome.emit_signal("update::bg_sink", node) - end - end - end - ) - --[[ capi.awesome.connect_signal( - "update::bg_sink", - function(new_node) - if node == new_node then - device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg", - Theme_config.volume_controller.device_icon_color) - device.bg = Theme_config.volume_controller.device_headphones_selected_bg - device.fg = Theme_config.volume_controller.device_headphones_selected_fg - Hover_signal(device) - else - device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg", - Theme_config.volume_controller.device_headphones_selected_icon_color) - device.bg = Theme_config.volume_controller.device_bg - device.fg = Theme_config.volume_controller.device_headphones_fg - Hover_signal(device) - end - end - ) ]] - else - device:connect_signal( - "button::press", - function(_, _, _, key) - if key == 1 then - if node then - --awful.spawn("./.config/awesome/src/scripts/mic.sh set_source " .. node) - --capi.awesome.emit_signal("update::bg_source", node) - end - end - end - ) - --[[ capi.awesome.connect_signal( - "update::bg_source", - function(new_node) - if node == new_node then - device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg", - Theme_config.volume_controller.device_icon_color) - device.bg = Theme_config.volume_controller.device_microphone_selected_bg - device.fg = Theme_config.volume_controller.device_microphone_selected_fg - Hover_signal(device) - else - device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "microphone.svg", - Theme_config.volume_controller.device_microphone_selected_icon_color) - device.bg = Theme_config.volume_controller.device_bg - device.fg = Theme_config.volume_controller.device_microphone_fg - Hover_signal(device) - end - end - ) ]] - end - return device -end - --- Get all source devices -function volume_controler:get_source_devices() - -end - --- Get all input devices -function volume_controler:get_input_devices() - -end - -function volume_controler:toggle() - volume_controler.popup.visible = not volume_controler.popup.visible -end - -function volume_controler.run(args) - - args = args or {} - - local ret = gobject {} - - local w = wibox.widget { - { - { - -- Audio Device selector - { - { - { - { - { - resize = false, - image = gears.color.recolor_image(icondir .. "menu-down.svg", - Theme_config.volume_controller.device_headphones_selected_icon_color), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "icon" - }, - id = "center", - halign = "center", - valign = "center", - widget = wibox.container.place, - }, - { - { - text = "Output Device", - widget = wibox.widget.textbox, - id = "device_name" - }, - margins = dpi(5), - widget = wibox.container.margin - }, - id = "audio_volume", - layout = wibox.layout.fixed.horizontal - }, - id = "audio_bg", - bg = Theme_config.volume_controller.list_bg, - fg = Theme_config.volume_controller.list_headphones_fg, - shape = Theme_config.volume_controller.list_shape, - widget = wibox.container.background - }, - id = "audio_selector_margin", - left = dpi(10), - right = dpi(10), - top = dpi(10), - widget = wibox.container.margin - }, - { - id = "volume_list", - widget = { - { - { - { - { - spacing = dpi(10), - layout = require("src.lib.overflow_widget.overflow").vertical, - scrollbar_width = 0, - step = dpi(50), - id = "volume_device_list", - }, - id = "margin", - margins = dpi(10), - widget = wibox.container.margin - }, - id = "place", - height = dpi(200), - strategy = "max", - widget = wibox.container.constraint - }, - border_color = Theme_config.volume_controller.list_border_color, - border_width = Theme_config.volume_controller.list_border_width, - id = "volume_device_background", - shape = Theme_config.volume_controller.list_shape, - widget = wibox.container.background - }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - forced_height = 0 - }, - -- Microphone selector - { - { - { - { - { - resize = false, - image = gears.color.recolor_image(icondir .. "menu-down.svg", - Theme_config.volume_controller.device_microphone_selected_icon_color), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "icon", - }, - id = "center", - halign = "center", - valign = "center", - widget = wibox.container.place, - }, - { - { - text = "Input Device", - widget = wibox.widget.textbox, - id = "device_name" - }, - margins = dpi(5), - widget = wibox.container.margin - }, - id = "mic_volume", - layout = wibox.layout.fixed.horizontal - }, - id = "mic_bg", - bg = Theme_config.volume_controller.list_bg, - fg = Theme_config.volume_controller.list_microphone_fg, - shape = Theme_config.volume_controller.selector_shape, - widget = wibox.container.background - }, - id = "mic_selector_margin", - left = dpi(10), - right = dpi(10), - top = dpi(10), - widget = wibox.container.margin - }, - { - id = "mic_list", - widget = { - { - { - { - { - spacing = dpi(10), - layout = require("src.lib.overflow_widget.overflow").vertical, - id = "volume_device_list", - scrollbar_width = 0, - step = dpi(50), - }, - id = "margin", - margins = dpi(10), - widget = wibox.container.margin - }, - id = "place", - height = dpi(200), - strategy = "max", - widget = wibox.container.constraint - }, - id = "volume_device_background", - border_color = Theme_config.volume_controller.list_border_color, - border_width = Theme_config.volume_controller.list_border_width, - shape = Theme_config.volume_controller.list_shape, - widget = wibox.container.background - }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - forced_height = 0 - }, - -- Audio volume slider - { - { - { - resize = false, - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_controller.volume_fg), - id = "icon", - }, - { - { - bar_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bar_height = dpi(5), - bar_color = Theme_config.volume_controller.border_color, - bar_active_color = Theme_config.volume_controller.volume_fg, - handle_color = Theme_config.volume_controller.volume_fg, - handle_shape = gears.shape.circle, - handle_border_color = Theme_config.volume_controller.volume_fg, - handle_width = dpi(12), - maximum = 100, - forced_height = dpi(26), - widget = wibox.widget.slider, - id = "slider" - }, - left = dpi(5), - id = "slider_margin", - widget = wibox.container.margin - }, - id = "audio_volume", - layout = wibox.layout.align.horizontal - }, - id = "audio_volume_margin", - top = dpi(10), - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - -- Microphone volume slider - { - { - { - resize = false, - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "microphone.svg", Theme_config.volume_controller.microphone_fg), - id = "icon" - }, - { - { - bar_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bar_height = dpi(5), - bar_color = Theme_config.volume_controller.device_border_color, - bar_active_color = Theme_config.volume_controller.microphone_fg, - handle_color = Theme_config.volume_controller.microphone_fg, - handle_shape = gears.shape.circle, - handle_border_color = Theme_config.volume_controller.microphone_fg, - handle_width = dpi(12), - maximum = 100, - forced_height = dpi(26), - widget = wibox.widget.slider, - id = "slider" - }, - left = dpi(5), - id = "slider_margin", - widget = wibox.container.margin - }, - id = "mic_volume", - layout = wibox.layout.align.horizontal - }, - id = "mic_volume_margin", - left = dpi(10), - right = dpi(10), - top = dpi(10), - widget = wibox.container.margin - }, - id = "controller_layout", - layout = wibox.layout.fixed.vertical - }, - id = "controller_margin", - margins = dpi(10), - widget = wibox.container.margin - }, - bg = Theme_config.volume_controller.bg, - border_color = Theme_config.volume_controller.border_color, - border_width = Theme_config.volume_controller.border_width, - shape = Theme_config.volume_controller.shape, - forced_width = dpi(400), - widget = wibox.container.background - } - - ret.widget = w - ret.audio_dropdown = w:get_children_by_id("audio_list")[1] - ret.mic_dropdown = w:get_children_by_id("mic_list")[1] - ret.audio_slider = w:get_children_by_id("slider")[1] - ret.mic_slider = w:get_children_by_id("slider")[1] - - -- Main container - ret.popup = awful.popup { - widget = w, - ontop = true, - bg = Theme_config.volume_controller.bg, - stretch = false, - visible = false, - screen = args.screen, - --! Calculate the popup position instead of hardcoding it - placement = function(c) awful.placement.align(c, - { position = "top_right", margins = { right = dpi(305), top = dpi(60) } }) - end, - shape = Theme_config.volume_controller.shape, - } - - -- Set the volume and icon - capi.awesome.connect_signal( - "audio::get", - function(muted, volume) - if muted then - volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color - .recolor_image(icondir .. "volume-mute.svg", Theme_config.volume_controller.volume_fg)) - else - volume = tonumber(volume) - if not volume then - return - end - local icon = icondir .. "volume" - if volume < 1 then - icon = icon .. "-mute" - elseif volume >= 1 and volume < 34 then - icon = icon .. "-low" - elseif volume >= 34 and volume < 67 then - icon = icon .. "-medium" - elseif volume >= 67 then - icon = icon .. "-high" - end - - volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.slider_margin.slider: - set_value(volume) - volume_controller.controller_margin.controller_layout.audio_volume_margin.audio_volume.icon:set_image(gears.color - .recolor_image(icon - .. ".svg", Theme_config.volume_controller.volume_fg)) - end - end - ) - - -- Get microphone volume - capi.awesome.connect_signal( - "microphone::get", - function(muted, volume) - if muted then - --volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(0)) - volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir - .. "microphone-off.svg", Theme_config.volume_controller.microphone_fg)) - else - volume = tonumber(volume) - if not volume then - return - end - volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(volume)) - if volume > 0 then - volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir - .. "microphone.svg", Theme_config.volume_controller.microphone_fg)) - else - volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir - .. "microphone-off.svg", Theme_config.volume_controller.microphone_fg)) - end - end - end - ) - - -- Microphone slider change event - ret.widget:connect_signal( - "property::value", - function() - end - ) - - -- Slide animation - ret.audio_dropdown:connect_signal( - "button::press", - function(_, _, _, key) - if key == 1 then - local rubato_timer = rubato.timed { - duration = 0.4, - intro = 0.1, - outro = 0.1, - pos = mic_list.forced_height, - easing = rubato.linear, - subscribed = function(v) - mic_list.forced_height = v - end - } - if mic_list.forced_height == 0 then - rubato_timer.target = dpi(200) - mic_selector_margin.mic_bg.shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg", - Theme_config.volume_controller.device_microphone_selected_icon_color)) - else - rubato_timer.target = 0 - mic_bg.shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(4)) - end - mic_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg", - Theme_config.volume_controller.device_microphone_selected_icon_color)) - end - end - end - ) - - -- Slide animation - ret.mic_dropdown:connect_signal( - "button::press", - function(_, _, _, key) - if key == 1 then - local rubato_timer = rubato.timed { - duration = 0.4, - intro = 0.1, - outro = 0.1, - pos = volume_list.forced_height, - easing = rubato.linear, - subscribed = function(v) - volume_list.forced_height = v - end - } - if volume_list.forced_height == 0 then - rubato_timer.target = dpi(200) - audio_bg.shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-up.svg", - Theme_config.volume_controller.device_headphones_selected_icon_color)) - else - rubato_timer.target = 0 - audio_bg.shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(4)) - end - audio_volume.icon:set_image(gears.color.recolor_image(icondir .. "menu-down.svg", - Theme_config.volume_controller.device_headphones_selected_icon_color)) - end - end - end - ) - - return ret -end - -function volume_controler.mt:__call(...) - return volume_controler.run(...) -end - -return setmetatable(volume_controler, volume_controler.mt) diff --git a/awesome/src/modules/audio/volume_osd.lua b/awesome/src/modules/audio/volume_osd.lua index d53a145..54c5233 100644 --- a/awesome/src/modules/audio/volume_osd.lua +++ b/awesome/src/modules/audio/volume_osd.lua @@ -3,151 +3,136 @@ ----------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local gobject = require("gears.object") +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +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 capi = { - awesome = awesome, - mouse = mouse, -} +local audio_helper = require('src.tools.helpers.audio') -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/' -local osd = { mt = {} } +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 ret = gobject {} - - ret.w = wibox.widget { - { + local w = apopup { + widget = { { - { -- Volume Icon - image = gears.color.recolor_image(icondir .. "volume-high.svg", Theme_config.volume_osd.icon_color), - valign = "center", - halign = "center", - resize = false, - id = "icon", - widget = wibox.widget.imagebox - }, - { -- Volume Bar - { + { + { -- Volume Icon { - id = "progressbar1", - color = Theme_config.volume_osd.bar_bg_active, - background_color = Theme_config.volume_osd.bar_bg, - max_value = 100, - value = 50, - forced_height = dpi(6), - shape = function(cr, width, heigth) - gears.shape.rounded_bar(cr, width, heigth, dpi(6)) - end, - widget = wibox.widget.progressbar + image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.volume_osd.icon_color), + valign = 'center', + halign = 'center', + resize = true, + id = 'icon_role', + widget = wibox.widget.imagebox, }, - id = "progressbar_container2", - halign = "center", - valign = "center", - widget = wibox.container.place + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', }, - id = "progressbar_container", - width = dpi(240), - heigth = dpi(20), - stragety = "max", - widget = wibox.container.constraint + { -- Volume Bar + { + { + id = 'progressbar', + color = Theme_config.volume_osd.bar_bg_active, + background_color = Theme_config.volume_osd.bar_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, + }, + { -- Volume text + widget = wibox.widget.textbox, + id = 'text_role', + text = '0', + valign = 'center', + halign = 'center', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, }, - id = "layout1", - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + left = dpi(10), + right = dpi(10), + top = dpi(20), + bottom = dpi(20), + widget = wibox.container.margin, }, - id = "margin", - margins = dpi(10), - widget = wibox.container.margin + shape = Theme_config.volume_osd.shape, + widget = wibox.container.background, }, - forced_width = dpi(300), - forced_height = dpi(80), - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(12)) - end, + ontop = true, + stretch = false, + visible = false, border_color = Theme_config.volume_osd.border_color, border_width = Theme_config.volume_osd.border_width, fg = Theme_config.volume_osd.fg, bg = Theme_config.volume_osd.bg, - widget = wibox.container.background + screen = 1, + placement = function(c) aplacement.bottom(c, { margins = dpi(20) }) end, } - local volume_container = awful.popup { - widget = ret.w, - ontop = true, - stretch = false, - visible = false, - screen = args.screen, - placement = function(c) awful.placement.bottom_left(c, { margins = dpi(20) }) end, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(14)) - end - } + gtable.crush(w, osd) - local hide_volume_osd = gears.timer { + w.timer = gtimer { timeout = 2, autostart = true, callback = function() - volume_container.visible = false - end + w.visible = false + end, } - capi.awesome.connect_signal( - "audio::get", - function(muted, volume) - if muted then - ret.w:get_children_by_id("icon")[1] - :set_image(gears.color.recolor_image( - icondir .. "volume-mute" .. ".svg", Theme_config.volume_osd.icon_color)) - ret.w:get_children_by_id("progressbar1")[1].value = tonumber(0) - else - volume = tonumber(volume) - if not volume then - return - end - ret.w:get_children_by_id("progressbar1")[1].value = tonumber(volume) - local icon = icondir .. "volume" - if volume < 1 then - icon = icon .. "-mute" - elseif volume >= 1 and volume < 34 then - icon = icon .. "-low" - elseif volume >= 34 and volume < 67 then - icon = icon .. "-medium" - elseif volume >= 67 then - icon = icon .. "-high" - end - ret.w:get_children_by_id("icon")[1]:set_image(gears.color.recolor_image(icon .. ".svg", - Theme_config.volume_osd.icon_color)) + 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', Theme_config.volume_osd.icon_color)) + 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 - end - ) - capi.awesome.connect_signal( - "widget::volume_osd:rerun", - function() - if capi.mouse.screen == args.screen then - volume_container.visible = true - if hide_volume_osd.started then - hide_volume_osd:again() - else - hide_volume_osd:start() - end - end + w.widget:get_children_by_id('icon_role')[1]:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.volume_osd.icon_color)) + w.widget:get_children_by_id('text_role')[1].text = volume end - ) + w:run() + end) + + return w end -function osd.mt:__call(...) - return osd.new(...) -end - -return setmetatable(osd, osd.mt) +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 dc846ec..2c4480c 100644 --- a/awesome/src/modules/bluetooth/device.lua +++ b/awesome/src/modules/bluetooth/device.lua @@ -3,23 +3,24 @@ -------------------------------------- -- Awesome Libs -local abutton = require("awful.button") -local awidget = require("awful.widget") -local base = require("wibox.widget.base") -local dpi = require("beautiful").xresources.apply_dpi -local gcolor = require("gears").color -local gfilesystem = require("gears").filesystem -local gtable = require("gears").table -local lgi = require("lgi") -local wibox = require("wibox") +local abutton = require('awful.button') +local awidget = require('awful.widget') +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears').color +local gfilesystem = require('gears').filesystem +local gtable = require('gears').table +local lgi = require('lgi') +local wibox = require('wibox') -- Own libs -local context_menu = require("src.modules.context_menu") +local context_menu = require('src.modules.context_menu.init') +local hover = require('src.tools.hover') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/' local capi = { - awesome = awesome + awesome = awesome, } local device = { mt = {} } @@ -33,7 +34,7 @@ function device:layout(_, width, height) end function device:fit(context, width, height) - local w, h = 0, 0 + local w, h = 0, 0 ---@type number|nil, number|nil if self._private.widget then w, h = base.fit_widget(self, context, self._private.widget, width, height) end @@ -48,29 +49,14 @@ end --#endregion +local dbus_proxy = require('dbus_proxy') --- Connect to a device if not connected else disconnect function device:toggle_connect() + if not self.device.Paired then + self:toggle_pair() + return + end if not self.device.Connected then - - --TODO: Implement device passcode support, I have no idea how to get the - --TODO: Methods from Agent1 implemented - --[[ self._private.AgentManager1 = dbus_proxy.Proxy:new { - bus = dbus_proxy.Bus.SYSTEM, - name = "org.bluez", - path = "/org/bluez", - interface = "org.bluez.AgentManager1" - } - - self._private.Agent1 = dbus_proxy.Proxy:new { - bus = dbus_proxy.Bus.SYSTEM, - name = "org.bluez", - path = "/org/bluez", - interface = "org.bluez.Agent1", - } - - self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, "") - self._private.AgentManager1:RequestDefaultAgent(self._private.Agent1.object_path) ]] - self.device:ConnectAsync() else self.device:DisconnectAsync() @@ -79,37 +65,52 @@ end --- Pair to a device if not paired else unpair function device:toggle_pair() - if self.device.Paired then + if not self.device.Paired then + self._private.AgentManager1 = dbus_proxy.Proxy:new { + bus = dbus_proxy.Bus.SYSTEM, + name = 'org.bluez', + path = '/org/bluez', + interface = 'org.bluez.AgentManager1', + } + + self._private.Agent1 = dbus_proxy.Proxy:new { + bus = dbus_proxy.Bus.SYSTEM, + name = 'org.bluez', + path = '/org/bluez', + interface = 'org.bluez.Agent1', + } + + self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, 'KeyboardDisplay') self.device:PairAsync() else - self.device:CancelPairingAsync() + --Remove via adapter end end --- Trust a device if not trusted else untrust function device:toggle_trusted() - self.device:Set("org.bluez.Device1", "Trusted", lgi.GLib.Variant("b", not self.device.Trusted)) - self.device.Trusted = { signature = "b", value = not self.device.Trusted } + self.device:Set('org.bluez.Device1', 'Trusted', lgi.GLib.Variant('b', not self.device.Trusted)) + self.device.Trusted = { signature = 'b', value = not self.device.Trusted } end ---Rename a device alias ---@param newname string New name, if empty the device name will be reset ---@return string name The new or old name depending if the string was empty or not function device:rename(newname) - self.device:Set("org.bluez.Device1", "Alias", lgi.GLib.Variant("s", newname)) - self.device.Alias = { signature = "s", value = newname } - return self.device:Get("org.bluez.Device1", "Alias") + self.device:Set('org.bluez.Device1', 'Alias', lgi.GLib.Variant('s', newname)) + self.device.Alias = { signature = 's', value = newname } + return self.device:Get('org.bluez.Device1', 'Alias') end function device.new(args) args = args or {} - local icon = device.Icon or "bluetooth-on" + local icon = device.Icon or 'bluetooth-on' local inputbox = awidget.inputbox { text = args.device.Alias or args.device.Name, - halign = "left", - valign = "center", + halign = 'left', + valign = 'center', } local ret = base.make_widget_from_value(wibox.widget { @@ -119,78 +120,80 @@ function device.new(args) { { image = gcolor.recolor_image( - icondir .. icon .. ".svg", Theme_config.bluetooth_controller.icon_color), + icondir .. icon .. '.svg', Theme_config.bluetooth_controller.icon_color), resize = false, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, }, - strategy = "exact", + strategy = 'exact', width = dpi(24), height = dpi(24), - widget = wibox.container.constraint + widget = wibox.container.constraint, }, { inputbox, widget = wibox.container.constraint, - strategy = "exact", + strategy = 'exact', width = dpi(300), - id = "const" + id = 'const', }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, { -- Spacing forced_width = dpi(10), - widget = wibox.container.background + widget = wibox.container.background, }, { { { { { - id = "con", + id = 'con', resize = false, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, }, - strategy = "exact", + strategy = 'exact', width = dpi(24), height = dpi(24), - widget = wibox.container.constraint + widget = wibox.container.constraint, }, margins = dpi(2), - widget = wibox.container.margin + widget = wibox.container.margin, }, shape = Theme_config.bluetooth_controller.icon_shape, bg = Theme_config.bluetooth_controller.con_button_color, - widget = wibox.container.background + widget = wibox.container.background, }, margin = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.bluetooth_controller.device_bg, fg = Theme_config.bluetooth_controller.device_fg, border_color = Theme_config.bluetooth_controller.device_border_color, border_width = Theme_config.bluetooth_controller.device_border_width, - id = "background", + id = 'background', shape = Theme_config.bluetooth_controller.device_shape, - widget = wibox.container.background + widget = wibox.container.background, }) + assert(ret, 'Failed to create widget') + gtable.crush(ret, device, true) ret.device = args.device or {} -- Set the image of the connection button depending on the connection state - ret:get_children_by_id("con")[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. "link.svg" or - icondir .. "link-off.svg", + ret:get_children_by_id('con')[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. 'link.svg' or + icondir .. 'link-off.svg', Theme_config.bluetooth_controller.icon_color_dark) local cm = context_menu { @@ -201,78 +204,82 @@ function device.new(args) { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role", + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, }, spacing = dpi(10), entries = { { -- Connect/Disconnect a device - name = ret.device.Connected and "Disconnect" or "Connect", - icon = gcolor.recolor_image(ret.device.Connected and icondir .. "bluetooth-off.svg" or - icondir .. "bluetooth-on.svg", + name = ret.device.Connected and 'Disconnect' or 'Connect', + icon = gcolor.recolor_image(ret.device.Connected and icondir .. 'bluetooth-off.svg' or + icondir .. 'bluetooth-on.svg', Theme_config.bluetooth_controller.icon_color), callback = function() ret:toggle_connect() end, - id = "connected" + id = 'connected', }, { -- Pair/Unpair a device - name = "Pair", - icon = gcolor.recolor_image(ret.device.Paired and icondir .. "link-off.svg" or - icondir .. "link.svg", + name = 'Pair', + icon = gcolor.recolor_image(ret.device.Paired and icondir .. 'link-off.svg' or + icondir .. 'link.svg', Theme_config.bluetooth_controller.icon_color), callback = function() ret:toggle_pair() - end + end, }, { -- Trust/Untrust a device - name = ret.device.Trusted and "Untrust" or "Trust", - icon = gcolor.recolor_image(ret.device.Trusted and icondir .. "untrusted.svg" or icondir .. "trusted.svg", + name = ret.device.Trusted and 'Untrust' or 'Trust', + icon = gcolor.recolor_image(ret.device.Trusted and icondir .. 'untrusted.svg' or icondir .. 'trusted.svg', Theme_config.bluetooth_controller.icon_color), callback = function() ret:toggle_trusted() end, - id = "trusted" + id = 'trusted', }, { -- Rename a device - name = "Rename", - icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.bluetooth_controller.icon_color), + name = 'Rename', + icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.bluetooth_controller.icon_color), callback = function() inputbox:focus() - inputbox:connect_signal("submit", function(text) + inputbox:connect_signal('submit', function(text) text = text:get_text() inputbox.markup = ret:rename(text) end) - end + end, }, { -- Remove a device - name = "Remove", - icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.bluetooth_controller.icon_color), + name = 'Remove', + icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.bluetooth_controller.icon_color), callback = function() args.remove_callback(ret.device) - end - } - } + end, + }, + }, } + cm:connect_signal('mouse::leave', function() + cm.visible = false + end) + ret:buttons(gtable.join( abutton({}, 1, function() -- Toggle the connection state @@ -281,19 +288,19 @@ function device.new(args) abutton({}, 3, function() -- Show the context menu and update its entrie names for _, value in ipairs(cm.widget.children) do - value.id = value.id or "" - if value.id:match("connected") then - value:get_children_by_id("text_role")[1].text = ret.device.Connected and "Disconnect" or "Connect" - value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Connected and - icondir .. "bluetooth-off.svg" or icondir .. "bluetooth-on.svg", + value.id = value.id or '' + if value.id:match('connected') then + value:get_children_by_id('text_role')[1].text = ret.device.Connected and 'Disconnect' or 'Connect' + value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Connected and + icondir .. 'bluetooth-off.svg' or icondir .. 'bluetooth-on.svg', Theme_config.bluetooth_controller.icon_color) - elseif value.id:match("trusted") then - value:get_children_by_id("text_role")[1].text = ret.device.Trusted and "Untrust" or "Trust" - value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Trusted and - icondir .. "untrusted.svg" or icondir .. "trusted.svg", Theme_config.bluetooth_controller.icon_color) - elseif value.id:match("paired") then - value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Paired and - icondir .. "link-off.svg" or icondir .. "link.svg", Theme_config.bluetooth_controller.icon_color) + elseif value.id:match('trusted') then + value:get_children_by_id('text_role')[1].text = ret.device.Trusted and 'Untrust' or 'Trust' + value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Trusted and + icondir .. 'untrusted.svg' or icondir .. 'trusted.svg', Theme_config.bluetooth_controller.icon_color) + elseif value.id:match('paired') then + value:get_children_by_id('icon_role')[1].image = gcolor.recolor_image(ret.device.Paired and + icondir .. 'link-off.svg' or icondir .. 'link.svg', Theme_config.bluetooth_controller.icon_color) end end cm:toggle() @@ -301,13 +308,13 @@ function device.new(args) )) -- Update the updated device icon - capi.awesome.connect_signal(ret.device.object_path .. "_updated", function(d) - ret:get_children_by_id("con")[1].image = gcolor.recolor_image(d.Connected and icondir .. "link.svg" or - icondir .. "link-off.svg", + capi.awesome.connect_signal(ret.device.object_path .. '_updated', function(d) + ret:get_children_by_id('con')[1].image = gcolor.recolor_image(d.Connected and icondir .. 'link.svg' or + icondir .. 'link-off.svg', Theme_config.bluetooth_controller.icon_color_dark) end) - Hover_signal(ret) + hover.bg_hover { widget = ret } return ret end diff --git a/awesome/src/modules/bluetooth/init.lua b/awesome/src/modules/bluetooth/init.lua index ee9f414..09904e1 100644 --- a/awesome/src/modules/bluetooth/init.lua +++ b/awesome/src/modules/bluetooth/init.lua @@ -3,28 +3,29 @@ -------------------------------------- -- Awesome Libs -local abutton = require("awful.button") -local aspawn = require("awful.spawn") -local base = require("wibox.widget.base") -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 abutton = require('awful.button') +local aspawn = require('awful.spawn') +local base = require('wibox.widget.base') +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') -- Third party libs -local rubato = require("src.lib.rubato") +local rubato = require('src.lib.rubato') +local hover = require('src.tools.hover') -- Own libs -local bt_device = require("src.modules.bluetooth.device") -local dnd_widget = require("awful.widget.toggle_widget") +local bt_device = require('src.modules.bluetooth.device') +local dnd_widget = require('awful.widget.toggle_widget') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/' local capi = { awesome = awesome, @@ -61,13 +62,13 @@ end ---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 + 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 + return self:get_children_by_id('discovered_device_list')[1].children end --- Remove a device by first disconnecting it async then removing it @@ -81,8 +82,8 @@ end 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] + 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 @@ -117,6 +118,7 @@ function bluetooth:add_device(device, object_path) self:remove_device_information(device) end, }) + self:emit_signal('device::added_connected') else dlist:add(bt_device { device = device, @@ -125,22 +127,25 @@ function bluetooth:add_device(device, object_path) self:remove_device_information(device) end, }) + self:emit_signal('device::added_discovered') 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] + 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 then + 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 @@ -159,42 +164,42 @@ end 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:Set('org.bluez.Adapter1', 'Powered', lgi.GLib.Variant('b', not powered)) self._private.Adapter1.Powered = { - signature = "b", - value = not powered + signature = 'b', + value = not powered, } end --- Open blueman-manager function bluetooth:open_settings() - aspawn("blueman-manager") + 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 + 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 + 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 + 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 + if (not Device1.Name) or (Device1.Name == '') then return end -- For some reason it notifies twice or thrice local just_notified = false @@ -205,29 +210,29 @@ function bluetooth:get_device_info(object_path) single_shot = true, callback = function() just_notified = false - end + 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 changed_props['Connected'] ~= nil then if not just_notified then - naughty.notification({ - app_icon = icondir .. "bluetooth-on.svg", - app_name = "Bluetooth", + naughty.notification { + app_icon = icondir .. 'bluetooth-on.svg', + app_name = 'Bluetooth', title = Device1.Name, - icon = gcolor.recolor_image(icondir .. Device1.Icon .. ".svg", Theme_config.bluetooth_controller.icon_color), + 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", - }) + 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") + capi.awesome.emit_signal(object_path .. '_updated', Device1) + end, 'PropertiesChanged') self:add_device(Device1, object_path) end @@ -236,13 +241,12 @@ end ---@param powered boolean the powered state of the adapter local function send_state_notification(powered) naughty.notification { - app_icon = gcolor.recolor_image(icondir .. "bluetooth-on.svg", Theme_config.bluetooth_controller.icon_color), - app_name = "Bluetooth", - title = "Bluetooth", - message = powered and "Enabled" or "Disabled", - icon = gcolor.recolor_image(powered and icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg", - Theme_config.bluetooth_controller.icon_color), - category = powered and "device.added" or "device.removed", + 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 @@ -250,7 +254,7 @@ 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 ret = base.make_widget_from_value { { { { @@ -258,128 +262,132 @@ function bluetooth.new(args) { { resize = false, - image = gcolor.recolor_image(icondir .. "menu-down.svg", + image = gcolor.recolor_image(icondir .. 'menu-down.svg', Theme_config.bluetooth_controller.connected_icon_color), widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "connected_icon" + valign = 'center', + halign = 'center', + id = 'connected_icon', }, { { - text = "Paired Devices", - valign = "center", - halign = "center", + text = 'Paired Devices', + valign = 'center', + halign = 'center', widget = wibox.widget.textbox, }, margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, bg = Theme_config.bluetooth_controller.connected_bg, fg = Theme_config.bluetooth_controller.connected_fg, shape = Theme_config.bluetooth_controller.connected_shape, widget = wibox.container.background, - id = "connected_bg" + id = 'connected_bg', }, - id = "connected_margin", - widget = wibox.container.margin + 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" + { + 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, }, - id = "margin", - margins = dpi(10), - widget = wibox.container.margin + border_color = Theme_config.bluetooth_controller.con_device_border_color, + border_width = Theme_config.bluetooth_controller.con_device_border_width, + shape = Theme_config.bluetooth_controller.con_device_shape, + widget = wibox.container.background, }, - border_color = Theme_config.bluetooth_controller.con_device_border_color, - border_width = Theme_config.bluetooth_controller.con_device_border_width, - shape = Theme_config.bluetooth_controller.con_device_shape, - widget = wibox.container.background, - forced_height = 0, - id = "connected_list", + widget = wibox.container.constraint, + strategy = 'exact', + height = 0, + id = 'connected_list', }, { { { { resize = false, - image = gcolor.recolor_image(icondir .. "menu-down.svg", + image = gcolor.recolor_image(icondir .. 'menu-down.svg', Theme_config.bluetooth_controller.discovered_icon_color), widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "discovered_icon", + valign = 'center', + halign = 'center', + id = 'discovered_icon', }, { { - text = "Nearby Devices", - valign = "center", - halign = "center", + text = 'Nearby Devices', + valign = 'center', + halign = 'center', widget = wibox.widget.textbox, }, margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - id = "discovered_bg", + id = 'discovered_bg', bg = Theme_config.bluetooth_controller.discovered_bg, fg = Theme_config.bluetooth_controller.discovered_fg, shape = Theme_config.bluetooth_controller.discovered_shape, - widget = wibox.container.background + widget = wibox.container.background, }, - id = "discovered_margin", + id = 'discovered_margin', top = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, { { { - id = "discovered_device_list", + id = 'discovered_device_list', spacing = dpi(10), step = dpi(50), - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, scrollbar_width = 0, }, margins = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, border_color = Theme_config.bluetooth_controller.con_device_border_color, border_width = Theme_config.bluetooth_controller.con_device_border_width, shape = Theme_config.bluetooth_controller.con_device_shape, widget = wibox.container.background, forced_height = 0, - id = "discovered_list", + id = 'discovered_list', }, { { -- action buttons { dnd_widget { color = Theme_config.bluetooth_controller.power_bg, - size = dpi(40) + size = dpi(40), }, - id = "dnd", + id = 'dnd', widget = wibox.container.place, - valign = "center", - halign = "center" + valign = 'center', + halign = 'center', }, nil, { -- refresh { { - image = gcolor.recolor_image(icondir .. "refresh.svg", + image = gcolor.recolor_image(icondir .. 'refresh.svg', Theme_config.bluetooth_controller.refresh_icon_color), resize = false, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', widget = wibox.widget.imagebox, }, widget = wibox.container.margin, @@ -387,28 +395,30 @@ function bluetooth.new(args) }, shape = Theme_config.bluetooth_controller.refresh_shape, bg = Theme_config.bluetooth_controller.refresh_bg, - id = "scan", - widget = wibox.container.background + id = 'scan', + widget = wibox.container.background, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.margin, top = dpi(10), }, - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, margins = dpi(15), widget = wibox.container.margin, }, margins = dpi(15), 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() + local dnd = ret:get_children_by_id('dnd')[1]:get_widget() -- Toggle bluetooth on or off - dnd:connect_signal("dnd::toggle", function(enable) + dnd:connect_signal('dnd::toggle', function() ret:toggle() end) @@ -418,36 +428,38 @@ function bluetooth.new(args) -- 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 = "/" + 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" + 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" + 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") + end, 'InterfacesAdded') -- Connect to the ObjectManager's InterfacesRemoved signal ret._private.ObjectManager:connect_signal(function(_, interface) ret:remove_device(interface) - end, "InterfacesRemoved") + end, 'InterfacesRemoved') -- Connect to the Adapter1's PropertiesChanged signal ret._private.Adapter1Properties:connect_signal(function(_, _, data) @@ -459,9 +471,9 @@ function bluetooth.new(args) else dnd:set_disabled() end - ret:emit_signal("bluetooth::status", data.Powered) + ret:emit_signal('bluetooth::status', data.Powered) end - end, "PropertiesChanged") + end, 'PropertiesChanged') gtimer.delayed_call(function() for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do @@ -473,100 +485,160 @@ function bluetooth.new(args) else dnd:set_disabled() end - ret:emit_signal("bluetooth::status", ret._private.Adapter1.Powered) + 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] - local connected_icon = ret:get_children_by_id("connected_icon")[1] + 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] + + local connected_animation = rubato.timed { + duration = 0.2, + pos = connected_list.height, + clamp_position = true, + subscribed = function(v) + connected_list.height = v + end, + } + + 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) - connected_margin:connect_signal( - "button::press", - function() - local rubato_timer = rubato.timed { - duration = 0.2, - pos = connected_list.forced_height, - easing = rubato.linear, - subscribed = function(v) - connected_list.forced_height = v - end - } - if connected_list.forced_height == 0 then - local size = (#ret:get_paired_devices() * 60) - if size < 210 then - rubato_timer.target = dpi(size) - end - if size > 0 then - 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", - Theme_config.bluetooth_controller.connected_icon_color)) - end - else - rubato_timer.target = 0 connected_margin.connected_bg.shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, 4) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) end - connected_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg", + + connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', Theme_config.bluetooth_controller.connected_icon_color)) end end - ) + 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] + ret:connect_signal('device::removed_connected', function(device) + local size = (#ret:get_paired_devices() * 60) + if size < 210 then + connected_animation.target = dpi(size) - discovered_margin:connect_signal( - "button::press", - function() - local rubato_timer = rubato.timed { - duration = 0.2, - pos = discovered_list.forced_height, - easing = rubato.linear, - subscribed = function(v) - discovered_list.forced_height = v - end - } + connected_margin.connected_bg.shape = function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) + end - if discovered_list.forced_height == 0 then - local size = (#ret:get_discovered_devices() * 60) - if size > 210 then - size = 210 + connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + Theme_config.bluetooth_controller.connected_icon_color)) + 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)) end - if size > 0 then - rubato_timer.target = dpi(size) - discovered_margin.discovered_bg.shape = function(cr, width, height) - gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) - end - discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg", - Theme_config.bluetooth_controller.discovered_icon_color)) + + connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', + Theme_config.bluetooth_controller.connected_icon_color)) + end + else + connected_animation.target = 0 + connected_margin.connected_bg.shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, 4) + end + + connected_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.bluetooth_controller.connected_icon_color)) + end + 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 - else - rubato_timer.target = 0 - discovered_bg.shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, 4) - end - discovered_icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg", + discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', Theme_config.bluetooth_controller.discovered_icon_color)) 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', + Theme_config.bluetooth_controller.discovered_icon_color)) + 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', + Theme_config.bluetooth_controller.discovered_icon_color)) + end + else + discovered_animation.target = 0 + discovered_bg.shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, 4) + end + discovered_icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', + Theme_config.bluetooth_controller.discovered_icon_color)) + end + end) --#endregion -- Add buttons to the scan button - ret:get_children_by_id("scan")[1]:buttons({ + ret:get_children_by_id('scan')[1]:buttons { abutton({}, 1, function() ret:scan() - end) - }) + end), + } - Hover_signal(ret:get_children_by_id("scan")[1]) + 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 } return ret end diff --git a/awesome/src/modules/brightness/brightness_osd.lua b/awesome/src/modules/brightness/brightness_osd.lua index eb226fc..e89e179 100644 --- a/awesome/src/modules/brightness/brightness_osd.lua +++ b/awesome/src/modules/brightness/brightness_osd.lua @@ -3,17 +3,17 @@ --------------------------------------- -- Awesome Libs -local aplacement = require("awful.placement") -local apopup = require("awful.popup") -local dpi = require("beautiful").xresources.apply_dpi -local gcolor = require("gears.color") -local gfilesystem = require("gears.filesystem") -local gtable = require("gears.table") -local gshape = require("gears.shape") -local gtimer = require("gears.timer") -local wibox = require("wibox") +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +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 backlight_helper = require('src.tools.helpers.backlight') local capi = { awesome = awesome, @@ -21,125 +21,119 @@ local capi = { } -- Icon directory path -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/brightness/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/brightness/' local brightness_osd = { mt = {} } -- Hide the brightness_osd after 3 seconds -function brightness_osd:hide() - self.timer:stop(false) -end - --- Rerun the timer -function brightness_osd:rerun() +function brightness_osd:run() self.visible = true - self.timer:again(true) -end - --- Show the brightness_osd for 3 seconds -function brightness_osd:show() - self.visible = true - self.timer:start(true) + if self.timer.started then + self.timer:again() + else + self.timer:start() + end end function brightness_osd.new(args) args = args or {} - local osd = apopup { + local w = apopup { widget = { { { { -- Brightness Icon - image = gcolor.recolor_image(icondir .. "brightness-high.svg", Theme_config.brightness_osd.icon_color), - valign = "center", - halign = "center", - resize = false, - id = "icon", - widget = wibox.widget.imagebox + { + image = gcolor.recolor_image(icondir .. 'volume-off.svg', Theme_config.brightness_ods.icon_color), + 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 = "progressbar1", - color = Theme_config.brightness_osd.bar_bg_active, - background_color = Theme_config.brightness_osd.bar_bg, + id = 'progressbar', + color = Theme_config.brightness_ods.bar_bg_active, + background_color = Theme_config.brightness_ods.bar_bg, max_value = 100, value = 0, - forced_height = dpi(6), - shape = function(cr, width, height) - gshape.rounded_bar(cr, width, height, dpi(6)) - end, + shape = gshape.rounded_rect, widget = wibox.widget.progressbar }, - id = "progressbar_container2", - halign = "center", - valign = "center", - widget = wibox.container.place + widget = wibox.container.constraint, + width = dpi(250), + height = dpi(5), }, - id = "progressbar_container", - width = dpi(240), - heigth = dpi(20), - stragety = "max", - widget = wibox.container.constraint + widget = wibox.container.place + }, + { -- Brightness text + widget = wibox.widget.textbox, + id = 'text_role', + text = '0', + valign = 'center', + halign = 'center' }, - id = "layout1", spacing = dpi(10), layout = wibox.layout.fixed.horizontal }, - id = "margin", - margins = dpi(10), + left = dpi(10), + right = dpi(10), + top = dpi(20), + bottom = dpi(20), widget = wibox.container.margin }, - forced_width = dpi(300), - forced_height = dpi(80), - border_color = Theme_config.brightness_osd.border_color, - border_width = Theme_config.brightness_osd.border_width, - fg = Theme_config.brightness_osd.fg, - bg = Theme_config.brightness_osd.bg, + shape = Theme_config.brightness_ods.shape, widget = wibox.container.background }, ontop = true, stretch = false, visible = false, - screen = args.screen, - placement = function(c) aplacement.bottom_left(c, { margins = dpi(20) }) end, - shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, dpi(14)) + border_color = Theme_config.brightness_ods.border_color, + border_width = Theme_config.brightness_ods.border_width, + fg = Theme_config.brightness_ods.fg, + bg = Theme_config.brightness_ods.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 } - gtable.crush(osd, brightness_osd, true) + 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 - -- Called when the brightness changes, updates the brightness osd and icon - capi.awesome.connect_signal("brightness::changed", function(brightness) - if not capi.mouse.screen == args.screen then return end - assert(type(brightness) == "number", "brightness must be a number") + 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 = (brightness - 0) / ((backlight_helper.brightness_max or 24000) - 0) * 100 - osd.widget:get_children_by_id("progressbar1")[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 - - osd:rerun(true) - osd.widget:get_children_by_id("icon")[1]:set_image(gcolor.recolor_image(icon, - Theme_config.brightness_osd.icon_color)) + w.widget:get_children_by_id('icon')[1]:set_image(gcolor.recolor_image(icon, Theme_config.brightness_osd.icon_color)) + w.widget:get_children_by_id('text_role')[1].text = brightness + w:run() + end) end) - -- osd timer - osd.timer = gtimer { - timeout = 3, - single_shot = true, - callback = function() - osd.visible = false - end - } + return w end function brightness_osd.mt:__call(...) diff --git a/awesome/src/modules/calendar/calendar.lua b/awesome/src/modules/calendar/calendar.lua deleted file mode 100644 index 70aabb7..0000000 --- a/awesome/src/modules/calendar/calendar.lua +++ /dev/null @@ -1,1089 +0,0 @@ --------------------------------------- --- This is the application launcher -- --------------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local ical_parser = require("src.tools.ical_parser") - -local capi = { - awesome = awesome, - mouse = mouse, -} - -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/calendar/" - ---- Month name lookup table -local months_table = { - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - "January", - "February", -} - ---- Table to easily shift back every month by two months -local month_convert = { - 11, - 12, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, -} - ---- Weekdays name lookup table -local weekdays_table = { - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", - "Sun", -} - ---- Create a date object from the current date -local os_date = os.date("%d%m%Y") -local date = { - day = math.floor(os_date:sub(1, 2)), - month = month_convert[math.floor(os_date:sub(3, 4))], - year = math.floor(os_date:sub(5, 8)) -} - ----Calculates the weekday of a given date ----@param day number|string? as number, usually from date.da ----@param month number|string? as number, usually from date.month ----@param year number|string? as number, usually from date.year ----@return number|nil weekday as number -local function get_date_weekday(day, month, year) - if not (day and month and year) then return end - - if (month == 11) or (month == 12) then - year = year - 1 - end - - -- No idea how the algorithm works, but since it works -> don't touch it! - local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) + - tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) + - math.floor(tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) / 4) + - math.floor(tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) / 4)) % 7) - --TODO: Add user variable to choose between Sunday and Monday weekstart - if w == 0 then w = 7 end - return w -end - ----Returns the length of the month from a lookup table and also check for leap years ----@param month number? as number, usually from date.month, can also be a string ----@param year number? as number, usually from date.year, can also be a string ----@return integer|nil month_length as integer -local function get_last_day_of_month(month, year) - if not (month and year) then return end - - month = tonumber(month) - local last_day = { - 31, - 30, - 31, - 30, - 31, - 31, - 30, - 31, - 30, - 31, - 31, - 28, - } - --In this calculcation February is the 12th of last year - if (month == 12) and (math.floor(year % 4) == 0) then - return 29 - else - return last_day[month] - end -end - ----Simple function to calculate how many weeks will need to be displayed in a calendar ----@param month number? as number, usually from date.month, can also be a string ----@param year number? as number, usually from date.year, can also be a string ----@return number|nil weeks ammount of weeks between 4-6 -local function get_weeks_in_month(month, year) - if not (month and year) then return end - return math.ceil((get_last_day_of_month(month, year) + get_date_weekday(1, month, year) - 1) / 7) -end - ----Gets the last month and accounts for year changes ----@param d table date object ----@return table|nil date returns a date object -local function get_last_month(d) - if not (d) then return end - if d.month == 1 then - return { month = 12, year = d.year - 1 } - else - return { month = d.month - 1, year = d.year } - end -end - ----Simple function to create a widget 7x for each day of the week ----@return table weeks_widget All weekdays names as a widget -local function create_weekdays() - local weekdays = { layout = wibox.layout.flex.horizontal } - for i = 1, 7 do - table.insert(weekdays, wibox.widget { - { - text = weekdays_table[i], - align = "center", - valign = "center", - widget = wibox.widget.textbox, - }, - bg = Theme_config.calendar.weekdays.bg, - fg = Theme_config.calendar.weekdays.fg, - widget = wibox.container.background, - }) - end - return weekdays -end - ----Create tasks from ical object ----@return table|nil tasks All tasks as a table -local function create_tasks() - if not ical_parser or not ical_parser.VCALENDAR then return end - local tasks = {} - --TODO: Initialize the timezone from ical.VCALENDAR.VTIMEZONE and make sure the time is correct - - -- Sort every VEVENT in ical by date into the tasks table. - for _, calendar in ipairs(ical_parser.VCALENDAR) do - for _, event in ipairs(calendar.VEVENT) do - local start_time = event.DTSTART.DTSTART - start_time.month = month_convert[start_time.month] - local end_time - if event.DTEND then - end_time = event.DTEND.DTEND - end_time.month = month_convert[end_time.month] - end - - if event.RRULE then - if event.RRULE.FREQ == "DAILY" then - elseif event.RRULE.FREQ == "WEEKLY" then - -- An event will always start on the day it first occurs. - local event_start = start_time - local event_end = event.RRULE.UNTIL - - local year_counter = event_start.year - local month_counter = event_start.month - if month_counter == 11 then - year_counter = year_counter - 1 - elseif month_counter == 12 then - year_counter = year_counter - 1 - end - local day_counter = event_start.day - local task = {} - while (year_counter <= event_end.year) or (month_counter <= event_end.month) or (day_counter <= event_end.day) do - -- First event will always be right since we start on its starting day - task = { - date_start = { - year = year_counter, - month = month_counter, - day = day_counter, - hour = event_start.hour or 0, - minute = event_start.minute or 0, - second = event_start.second or 0 - }, - date_end = { - year = year_counter, - month = month_counter, - day = day_counter, - hour = end_time.hour or 0, - minute = end_time.minute or 0, - second = end_time.second or 0 - }, - summary = event.SUMMARY, - location = event.LOCATION, - } - - if event.VALARM then - task.alarm = { - time = event.VALARM.TRIGGER.TRIGGER - } - local alarm_time = task.alarm.time:match("([-]?%d+)") - local alarm_unit = task.alarm.time:match("(%a)") - if alarm_unit == "W" then - alarm_time = alarm_time * 604800 - elseif alarm_unit == "D" then - alarm_time = alarm_time * 86400 - elseif alarm_unit == "H" then - alarm_time = alarm_time * 3600 - elseif alarm_unit == "M" then - alarm_time = alarm_time * 60 - end - - --[[ gears.timer { - autostart = true, - callback = function() - if alarm_time then - require("naughty").notification { - app_name = "Task Alarm", - title = task.summary, - message = task.description, - urgency = "normal", - timeout = 5, - icon = icondir .. "/alarm.png", - } - gears.timer:stop() - end - end - } ]] - end - - table.insert(tasks, task) - - day_counter = day_counter + 7 - local month_length = get_last_day_of_month(month_counter, year_counter) - if day_counter > month_length then - day_counter = day_counter - month_length - month_counter = month_counter + 1 - end - if month_counter == 11 then - year_counter = year_counter + 1 - end - if month_counter > 13 then - month_counter = 1 - end - end - elseif event.RRULE.FREQ == "MONTHLY" then - elseif event.RRULE.FREQ == "YEARLY" then - if not end_time then - end_time = { - year = start_time.year + 1000, - } - end - - local task = {} - for i = start_time.year, end_time.year, 1 do - task = { - date_start = { - year = i, - month = start_time.month, - day = start_time.day, - hour = start_time.hour or 0, - minute = start_time.minute or 0, - second = start_time.second or 0 - }, - date_end = { - year = i, - month = start_time.month, - day = start_time.day, - hour = end_time.hour or 0, - minute = end_time.minute or 0, - second = end_time.second or 0 - }, - summary = event.SUMMARY, - location = event.LOCATION, - description = event.DESCRIPTION, - url = event.URL, - } - - if event.VALARM then - task.alarm = { - time = event.VALARM.TRIGGER.TRIGGER - } - local alarm_time = task.alarm.time:match("([-]?%d+)") - local alarm_unit = task.alarm.time:match("(%a)") - if alarm_unit == "W" then - alarm_time = alarm_time * 604800 - elseif alarm_unit == "D" then - alarm_time = alarm_time * 86400 - elseif alarm_unit == "H" then - alarm_time = alarm_time * 3600 - elseif alarm_unit == "M" then - alarm_time = alarm_time * 60 - end - - --[[ gears.timer { - timeout = os.time(task.date_start) - os.time() + alarm_time, - autostart = true, - callback = function() - require("naughty").notification { - app_name = "Task Alarm", - title = task.summary, - message = task.description, - urgency = "normal", - timeout = 5, - icon = icondir .. "/alarm.png", - } - end - } ]] - end - - table.insert(tasks, task) - end - end - else - local task = { - date_start = { - year = start_time.year, - month = start_time.month, - day = start_time.day, - hour = start_time.hour or 0, - minute = start_time.minute or 0, - second = start_time.second or 0 - }, - date_end = { - year = start_time.year, - month = start_time.month, - day = start_time.day, - hour = start_time.hour or 0, - minute = start_time.minute or 0, - second = start_time.second or 0 - }, - summary = event.SUMMARY, - location = event.LOCATION, - description = event.DESCRIPTION, - url = event.URL, - } - - if event.VALARM then - task.alarm = { - time = event.VALARM.TRIGGER.TRIGGER - } - local alarm_time = task.alarm.time:match("([-]?%d+)") - local alarm_unit = task.alarm.time:match("(%a)") - if alarm_unit == "W" then - alarm_time = alarm_time * 604800 - elseif alarm_unit == "D" then - alarm_time = alarm_time * 86400 - elseif alarm_unit == "H" then - alarm_time = alarm_time * 3600 - elseif alarm_unit == "M" then - alarm_time = alarm_time * 60 - end - - --[[ gears.timer { - timeout = os.time(task.date_start) - os.time() + alarm_time, - autostart = true, - callback = function() - require("naughty").notification { - app_name = "Task Alarm", - title = task.summary, - message = task.description, - urgency = "normal", - timeout = 5, - icon = icondir .. "/alarm.png", - } - end - } ]] - end - table.insert(tasks, task) - end - end - end - - return tasks -end - -local tasks = create_tasks() - -local selected_day = { - year = date.year, - month = date.month, - day = date.day, - col = 1, - row = 1, -} - -return function(s) - -- The calendar grid - local calendar_matrix = wibox.widget { layout = wibox.layout.grid, spacing = dpi(2) } - - local weeks = wibox.widget { layout = wibox.layout.fixed.vertical } - - ---Main function to create the calendar widget - ---Probably needs some refractor at some point since it's a bit messy - ---@return wibox.widget calendar_widget - local function create_calendar() - - calendar_matrix:reset() - - --- Months table holds every month with their starting week day, length(30/31 or 28/29), the last week day and the name - local months = {} - for m_num, month in ipairs(months_table) do - months[m_num] = { - name = month, - first_day = get_date_weekday("01", m_num, date.year), - length = get_last_day_of_month(m_num, date.year), - last_day = get_date_weekday(get_last_day_of_month(m_num, date.year), m_num, date.year), - weeks = get_weeks_in_month(m_num, date.year) - } - end - - local function get_tasks_for_day(day, month, year) - if not tasks or #tasks == 0 then return end - local tasks_layout = { - layout = require("src.lib.overflow_widget.overflow").vertical, - scrollbar_width = 0, - step = dpi(50), - spacing = dpi(2) - } - for _, task in ipairs(tasks) do - if (task.date_start.year == year) and (task.date_start.month == month) and (task.date_start.day == day) then - table.insert(tasks_layout, wibox.widget { - { - { - text = task.summary, - align = "left", - halign = "center", - font = "JetBrainsMono Nerd Font, bold 10", - widget = wibox.widget.textbox - }, - margins = dpi(2), - widget = wibox.container.margin - }, - fg = Theme_config.calendar.task.fg, - bg = Theme_config.calendar.task.bg, - shape = Theme_config.calendar.task.shape, - forced_height = dpi(20), - widget = wibox.container.background - }) - end - end - return tasks_layout - end - - if months[date.month].first_day ~= 1 then - -- Fill previous month days, i doubles as the day - local column = 1 - local last_month = get_last_month(date) - local prev_month = date.month - local prev_year = date.year - if date.month == 1 then - prev_month = 12 - last_month = months[12].length - else - last_month = months[date.month - 1].length - end - if date.month == 11 then - prev_year = date.year - 1 - end - prev_month = prev_month - 1 - for i = last_month - months[date.month].first_day + 2, last_month, 1 do - local border = Theme_config.calendar.day.border_color - local bg = Theme_config.calendar.day.bg_unfocus - local fg = Theme_config.calendar.day.fg_unfocus - if column == selected_day.col and 1 == selected_day.row then - border = Theme_config.calendar.day.today_border_color - bg = Theme_config.calendar.day.today_bg_focus - fg = Theme_config.calendar.day.today_fg_focus - end - local y = tonumber(os.date("%Y")) - local m = month_convert[tonumber(os.date("%m"))] - if m == 1 then - m = 12 - end - if (i == date.day) and (m == prev_month) and (date.year == y) then - bg = Theme_config.calendar.day.bg_focus - fg = Theme_config.calendar.day.fg_focus - end - local day = wibox.widget { - { - { - { - { - { - { - { -- Day - widget = wibox.widget.textbox, - align = "center", - valign = "center", - text = math.floor(i), - id = "day_text", - }, - widget = wibox.container.margin, - margins = dpi(2), - }, - id = "day_bg", - widget = wibox.container.background, - bg = bg, - shape = Theme_config.calendar.day.shape, - fg = fg, - }, - widget = wibox.container.place, - valign = "center", - halign = "center", - }, - { - get_tasks_for_day(math.floor(i), prev_month, prev_year), - widget = wibox.container.margin, - margins = dpi(4) - }, - id = "tasks", - spacing = dpi(4), - layout = wibox.layout.fixed.vertical - }, - widget = wibox.container.margin, - top = dpi(4) - }, - id = "background", - widget = wibox.container.background, - bg = Theme_config.calendar.day.bg_unfocus, - fg = Theme_config.calendar.day.fg_unfocus, - border_color = border, - border_width = Theme_config.calendar.day.border_width, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(8)) - end - }, - widget = wibox.container.constraint, - width = dpi(100), - height = dpi(120), - strategy = "exact" - } - - -- update selected_day if the day is clicked - day:buttons( - gears.table.join( - awful.button({}, 1, function() - selected_day.col = column - selected_day.row = 1 - day:emit_signal("day::update_selected") - end) - ) - ) - - day:connect_signal("day::update_selected", function() - if column == selected_day.col and 1 == selected_day.row then - capi.awesome.emit_signal("day::reset_border") - day.background.border_color = Theme_config.calendar.day.today_border_color - end - end) - - capi.awesome.connect_signal("day::reset_border", function() - day.background.border_color = Theme_config.calendar.day.border_color - end) - - calendar_matrix:add_widget_at(day, 1, column) - column = column + 1 - end - end - - --Actual month days - local row = 1 - local col = months[date.month].first_day - for i = 1, months[date.month].length, 1 do - - local border = Theme_config.calendar.day.border_color - local fg = Theme_config.calendar.day.fg - local bg = Theme_config.calendar.day.bg - if col == selected_day.col and row == selected_day.row then - border = Theme_config.calendar.day.today_border_color - end - - local m = month_convert[tonumber(os.date("%m"))] - local y = tonumber(os.date("%Y")) - if (i == date.day) and (date.month == m) and (date.year == y) then - bg = Theme_config.calendar.day.bg_focus - fg = Theme_config.calendar.day.fg_focus - end - - local day = wibox.widget { - { - { - { - { - { - { - { -- Day - widget = wibox.widget.textbox, - align = "center", - valign = "center", - text = math.floor(i), - id = "day_text", - }, - widget = wibox.container.margin, - margins = dpi(2), - }, - id = "day_bg", - widget = wibox.container.background, - bg = bg, - shape = Theme_config.calendar.day.shape, - fg = fg, - }, - widget = wibox.container.place, - valign = "center", - halign = "center", - }, - { - get_tasks_for_day(math.floor(i), date.month, date.year), - widget = wibox.container.margin, - margins = dpi(4) - }, - id = "tasks", - spacing = dpi(4), - layout = wibox.layout.fixed.vertical - }, - widget = wibox.container.margin, - top = dpi(4) - }, - id = "background", - widget = wibox.container.background, - bg = Theme_config.calendar.day.bg, - fg = Theme_config.calendar.day.fg, - border_color = border, - border_width = Theme_config.calendar.day.border_width, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(8)) - end - }, - widget = wibox.container.constraint, - width = dpi(100), - height = dpi(120), - strategy = "exact" - } - - -- update selected_day if the day is clicked - day:buttons( - gears.table.join( - awful.button({}, 1, function() - selected_day.col = col - selected_day.row = row - day:emit_signal("day::update_selected") - end) - ) - ) - - day:connect_signal("day::update_selected", function() - if col == selected_day.col and row == selected_day.row then - capi.awesome.emit_signal("day::reset_border") - day.background.border_color = Theme_config.calendar.day.today_border_color - end - end) - - capi.awesome.connect_signal("day::reset_border", function() - day.background.border_color = Theme_config.calendar.day.border_color - end) - - calendar_matrix:add_widget_at(day, row, col) - col = col + 1 - if col == 8 then - col = 1 - row = row + 1 - end - end - - --next month - local next_month = date.month - if date.month == 12 then - next_month = 1 - else - next_month = next_month + 1 - end - - if months[date.month].last_day ~= 7 then - for i = 1, 7 - months[date.month].last_day, 1 do - local border = Theme_config.calendar.day.border_color - local fg = Theme_config.calendar.day.fg_unfocus - local bg = Theme_config.calendar.day.bg_unfocus - if i == selected_day.col and months[date.month].weeks == selected_day.row then - border = Theme_config.calendar.day.today_border_color - end - local m = month_convert[tonumber(os.date("%m")) + 1] - if m == 13 then - m = 1 - end - local y = tonumber(os.date("%Y")) - if (i == date.day) and (next_month == m) and (date.year == y) then - bg = Theme_config.calendar.day.bg_focus - fg = Theme_config.calendar.day.fg_focus - end - local day = wibox.widget { - { - { - { - { - { - { - { -- Day - widget = wibox.widget.textbox, - align = "center", - valign = "center", - text = math.floor(i), - id = "day_text", - }, - widget = wibox.container.margin, - margins = dpi(2), - }, - id = "day_bg", - widget = wibox.container.background, - bg = bg, - shape = Theme_config.calendar.day.shape, - fg = fg, - }, - widget = wibox.container.place, - valign = "center", - halign = "center", - }, - { - get_tasks_for_day(math.floor(i), next_month, date.year), - widget = wibox.container.margin, - margins = dpi(4) - }, - id = "tasks", - spacing = dpi(4), - layout = wibox.layout.fixed.vertical - }, - widget = wibox.container.margin, - top = dpi(4) - }, - id = "background", - widget = wibox.container.background, - bg = Theme_config.calendar.day.bg_unfocus, - fg = Theme_config.calendar.day.fg_unfocus, - border_color = border, - border_width = Theme_config.calendar.day.border_width, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(8)) - end - }, - widget = wibox.container.constraint, - width = dpi(100), - height = dpi(120), - strategy = "exact" - } - - -- update selected_day if the day is clicked - day:buttons( - gears.table.join( - awful.button({}, 1, function() - selected_day.col = i - selected_day.row = months[date.month].weeks - day:emit_signal("day::update_selected") - end) - ) - ) - - day:connect_signal("day::update_selected", function() - if i == selected_day.col and months[date.month].weeks == selected_day.row then - capi.awesome.emit_signal("day::reset_border") - day.background.border_color = Theme_config.calendar.day.today_border_color - end - end) - - capi.awesome.connect_signal("day::reset_border", function() - day.background.border_color = Theme_config.calendar.day.border_color - end) - calendar_matrix:add_widget_at(day, months[date.month].weeks, months[date.month].last_day + i) - end - end - - return calendar_matrix - end - - local function create_calendar_week_num() - weeks:reset() - local actual_fucking_date = date.month + 2 - if date.month == 11 then - actual_fucking_date = 1 - elseif date.month == 12 then - actual_fucking_date = 2 - end - local start_week = actual_fucking_date * 4 - 3 - local weeknum = actual_fucking_date * 4 - 3 - if get_date_weekday("01", date.month, date.year) ~= 1 then - weeknum = weeknum - 1 - end - if actual_fucking_date == 1 then - weeknum = 52 - end - for i = start_week, start_week + get_weeks_in_month(date.month, date.year) - 1, 1 do - weeks:add(wibox.widget { - { - { - text = weeknum, - id = "num", - align = "center", - valign = "top", - widget = wibox.widget.textbox, - }, - id = "background", - fg = Theme_config.calendar.day.fg_unfocus, - widget = wibox.container.background, - }, - strategy = "exact", - height = dpi(120), - width = dpi(40), - widget = wibox.container.constraint - }) - if weeknum == 52 then - weeknum = 1 - else - weeknum = weeknum + 1 - end - end - return weeks - end - - --- Calendar widget - local calendar = wibox.widget { - { - { - { - { - { - { - { - widget = wibox.widget.imagebox, - resize = false, - image = gears.color.recolor_image(icondir .. "add_ical.svg", Theme_config.calendar.add_ical.fg_focus), - halign = "center", - valign = "center" - }, - id = "add_ical", - shape = Theme_config.calendar.add_ical.shape, - bg = Theme_config.calendar.add_ical.bg, - widget = wibox.container.background - }, - widget = wibox.container.margin, - margins = dpi(4) - }, - { - { - { - widget = wibox.widget.imagebox, - resize = false, - image = gears.color.recolor_image(icondir .. "add_task.svg", Theme_config.calendar.add_task.fg), - halign = "center", - valign = "center" - }, - id = "add_task", - shape = Theme_config.calendar.add_task.shape, - bg = Theme_config.calendar.add_task.bg, - widget = wibox.container.background - }, - widget = wibox.container.margin, - margins = dpi(4) - }, - layout = wibox.layout.fixed.vertical - }, - widget = wibox.container.constraint, - strategy = "exact", - height = dpi(75) - }, - create_calendar_week_num(), - id = "weekdaysnum", - layout = wibox.layout.fixed.vertical - }, - { - { - { --Header - { -- Month switcher - { -- Prev arrow - widget = wibox.widget.imagebox, - resize = true, - image = icondir .. "chevron-left.svg", - valign = "center", - halign = "center", - id = "prev_month", - }, - { - { -- Month - widget = wibox.widget.textbox, - text = months_table[date.month], - id = "month", - valign = "center", - align = "center" - }, - widget = wibox.container.constraint, - strategy = "exact", - width = dpi(150) - }, - { -- Next arrow - widget = wibox.widget.imagebox, - resize = true, - image = icondir .. "chevron-right.svg", - valign = "center", - halign = "center", - id = "next_month", - }, - layout = wibox.layout.fixed.horizontal - }, - nil, - { -- Year switcher - { -- Prev arrow - widget = wibox.widget.imagebox, - resize = true, - image = icondir .. "chevron-left.svg", - valign = "center", - halign = "center", - id = "prev_year" - }, - { - { -- Month - widget = wibox.widget.textbox, - text = date.year, - id = "year", - valign = "center", - align = "center" - }, - widget = wibox.container.constraint, - strategy = "exact", - width = dpi(150) - }, - { -- Next arrow - widget = wibox.widget.imagebox, - resize = true, - image = icondir .. "chevron-right.svg", - valign = "center", - halign = "center", - id = "next_year" - }, - layout = wibox.layout.fixed.horizontal - }, - layout = wibox.layout.align.horizontal - }, - widget = wibox.container.constraint, - height = dpi(40), - strategy = "exact" - }, - { -- Weekdays - create_weekdays(), - widget = wibox.container.background - }, - create_calendar(), - id = "calendar", - spacing = dpi(5), - layout = wibox.layout.fixed.vertical - }, - id = "lay1", - layout = wibox.layout.fixed.horizontal, - }, - widget = wibox.container.background, - bg = Theme_config.calendar.bg, - border_color = Theme_config.calendar.border_color, - border_width = Theme_config.calendar.border_width, - border_strategy = "inner", - fg = Theme_config.calendar.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(4)) - end - } - - local add_ical = calendar:get_children_by_id("add_ical")[1] - local add_task = calendar:get_children_by_id("add_task")[1] - - add_ical:buttons( - gears.table.join( - awful.button({}, 1, function() - awful.spawn.easy_async_with_shell( - "zenity --file-selection --title='Select an iCalendar file' --file-filter='iCalendar File | *.ics'", - function(path_to_file) - path_to_file = string.gsub(path_to_file, "\n", "") - if not path_to_file then return end - ical_parser.new(path_to_file) - tasks = create_tasks() - calendar:get_children_by_id("weekdaysnum")[1].children[2] = create_calendar_week_num() - calendar:get_children_by_id("calendar")[1].children[3] = create_calendar() - end - ) - end) - ) - ) - - Hover_signal(add_ical) - Hover_signal(add_task) - - --- Popup that contains the calendar - local cal_popup = awful.popup { - widget = calendar, - screen = s, - ontop = true, - bg = "#00000000", - visible = false - } - - --- Calendar switch month back - calendar:get_children_by_id("prev_month")[1]:buttons( - gears.table.join( - awful.button({}, 1, function() - date.month = date.month - 1 - if date.month == 0 then - date.month = 12 - end - if date.month == 10 then - date.year = date.year - 1 - end - calendar:get_children_by_id("month")[1].text = months_table[date.month] - calendar:get_children_by_id("year")[1].text = date.year - calendar:get_children_by_id("weekdaysnum")[1].children[2] = create_calendar_week_num() - calendar:get_children_by_id("calendar")[1].children[3] = create_calendar() - end) - ) - ) - - --- Calendar switch month forward - calendar:get_children_by_id("next_month")[1]:buttons( - gears.table.join( - awful.button({}, 1, function() - date.month = date.month + 1 - if date.month == 13 then - date.month = 1 - end - if date.month == 11 then - date.year = date.year + 1 - end - calendar:get_children_by_id("month")[1].text = months_table[date.month] - calendar:get_children_by_id("year")[1].text = date.year - calendar:get_children_by_id("weekdaysnum")[1].children[2] = create_calendar_week_num() - calendar:get_children_by_id("calendar")[1].children[3] = create_calendar() - end) - ) - ) - - --- Calendar switch year back - calendar:get_children_by_id("prev_year")[1]:buttons( - gears.table.join( - awful.button({}, 1, function() - date.year = date.year - 1 - calendar:get_children_by_id("year")[1].text = date.year - calendar:get_children_by_id("weekdaysnum")[1].children[2] = create_calendar_week_num() - calendar:get_children_by_id("calendar")[1].children[3] = create_calendar() - end) - ) - ) - - --- Calendar switch year forward - calendar:get_children_by_id("next_year")[1]:buttons( - gears.table.join( - awful.button({}, 1, function() - date.year = date.year + 1 - calendar:get_children_by_id("year")[1].text = date.year - calendar:get_children_by_id("weekdaysnum")[1].children[2] = create_calendar_week_num() - calendar:get_children_by_id("calendar")[1].children[3] = create_calendar() - end) - ) - ) - - --- Toggle calendar visibility - capi.awesome.connect_signal("calendar::toggle", function(widget) - if s == capi.mouse.screen then - cal_popup.x = 3765 - cal_popup.y = 60 - cal_popup.visible = not cal_popup.visible - end - end) - -end diff --git a/awesome/src/modules/calendar/init.lua b/awesome/src/modules/calendar/init.lua index 8c7a5c3..65fdf3d 100644 --- a/awesome/src/modules/calendar/init.lua +++ b/awesome/src/modules/calendar/init.lua @@ -1,23 +1,21 @@ -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local gobject = require("gears.object") -local gshape = require("gears.shape") -local gcolor = require("gears.color") -local gfilesystem = require("gears").filesystem -local wibox = require("wibox") -local base = require("wibox.widget.base") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local gcolor = require('gears.color') +local gfilesystem = require('gears').filesystem +local wibox = require('wibox') +local base = require('wibox.widget.base') local capi = { - awesome = awesome, mouse = mouse, } -local ical_parser = require("src.tools.ical_parser")() -local task_info = require("src.modules.calendar.task_info") +local ical_parser = require('src.tools.ical_parser')() +local task_info = require('src.modules.calendar.task_info') +local hover = require('src.tools.hover') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/' local calendar = { mt = {} } calendar.tasks = {} @@ -27,36 +25,36 @@ calendar._private = {} -- Month lookup table calendar._private.months = { - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', } -- Weeks shortname lookup table calendar._private.weeks = { - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", - "Sun" + 'Mon', + 'Tue', + 'Wed', + 'Thu', + 'Fri', + 'Sat', + 'Sun', } --- A date table to keep track of the needed date calendar.date = { - day = tonumber(os.date("%d")) or 1, - month = tonumber(os.date("%m")) or 1, - year = tonumber(os.date("%Y")) or 1970 + day = tonumber(os.date('%d')) or 1, + month = tonumber(os.date('%m')) or 1, + year = tonumber(os.date('%Y')) or 1970, } --#region base widget functions @@ -67,7 +65,7 @@ function calendar:layout(_, width, height) end function calendar:fit(context, width, height) - local w, h = 0, 0 + local w, h = 0, 0 ---@type number|nil, number|nil if self._private.widget then w, h = base.fit_widget(self, context, self._private.widget, width, height) end @@ -102,7 +100,7 @@ function calendar:get_last_day_in_month(month, year) [9] = 30, [10] = 31, [11] = 30, - [12] = 31 + [12] = 31, } if (month == 2) and (math.floor(year % 4) == 0) then @@ -136,10 +134,10 @@ function calendar:weekday_for_day(day, month, year) end -- Forgot what the algorithm was called - local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) + - tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) + - math.floor(tonumber(tostring(year):match("[0-9][0-9]([0-9]+)")) / 4) + - math.floor(tonumber(tostring(year):match("([0-9]+)[0-9][0-9]")) / 4)) % 7) + local w = ((day + math.floor(2.6 * month - 0.2) - 2 * tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) + + tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) + + math.floor(tonumber(tostring(year):match('[0-9][0-9]([0-9]+)')) / 4) + + math.floor(tonumber(tostring(year):match('([0-9]+)[0-9][0-9]')) / 4)) % 7) -- If the week should start on monday, sunday is default. Since the function returns 0 - 6, we have to add 1 for lua's tables if w == 0 then w = 7 end @@ -181,7 +179,7 @@ function calendar:get_tasks() day = start_date.d, hour = start_date.hour or 0, min = start_date.min or 0, - sec = start_date.sec or 0 + sec = start_date.sec or 0, }, date_end = { year = end_date.y, @@ -189,7 +187,7 @@ function calendar:get_tasks() day = end_date.d, hour = end_date.hour or 0, min = end_date.min or 0, - sec = end_date.sec or 0 + sec = end_date.sec or 0, }, summary = sum, location = loc, @@ -219,12 +217,12 @@ function calendar:get_tasks() day = start_time.day, hour = start_time.hour, min = start_time.min, - sec = start_time.sec + sec = start_time.sec, } end -- Get repeat cases if event.RRULE then - if event.RRULE.FREQ == "DAILY" then + if event.RRULE.FREQ == 'DAILY' then local year_counter, month_counter, day_counter = start_time.year, start_time.month, start_time.day while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or @@ -235,14 +233,14 @@ function calendar:get_tasks() d = day_counter, hour = start_time.hour, min = start_time.min, - sec = start_time.sec + sec = start_time.sec, }, { y = year_counter, m = month_counter, d = day_counter, hour = end_time.hour, min = end_time.min, - sec = end_time.sec + sec = end_time.sec, }, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ) day_counter = day_counter + 1 @@ -255,14 +253,14 @@ function calendar:get_tasks() end end end - elseif event.RRULE.FREQ == "WEEKLY" then + elseif event.RRULE.FREQ == 'WEEKLY' then local year_counter, month_counter, day_counter = start_time.year, start_time.month, start_time.day while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or (day_counter <= event.RRULE.UNTIL.day) do task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour, - min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter, - d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec }, + min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter, + d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ) day_counter = day_counter + 7 local month_length = calendar:get_last_day_in_month(month_counter, year_counter) @@ -275,14 +273,14 @@ function calendar:get_tasks() end end end - elseif event.RRULE.FREQ == "MONTHLY" then + elseif event.RRULE.FREQ == 'MONTHLY' then local year_counter, month_counter, day_counter = start_time.year, start_time.month, start_time.day while (year_counter < event.RRULE.UNTIL.year) or (month_counter < event.RRULE.UNTIL.month) or (day_counter <= event.RRULE.UNTIL.day) do task_factory({ y = year_counter, m = month_counter, d = day_counter, hour = start_time.hour, - min = start_time.min, sec = start_time.sec }, { y = year_counter, m = month_counter, - d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec }, + min = start_time.min, sec = start_time.sec, }, { y = year_counter, m = month_counter, + d = day_counter, hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ) month_counter = month_counter + 1 if month_counter > 12 then @@ -290,27 +288,27 @@ function calendar:get_tasks() year_counter = year_counter + 1 end end - elseif event.RRULE.FREQ == "YEARLY" then + elseif event.RRULE.FREQ == 'YEARLY' then end_time = event.RRULE.UNTIL if not event.RRULE.UNTIL then end_time = { year = start_time.year + 1000, month = start_time.month, - day = start_time.day + day = start_time.day, } end for i = start_time.year, end_time.year, 1 do task_factory({ y = i, m = start_time.month, d = start_time.day, hour = start_time.hour, - min = start_time.min, sec = start_time.sec }, { y = i, m = end_time.month, d = end_time.day, - hour = end_time.hour, min = end_time.min, sec = end_time.sec }, event.SUMMARY, + min = start_time.min, sec = start_time.sec, }, { y = i, m = end_time.month, d = end_time.day, + hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ) end end -- If RRULE is empty we just add a single day event else task_factory({ y = start_time.year, m = start_time.month, d = start_time.day, hour = start_time.hour, - min = start_time.min, sec = start_time.sec }, { y = end_time.year, m = end_time.month, - d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec }, + min = start_time.min, sec = start_time.sec, }, { y = end_time.year, m = end_time.month, + d = end_time.day, hour = end_time.hour, min = end_time.min, sec = end_time.sec, }, event.SUMMARY, event.LOCATION, event.DESCRIPTION, event.UID, event.RRULE.FREQ) end if event.VALARM then @@ -323,7 +321,7 @@ function calendar:get_tasks() table.insert(self.tasks, tasks) table.insert(self.calendars, { tasks = self.tasks, - color = cal.color + color = cal.color, }) end end @@ -344,19 +342,19 @@ function calendar:create_calendar_weeks_widget() { { text = i, - id = "num", - align = "center", - valign = "top", + id = 'num', + align = 'center', + valign = 'top', widget = wibox.widget.textbox, }, - id = "background", + id = 'background', fg = Theme_config.calendar.day.fg_unfocus, widget = wibox.container.background, }, - strategy = "exact", + strategy = 'exact', height = dpi(120), width = dpi(40), - widget = wibox.container.constraint + widget = wibox.container.constraint, }) end end @@ -369,8 +367,8 @@ function calendar:create_weekdays_widget() self._private.weekdays:add(wibox.widget { { text = self._private.weeks[i], - align = "center", - valign = "center", + align = 'center', + valign = 'center', widget = wibox.widget.textbox, }, bg = Theme_config.calendar.weekdays.bg, @@ -404,10 +402,10 @@ function calendar:create_calendar_widget() local function get_tasks_for_day(day, month, year) if not self.tasks or #self.tasks == 0 then return end local tasks_layout = { - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, scrollbar_width = 0, step = dpi(50), - spacing = dpi(2) + spacing = dpi(2), } local function task_factory(task, bg) @@ -415,19 +413,19 @@ function calendar:create_calendar_widget() { { text = task.summary, - align = "left", - halign = "center", - font = "JetBrainsMono Nerd Font, bold 10", - widget = wibox.widget.textbox + align = 'left', + halign = 'center', + font = 'JetBrainsMono Nerd Font, bold 10', + widget = wibox.widget.textbox, }, margins = dpi(2), - widget = wibox.container.margin + widget = wibox.container.margin, }, fg = Theme_config.calendar.task.fg, bg = bg, shape = Theme_config.calendar.task.shape, forced_height = dpi(20), - widget = wibox.container.background + widget = wibox.container.background, } end @@ -442,7 +440,7 @@ function calendar:create_calendar_widget() ( task.date_start.year == self.date.year and task.date_start.month == self.date.month and task.date_start.day < self.date.day) then - tw = task_factory(task, cal.color .. "55") + tw = task_factory(task, cal.color .. '55') else tw = task_factory(task, cal.color) end @@ -466,10 +464,10 @@ function calendar:create_calendar_widget() widget = ti, ontop = true, visible = false, - bg = "#00000000", + bg = '#00000000', x = capi.mouse.coords().x, y = capi.mouse.coords().y, - screen = self.screen + screen = capi.mouse.screen, } tw:buttons( @@ -482,11 +480,11 @@ function calendar:create_calendar_widget() ) ) - tw:connect_signal("mouse::leave", function() + tw:connect_signal('mouse::leave', function() task_popup.visible = false end) - Hover_signal(tw) + hover.bg_hover { widget = tw } table.insert(tasks_layout, tw) end @@ -514,8 +512,8 @@ function calendar:create_calendar_widget() local bg = Theme_config.calendar.day.bg_unfocus local fg = Theme_config.calendar.day.fg_unfocus - local y = tonumber(os.date("%Y")) - local m = tonumber(os.date("%m")) + local y = tonumber(os.date('%Y')) + local m = tonumber(os.date('%m')) if (i == self.date.day) and (m == last_month) and (y == year) then bg = Theme_config.calendar.day.bg_focus @@ -531,39 +529,39 @@ function calendar:create_calendar_widget() { { -- Day widget = wibox.widget.textbox, - align = "center", - valign = "center", + align = 'center', + valign = 'center', text = math.floor(i), - id = "day_text", + id = 'day_text', }, widget = wibox.container.margin, margins = dpi(2), }, - id = "day_bg", + id = 'day_bg', widget = wibox.container.background, bg = bg, shape = Theme_config.calendar.day.shape, fg = fg, }, widget = wibox.container.place, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, { get_tasks_for_day(math.floor(i), last_month, year), widget = wibox.container.margin, margins = dpi(4), - id = "day_tasks", + id = 'day_tasks', }, - id = "tasks", + id = 'tasks', spacing = dpi(4), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - id = "day_bg", + id = 'day_bg', widget = wibox.container.margin, - top = dpi(4) + top = dpi(4), }, - id = "background", + id = 'background', widget = wibox.container.background, bg = Theme_config.calendar.day.bg_unfocus, fg = Theme_config.calendar.day.fg_unfocus, @@ -571,11 +569,11 @@ function calendar:create_calendar_widget() border_width = Theme_config.calendar.day.border_width, shape = Theme_config.calendar.day.shape, }, - id = "day", + id = 'day', widget = wibox.container.constraint, width = dpi(100), height = dpi(120), - strategy = "exact" + strategy = 'exact', } self._private.calendar_matrix:add_widget_at(day, 1, column) @@ -592,8 +590,8 @@ function calendar:create_calendar_widget() local bg = Theme_config.calendar.day.bg local fg = Theme_config.calendar.day.fg - local m = tonumber(os.date("%m")) - local y = tonumber(os.date("%Y")) + local m = tonumber(os.date('%m')) + local y = tonumber(os.date('%Y')) if (i == self.date.day) and (m == self.date.month) and (y == self.date.year) then bg = Theme_config.calendar.day.bg_focus fg = Theme_config.calendar.day.fg_focus @@ -608,37 +606,37 @@ function calendar:create_calendar_widget() { { -- Day widget = wibox.widget.textbox, - align = "center", - valign = "center", + align = 'center', + valign = 'center', text = math.floor(i), - id = "day_text", + id = 'day_text', }, widget = wibox.container.margin, margins = dpi(2), }, - id = "day_bg", + id = 'day_bg', widget = wibox.container.background, bg = bg, shape = Theme_config.calendar.day.shape, fg = fg, }, widget = wibox.container.place, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, { get_tasks_for_day(math.floor(i), self.date.month, self.date.year), widget = wibox.container.margin, - margins = dpi(4) + margins = dpi(4), }, - id = "tasks", + id = 'tasks', spacing = dpi(4), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.margin, - top = dpi(4) + top = dpi(4), }, - id = "background", + id = 'background', widget = wibox.container.background, bg = Theme_config.calendar.day.bg, fg = Theme_config.calendar.day.fg, @@ -649,7 +647,7 @@ function calendar:create_calendar_widget() widget = wibox.container.constraint, width = dpi(100), height = dpi(120), - strategy = "exact" + strategy = 'exact', } self._private.calendar_matrix:add_widget_at(day, row, col) @@ -674,8 +672,8 @@ function calendar:create_calendar_widget() local bg = Theme_config.calendar.day.bg_unfocus local fg = Theme_config.calendar.day.fg_unfocus - local m = tonumber(os.date("%m")) - local y = tonumber(os.date("%Y")) + local m = tonumber(os.date('%m')) + local y = tonumber(os.date('%Y')) if (i == self.date.day) and (m == next_month) and (y == year) then bg = Theme_config.calendar.day.bg_focus fg = Theme_config.calendar.day.fg_focus @@ -689,37 +687,37 @@ function calendar:create_calendar_widget() { { -- Day widget = wibox.widget.textbox, - align = "center", - valign = "center", + align = 'center', + valign = 'center', text = math.floor(i), - id = "day_text", + id = 'day_text', }, widget = wibox.container.margin, margins = dpi(2), }, - id = "day_bg", + id = 'day_bg', widget = wibox.container.background, bg = bg, shape = Theme_config.calendar.day.shape, fg = fg, }, widget = wibox.container.place, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, { get_tasks_for_day(math.floor(i), next_month, year), widget = wibox.container.margin, - margins = dpi(4) + margins = dpi(4), }, - id = "tasks", + id = 'tasks', spacing = dpi(4), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.margin, - top = dpi(4) + top = dpi(4), }, - id = "background", + id = 'background', widget = wibox.container.background, bg = Theme_config.calendar.day.bg_unfocus, fg = Theme_config.calendar.day.fg_unfocus, @@ -730,7 +728,7 @@ function calendar:create_calendar_widget() widget = wibox.container.constraint, width = dpi(100), height = dpi(120), - strategy = "exact" + strategy = 'exact', } self._private.calendar_matrix:add_widget_at(day, months_t[self.date.month].weeks, months_t[self.date.month].last_day + i) @@ -754,44 +752,44 @@ function calendar.new(args) { widget = wibox.widget.imagebox, resize = false, - image = gcolor.recolor_image(icondir .. "add_ical.svg", Theme_config.calendar.add_ical.fg_focus), - halign = "center", - valign = "center" + image = gcolor.recolor_image(icondir .. 'add_ical.svg', Theme_config.calendar.add_ical.fg_focus), + halign = 'center', + valign = 'center', }, - id = "add_ical", + id = 'add_ical', shape = Theme_config.calendar.add_ical.shape, bg = Theme_config.calendar.add_ical.bg, - widget = wibox.container.background + widget = wibox.container.background, }, widget = wibox.container.margin, - margins = dpi(4) + margins = dpi(4), }, { -- New task button { { widget = wibox.widget.imagebox, resize = false, - image = gcolor.recolor_image(icondir .. "add_task.svg", Theme_config.calendar.add_task.fg), - halign = "center", - valign = "center" + image = gcolor.recolor_image(icondir .. 'add_task.svg', Theme_config.calendar.add_task.fg), + halign = 'center', + valign = 'center', }, - id = "add_task", + id = 'add_task', shape = Theme_config.calendar.add_task.shape, bg = Theme_config.calendar.add_task.bg, - widget = wibox.container.background + widget = wibox.container.background, }, widget = wibox.container.margin, - margins = dpi(4) + margins = dpi(4), }, - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.constraint, - strategy = "exact", - height = dpi(75) + strategy = 'exact', + height = dpi(75), }, ret._private.calendar_weeks_widget, - id = "weekdaysnum", - layout = wibox.layout.fixed.vertical + id = 'weekdaysnum', + layout = wibox.layout.fixed.vertical, }, { { @@ -800,88 +798,88 @@ function calendar.new(args) { -- Prev arrow widget = wibox.widget.imagebox, resize = true, - image = icondir .. "chevron-left.svg", - valign = "center", - halign = "center", - id = "prev_month", + image = icondir .. 'chevron-left.svg', + valign = 'center', + halign = 'center', + id = 'prev_month', }, { { -- Month widget = wibox.widget.textbox, text = ret._private.months[ret.date.month], - id = "month", - valign = "center", - align = "center" + id = 'month', + valign = 'center', + align = 'center', }, widget = wibox.container.constraint, - strategy = "exact", - width = dpi(150) + strategy = 'exact', + width = dpi(150), }, { -- Next year arrow widget = wibox.widget.imagebox, resize = true, - image = icondir .. "chevron-right.svg", - valign = "center", - halign = "center", - id = "next_month", + image = icondir .. 'chevron-right.svg', + valign = 'center', + halign = 'center', + id = 'next_month', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, nil, { -- Year year switcher { -- Prev arrow widget = wibox.widget.imagebox, resize = true, - image = icondir .. "chevron-left.svg", - valign = "center", - halign = "center", - id = "prev_year" + image = icondir .. 'chevron-left.svg', + valign = 'center', + halign = 'center', + id = 'prev_year', }, { { -- Year widget = wibox.widget.textbox, text = calendar.date.year, - id = "year", - valign = "center", - align = "center" + id = 'year', + valign = 'center', + align = 'center', }, widget = wibox.container.constraint, - strategy = "exact", - width = dpi(150) + strategy = 'exact', + width = dpi(150), }, { -- Next year arrow widget = wibox.widget.imagebox, resize = true, - image = icondir .. "chevron-right.svg", - valign = "center", - halign = "center", - id = "next_year" + image = icondir .. 'chevron-right.svg', + valign = 'center', + halign = 'center', + id = 'next_year', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.constraint, height = dpi(40), - strategy = "exact" + strategy = 'exact', }, { -- Weekdays ret._private.weekdays, - widget = wibox.container.background + widget = wibox.container.background, }, ret._private.calendar_matrix, - id = "calendar", + id = 'calendar', spacing = dpi(5), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - id = "lay1", + id = 'lay1', layout = wibox.layout.fixed.horizontal, }, widget = wibox.container.background, bg = Theme_config.calendar.bg, border_color = Theme_config.calendar.border_color, border_width = Theme_config.calendar.border_width, - border_strategy = "inner", + border_strategy = 'inner', fg = Theme_config.calendar.fg, shape = Theme_config.calendar.shape, }) @@ -893,13 +891,13 @@ function calendar.new(args) ret:create_weekdays_widget() ret:create_calendar_weeks_widget() - ret:get_widget():get_children_by_id("add_ical")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('add_ical')[1]:buttons(gtable.join( awful.button({}, 1, function() awful.spawn.easy_async_with_shell( "zenity --file-selection --title='Select an ICalendar file' --file-filter='iCalendar File | *.ics'", function(path_to_file) - path_to_file = string.gsub(path_to_file, "\n", "") - if (not path_to_file) or (path_to_file == "") then return end + path_to_file = string.gsub(path_to_file, '\n', '') + if (not path_to_file) or (path_to_file == '') then return end ical_parser:add_calendar(path_to_file) ret:get_tasks() ret:create_calendar_widget() @@ -908,7 +906,7 @@ function calendar.new(args) end) )) - ret:get_widget():get_children_by_id("add_task")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('add_task')[1]:buttons(gtable.join( awful.button({}, 1, function() awful.spawn.easy_async_with_shell( "zenity --info --text='Soon TM'", @@ -919,54 +917,57 @@ function calendar.new(args) end) )) - ret:get_widget():get_children_by_id("prev_month")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('prev_month')[1]:buttons(gtable.join( awful.button({}, 1, function() ret.date.month = ret.date.month - 1 if ret.date.month == 0 then ret.date.month = 12 ret.date.year = ret.date.year - 1 end - ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month] - ret:get_widget():get_children_by_id("year")[1].text = ret.date.year + ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month] + ret:get_widget():get_children_by_id('year')[1].text = ret.date.year ret:create_calendar_weeks_widget() ret:create_calendar_widget() end) )) - ret:get_widget():get_children_by_id("next_month")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('next_month')[1]:buttons(gtable.join( awful.button({}, 1, function() ret.date.month = ret.date.month + 1 if ret.date.month == 13 then ret.date.month = 1 ret.date.year = ret.date.year + 1 end - ret:get_widget():get_children_by_id("month")[1].text = ret._private.months[ret.date.month] - ret:get_widget():get_children_by_id("year")[1].text = ret.date.year + ret:get_widget():get_children_by_id('month')[1].text = ret._private.months[ret.date.month] + ret:get_widget():get_children_by_id('year')[1].text = ret.date.year ret:create_calendar_weeks_widget() ret:create_calendar_widget() end) )) --- Calendar switch year back - ret:get_widget():get_children_by_id("prev_year")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('prev_year')[1]:buttons(gtable.join( awful.button({}, 1, function() ret.date.year = ret.date.year - 1 - ret:get_widget():get_children_by_id("year")[1].text = ret.date.year + ret:get_widget():get_children_by_id('year')[1].text = ret.date.year ret:create_calendar_weeks_widget() ret:create_calendar_widget() end) )) --- Calendar switch year forward - ret:get_widget():get_children_by_id("next_year")[1]:buttons(gtable.join( + ret:get_widget():get_children_by_id('next_year')[1]:buttons(gtable.join( awful.button({}, 1, function() ret.date.year = ret.date.year + 1 - ret:get_widget():get_children_by_id("year")[1].text = ret.date.year + ret:get_widget():get_children_by_id('year')[1].text = ret.date.year ret:create_calendar_weeks_widget() ret:create_calendar_widget() end) )) + hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_ical')[1] } + hover.bg_hover { widget = ret:get_widget():get_children_by_id('add_task')[1] } + return ret end diff --git a/awesome/src/modules/calendar/task_info.lua b/awesome/src/modules/calendar/task_info.lua index 8144d50..c54bd98 100644 --- a/awesome/src/modules/calendar/task_info.lua +++ b/awesome/src/modules/calendar/task_info.lua @@ -1,18 +1,16 @@ -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gcolor = require("gears.color") -local gtable = require("gears.table") -local gshape = require("gears.shape") -local gobject = require("gears.object") -local gfilesystem = require("gears").filesystem -local wibox = require("wibox") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gtable = require('gears.table') +local gshape = require('gears.shape') +local gobject = require('gears.object') +local gfilesystem = require('gears').filesystem +local wibox = require('wibox') -local capi = { - mouse = mouse, -} +local hover = require('src.tools.hover') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/calendar/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/calendar/' local task_info = { mt = {} } task_info._private = {} @@ -23,124 +21,126 @@ function task_info.new(args) local ret = gobject {} gtable.crush(ret, task_info, true) - args.color = args.color or "#ffffff" + args.color = args.color or '#ffffff' - local date_long_written = os.date("%A, %d. %B %Y", os.time(args.date_start)) + local date_long_written = os.date('%A, %d. %B %Y', os.time(args.date_start)) + + local from_to = os.date('%H:%M', os.time(args.date_start)) .. ' - ' .. os.date('%H:%M', os.time(args.date_end)) - local from_to = os.date("%H:%M", os.time(args.date_start)) .. " - " .. os.date("%H:%M", os.time(args.date_end)) - local task_info_widget = wibox.widget { { { { - { -- Task detail - { -- Calendar color - widget = wibox.container.background, - bg = args.color, - forced_width = dpi(10), - shape = function(cr, _, height) - gshape.rounded_rect(cr, dpi(10), height, dpi(8)) - end, + { -- Task detail + { -- Calendar color + widget = wibox.container.background, + bg = args.color, + forced_width = dpi(10), + shape = function(cr, _, height) + gshape.rounded_rect(cr, dpi(10), height, dpi(8)) + end, + }, + { + { -- Summary + widget = wibox.widget.textbox, + text = args.summary:sub(1, -2) or 'NO SUMMARY', + valign = 'center', + halign = 'left', + id = 'summary', + }, + { -- Date long + widget = wibox.widget.textbox, + text = date_long_written or '01.12.1970', + valign = 'center', + halign = 'right', + id = 'date_long', + }, + { -- From - To + widget = wibox.widget.textbox, + text = from_to or '', + valign = 'center', + halign = 'left', + id = 'from_to', + }, + { -- Repeat information + widget = wibox.widget.textbox, + text = args.freq or '0', + valign = 'center', + halign = 'left', + id = 'repeat_info', + }, -- Year + { + widget = wibox.widget.textbox, + text = args.date_start.year or '1970', + valign = 'center', + halign = 'left', + id = 'year', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + spacing = dpi(20), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.margin, + left = dpi(9), }, - { - { -- Summary - widget = wibox.widget.textbox, - text = args.summary:sub(1, -2) or "NO SUMMARY", - valign = "center", - halign = "left", - id = "summary", + { -- Location + { + widget = wibox.widget.imagebox, + image = gcolor.recolor_image(icondir .. 'location.svg', args.color), + resize = false, + valign = 'center', + halign = 'center', }, - { -- Date long - widget = wibox.widget.textbox, - text = date_long_written or "01.12.1970", - valign = "center", - halign = "right", - id = "date_long", - }, - { -- From - To - widget = wibox.widget.textbox, - text = from_to or "", - valign = "center", - halign = "left", - id = "from_to", - }, - { -- Repeat information - widget = wibox.widget.textbox, - text = args.freq or "0", - valign = "center", - halign = "left", - id = "repeat_info", - }, -- Year { widget = wibox.widget.textbox, - text = args.date_start.year or "1970", - valign = "center", - halign = "left", - id = "year", + text = args.location:sub(1, -2) or 'F303', + valign = 'center', + halign = 'left', + id = 'location', }, spacing = dpi(10), - layout = wibox.layout.fixed.vertical, + id = 'location_container', + layout = wibox.layout.fixed.horizontal, }, - spacing = dpi(20), - layout = wibox.layout.fixed.horizontal + { -- Alarm + { + widget = wibox.widget.imagebox, + image = gcolor.recolor_image(icondir .. 'alarm.svg', args.color), + resize = false, + valign = 'center', + halign = 'center', + }, + { + widget = wibox.widget.textbox, + text = args.alarm or 'NO ALARM', + valign = 'center', + halign = 'left', + id = 'alarm', + }, + spacing = dpi(10), + id = 'alarm_container', + layout = wibox.layout.fixed.horizontal, + }, + id = 'task_detail', + spacing = dpi(15), + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.margin, - left = dpi(9) - }, - { -- Location - { - widget = wibox.widget.imagebox, - image = gcolor.recolor_image(icondir .. "location.svg", args.color), - resize = false, - valign = "center", - halign = "center", - }, - { - widget = wibox.widget.textbox, - text = args.location:sub(1, -2) or "F303", - valign = "center", - halign = "left", - id = "location", - }, - spacing = dpi(10), - id = "location_container", - layout = wibox.layout.fixed.horizontal - }, - { -- Alarm - { - widget = wibox.widget.imagebox, - image = gcolor.recolor_image(icondir .. "alarm.svg", args.color), - resize = false, - valign = "center", - halign = "center", - }, - { - widget = wibox.widget.textbox, - text = args.alarm or "NO ALARM", - valign = "center", - halign = "left", - id = "alarm", - }, - spacing = dpi(10), - id = "alarm_container", - layout = wibox.layout.fixed.horizontal - }, - id = "task_detail", - spacing = dpi(15), - layout = wibox.layout.fixed.vertical + left = dpi(6), + right = dpi(15), + top = dpi(15), + bottom = dpi(15), }, - widget = wibox.container.margin, - left = dpi(6), - right = dpi(15), - top = dpi(15), - bottom = dpi(15), - }, bg = Theme_config.calendar.task_info.bg, fg = Theme_config.calendar.task_info.fg, shape = Theme_config.calendar.task_info.shape, widget = wibox.container.background, } + hover.bg_hover { widget = task_info_widget } + ret.widget = task_info_widget return ret.widget diff --git a/awesome/src/modules/context_menu/init.lua b/awesome/src/modules/context_menu/init.lua index c7b4d4e..955094c 100644 --- a/awesome/src/modules/context_menu/init.lua +++ b/awesome/src/modules/context_menu/init.lua @@ -2,32 +2,33 @@ -- This is the brightness_osd module -- --------------------------------------- -- Awesome Libs -local awful = require("awful") +local awful = require('awful') local abutton = awful.button -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local base = require("wibox.widget.base") -local wibox = require("wibox") -local gfilesystem = require("gears.filesystem") -local gobject = require("gears.object") -local gcolor = require("gears.color") -local gtimer = require("gears.timer") +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local base = require('wibox.widget.base') +local wibox = require('wibox') +local gfilesystem = require('gears.filesystem') +local gcolor = require('gears.color') +local gtimer = require('gears.timer') + +local hover = require('src.tools.hover') local capi = { awesome = awesome, - mouse = mouse + mouse = mouse, } -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/context_menu/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/context_menu/' local context_menu = { - mt = {} + mt = {}, } function context_menu:layout(_, width, height) if self._private.widget then return { - base.place_widget_at(self._private.widget, 0, 0, width, height) + base.place_widget_at(self._private.widget, 0, 0, width, height), } end end @@ -45,7 +46,7 @@ context_menu.set_widget = base.set_widget_common function context_menu:make_entries(wtemplate, entries, spacing) local menu_entries = { layout = wibox.layout.fixed.vertical, - spacing = spacing + spacing = spacing, } if not wtemplate then @@ -53,8 +54,7 @@ function context_menu:make_entries(wtemplate, entries, spacing) end for key, entry in pairs(entries) do - -- TODO: Figure out how to make a new widget from etemplate - local menu_entry = wibox.widget { + local menu_entry = base.make_widget_from_value { { { { @@ -62,72 +62,74 @@ function context_menu:make_entries(wtemplate, entries, spacing) { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role" + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, nil, { { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "arrow_role" + valign = 'center', + halign = 'center', + id = 'arrow_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.desktop.context_menu.entry_bg, fg = Theme_config.desktop.context_menu.entry_fg, - widget = wibox.container.background + widget = wibox.container.background, } - Hover_signal(menu_entry) + assert(type(menu_entry) == 'table', 'Entry must be a table') - menu_entry:get_children_by_id("icon_role")[1].image = entry.icon - menu_entry:get_children_by_id("text_role")[1].text = entry.name + hover.bg_hover { widget = menu_entry } + + menu_entry:get_children_by_id('icon_role')[1].image = entry.icon + menu_entry:get_children_by_id('text_role')[1].text = entry.name if entry.submenu then - menu_entry:get_children_by_id("arrow_role")[1].image = - gcolor.recolor_image(icondir .. "entry.svg", Theme_config.desktop.context_menu.entry_fg) + menu_entry:get_children_by_id('arrow_role')[1].image = + gcolor.recolor_image(icondir .. 'entry.svg', Theme_config.desktop.context_menu.entry_fg) end gtable.crush(menu_entry, entry, true) menu_entry:buttons(gtable.join { - abutton({ + abutton { modifiers = {}, button = 1, on_release = function() if not entry.submenu then entry.callback() end - capi.awesome.emit_signal("submenu::close") - capi.awesome.emit_signal("cm::hide") - end - }) + capi.awesome.emit_signal('submenu::close') + capi.awesome.emit_signal('cm::hide') + end, + }, }) if entry.submenu then @@ -139,7 +141,7 @@ function context_menu:make_entries(wtemplate, entries, spacing) border_width = Theme_config.desktop.context_menu.border_width, border_color = Theme_config.desktop.context_menu.border_color, shape = Theme_config.desktop.context_menu.shape, - visible = false + visible = false, } local hide_timer = gtimer { @@ -148,25 +150,25 @@ function context_menu:make_entries(wtemplate, entries, spacing) single_shot = true, callback = function() menu_entry.popup.visible = false - end + end, } - menu_entry:connect_signal("mouse::enter", function() + menu_entry:connect_signal('mouse::enter', function() -- place widget right of parent menu_entry.popup:move_next_to(capi.mouse.current_widget_geometry) hide_timer:stop() menu_entry.popup.visible = true end) - menu_entry.popup:connect_signal("mouse::leave", function() + menu_entry.popup:connect_signal('mouse::leave', function() hide_timer:again() end) - menu_entry.popup:connect_signal("mouse::enter", function() + menu_entry.popup:connect_signal('mouse::enter', function() hide_timer:stop() end) - menu_entry:connect_signal("mouse::leave", function() + menu_entry:connect_signal('mouse::leave', function() hide_timer:again() end) - capi.awesome.connect_signal("submenu::close", function() + capi.awesome.connect_signal('submenu::close', function() menu_entry.popup.visible = false end) end @@ -176,8 +178,11 @@ function context_menu:make_entries(wtemplate, entries, spacing) end function context_menu:toggle() - self.x = capi.mouse.coords().x - self.y = capi.mouse.coords().y + self.x = capi.mouse.coords().x - dpi(5) + self.y = capi.mouse.coords().y - dpi(5) + if self.y + self.height > capi.mouse.screen.geometry.height then + self.y = self.y - self.height + dpi(10) + end self.visible = not self.visible end @@ -190,8 +195,10 @@ function context_menu.new(args) gtable.crush(ret, context_menu, true) + local entries = ret:make_entries(args.widget_template, args.entries, args.spacing) + ret = awful.popup { - widget = ret:make_entries(args.widget_template, args.entries, args.spacing), + widget = entries, bg = Theme_config.desktop.context_menu.bg, fg = Theme_config.desktop.context_menu.fg, ontop = true, @@ -200,11 +207,11 @@ function context_menu.new(args) shape = Theme_config.desktop.context_menu.shape, visible = false, x = capi.mouse.coords().x + 10, - y = capi.mouse.coords().y - 10 + y = capi.mouse.coords().y - 10, } -- I literally have no clue how to do it better, it doesn't really matter anyways - capi.awesome.connect_signal("cm::hide", function() + capi.awesome.connect_signal('cm::hide', function() ret.visible = false end) diff --git a/awesome/src/modules/crylia_bar/center_bar.lua b/awesome/src/modules/crylia_bar/center_bar.lua index ec832a1..35382c0 100644 --- a/awesome/src/modules/crylia_bar/center_bar.lua +++ b/awesome/src/modules/crylia_bar/center_bar.lua @@ -2,10 +2,10 @@ -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') local capi = { awesome = awesome, @@ -17,7 +17,7 @@ return function(s, widgets) local function prepare_widgets(w) local layout = { forced_height = dpi(50), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, } for i, widget in pairs(w) do if i == 1 then @@ -28,7 +28,7 @@ return function(s, widgets) right = dpi(6), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) elseif i == #w then table.insert(layout, @@ -38,7 +38,7 @@ return function(s, widgets) right = dpi(6), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) else table.insert(layout, @@ -48,28 +48,28 @@ return function(s, widgets) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) end end return layout end - local top_center = awful.popup { + local top_center = apopup { screen = s, widget = prepare_widgets(widgets), ontop = false, bg = Theme_config.center_bar.bg, visible = true, maximum_width = dpi(500), - placement = function(c) awful.placement.top(c, { margins = dpi(10) }) end + placement = function(c) aplacement.top(c, { margins = dpi(10) }) end, } top_center:struts { - top = dpi(55) + top = dpi(55), } - capi.client.connect_signal("manage", function(c) + capi.client.connect_signal('manage', function(c) if #s.selected_tag:clients() < 1 then top_center.visible = false else @@ -77,7 +77,7 @@ return function(s, widgets) end end) - capi.client.connect_signal("unmanage", function(c) + capi.client.connect_signal('unmanage', function(c) if #s.selected_tag:clients() < 1 then top_center.visible = false else @@ -85,7 +85,7 @@ return function(s, widgets) end end) - capi.client.connect_signal("property::selected", function(c) + capi.client.connect_signal('property::selected', function(c) if #s.selected_tag:clients() < 1 then top_center.visible = false else @@ -93,7 +93,7 @@ return function(s, widgets) end end) - capi.awesome.connect_signal("refresh", function(c) + capi.awesome.connect_signal('refresh', function(c) if #s.selected_tag:clients() < 1 then top_center.visible = false else diff --git a/awesome/src/modules/crylia_bar/dock.lua b/awesome/src/modules/crylia_bar/dock.lua index be31528..33bd440 100644 --- a/awesome/src/modules/crylia_bar/dock.lua +++ b/awesome/src/modules/crylia_bar/dock.lua @@ -2,518 +2,594 @@ -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local Gio = require("lgi").Gio -local gears = require("gears") -local wibox = require("wibox") +local lgi = require('lgi') +local Gio = lgi.Gio +local abutton = require('awful.button') +local apopup = require('awful.popup') +local dpi = require('beautiful').xresources.apply_dpi +local gfilesystem = require('gears.filesystem') +local gtable = require('gears.table') +local wibox = require('wibox') +local gcolor = require('gears.color') +local awidget = require('awful.widget') +local aplacement = require('awful.placement') +local gtimer = require('gears.timer') +local amenu = require('awful.menu') + +-- Local libs +local config = require('src.tools.config') +local context_menu = require('src.modules.context_menu.init') +local hover = require('src.tools.hover') local capi = { awesome = awesome, client = client, mouse = mouse, + screen = screen, } -local json = require("src.lib.json-lua.json-lua") +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/' -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/context_menu/" +local elements = { + ['pinned'] = {}, + ['applauncher_starter'] = {}, + ['running'] = {}, +} -local cm = require("src.modules.context_menu.init") +local instances = {} -return function(screen) +local dock = { mt = {} } - local cm_open = false +--[[ Json format of dock.json, running apps won't be saved + [ + { + "applauncher_starter": { + { + "name": "Application Launcher", + "icon": "/usr/share/icons/Papirus/48x48/apps/xfce4-appfinder.svg", + } + }, + "pinned": [ + { + "name": "firefox", + "icon": "/usr/share/icons/Papirus/48x48/apps/firefox.svg", + "exec": "firefox", + "desktop_file": "/usr/share/applications/firefox.desktop" + }, + { + "name": "discord", + "icon": "/usr/share/icons/Papirus/48x48/apps/discord.svg", + "exec": "discord", + "desktop_file": "/usr/share/applications/discord.desktop" + } + ], + } + ] +]] - local dock_element_ammount = 0 +function dock:toggle() + self.popup.visible = not self.popup.visible +end - ---Creates a new program widget for the dock - ---@param program string | function The name of the .desktop file - ---@param size number The size of the widget - ---@return widox.widget | nil The widget or nil if the program is not found - local function create_dock_element(program, size) +function dock:write_elements_to_file_async(callback) + --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) +end - local dock_element = wibox.widget { +---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) + 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 +---@param desktop_file string .desktop file path +---@return nil +function dock:get_element_widget(desktop_file) + if not desktop_file then return end + + local GDesktopAppInfo = Gio.DesktopAppInfo.new_from_filename(desktop_file) + + local icon = Get_gicon_path(nil, GDesktopAppInfo.get_string(GDesktopAppInfo, 'Icon')) or + Get_gicon_path(nil, Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'X-AppImage-Old-Icon')) or '' + + local widget = wibox.widget { + { + { + { + { + widget = wibox.widget.imagebox, + image = icon, + valign = 'center', + halign = 'center', + resize = true, + id = 'icon_role', + }, + widget = wibox.container.constraint, + width = User_config.dock_icon_size, + height = User_config.dock_icon_size, + }, + widget = wibox.container.margin, + margins = dpi(5), + }, + widget = wibox.container.constraint, + width = User_config.dock_icon_size + dpi(10), -- + margins + height = User_config.dock_icon_size + dpi(10), + strategy = 'exact', + }, + bg = Theme_config.dock.element.bg, + shape = Theme_config.dock.element.shape, + widget = wibox.container.background, + } + + local action_entries = {} + for _, action in ipairs(Gio.DesktopAppInfo.list_actions(GDesktopAppInfo)) do + table.insert(action_entries, { + name = Gio.DesktopAppInfo.get_action_name(GDesktopAppInfo, action) or '', + icon = Get_gicon_path(nil, GDesktopAppInfo.get_string(GDesktopAppInfo, 'Icon')) or + Get_gicon_path(nil, Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'X-AppImage-Old-Icon')) or + gcolor.recolor_image(icondir .. 'entry.svg', Theme_config.dock.cm_icon), + callback = function() + Gio.DesktopAppInfo.launch_action(GDesktopAppInfo, action) + end, + }) + end + + table.insert(action_entries, { + name = 'Remove from Dock', + icon = gcolor.recolor_image(icondir .. 'context_menu/entry.svg', Theme_config.dock.cm_icon), + callback = function() + local data = config.read_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json') + for i, v in ipairs(data) do + if v.desktop_file == desktop_file then + if type(data) == 'table' then + table.remove(data, i) + end + break + end + end + config.write_json(gfilesystem.get_configuration_dir() .. 'src/config/dock_' .. self.screen.index .. '.json', data) + self:remove_element_widget(widget) + end, + }) + + widget.cm = context_menu { + widget_template = wibox.widget { { { { { - resize = true, widget = wibox.widget.imagebox, - image = program.icon or "", - valign = "center", - halign = "center", - id = "icon", + resize = true, + valign = 'center', + halign = 'center', + id = 'icon_role', }, - id = "icon_container", - strategy = "exact", - width = dpi(size), - height = dpi(size), - widget = wibox.container.constraint + widget = wibox.container.constraint, + stragety = 'exact', + width = dpi(24), + height = dpi(24), + id = 'const', }, - margins = dpi(5), - widget = wibox.container.margin, - id = "margin" + { + widget = wibox.widget.textbox, + valign = 'center', + halign = 'left', + id = 'text_role', + }, + layout = wibox.layout.fixed.horizontal, }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(10)) - end, - bg = Theme_config.dock.element_bg, - fg = "#000000", - widget = wibox.container.background, - id = "background" + widget = wibox.container.margin, }, - top = dpi(5), - left = dpi(5), - right = dpi(5), - widget = wibox.container.margin - } + widget = wibox.container.background, + }, spacing = dpi(10), + entries = action_entries, + } - Hover_signal(dock_element.background, Theme_config.dock.element_focused_bg .. "dd") + widget.cm:connect_signal('mouse::leave', function() + widget.cm.visible = false + self.cm_open = widget.cm.visible + end) - local DAI = Gio.DesktopAppInfo.new_from_filename(program.desktop_file) - if not DAI then return end - local action_entries = {} - for _, action in ipairs(program.actions) do - table.insert(action_entries, { - name = Gio.DesktopAppInfo.get_action_name(DAI, action) or "", - icon = gears.color.recolor_image(action.icon or icondir .. "entry.svg", Theme_config.dock.cm_icon), - callback = function() - Gio.DesktopAppInfo.launch_action(DAI, action) - end - }) + hover.bg_hover { + widget = widget, + overlay = 12, + press_overlay = 24, + } + + local exec = Gio.DesktopAppInfo.get_string(GDesktopAppInfo, 'Exec') + + widget:buttons(gtable.join { + abutton({}, 1, function() + Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(exec, nil, 0)) + end), + abutton({}, 3, function() + widget.cm:toggle() + self.cm_open = widget.cm.visible + end), + }) + + table.insert(elements['pinned'], widget) + self:emit_signal('dock::element_added', widget) +end + +---Removes a given widget from the dock +---@param widget wibox.widget The widget to remove +function dock:remove_element_widget(widget) + if not widget then return end + for k, v in pairs(elements['pinned']) do + if v == widget then + table.remove(elements['pinned'], k) + self:emit_signal('dock::element_removed', widget) + return end + end +end - table.insert(action_entries, { - name = "Remove from Dock", - icon = gears.color.recolor_image(icondir .. "entry.svg", Theme_config.dock.cm_icon), - callback = function() - local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r") - if not data then - return - end - local dock = json:decode(data:read("a")) - data:close() - for i, v in ipairs(dock) do - if v.desktop_file == program.desktop_file then - if type(dock) == "table" then - table.remove(dock, i) - end - break - end - end - data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "w") - if not data then - return - end - data:write(json:encode(dock)) - data:close() - capi.awesome.emit_signal("dock::changed") - end - }) +---Pins an element to the dock by adding it to the pinned table, then writes the table to the file +---emits the signal `dock::pin_element` then successfully added to the table +---@param args {desktop_file: string} The path to the .desktop file +function dock:pin_element(args) + if not args then return end - local context_menu = cm { - widget_template = wibox.widget { + local e = args.desktop_file + + assert(e, 'No desktop file provided') + + self:emit_signal('dock::pin_element', e) + + self:write_elements_to_file_async() +end + +function dock:add_start_element() + local widget = wibox.widget { + { + { { { - { - { - widget = wibox.widget.imagebox, - resize = true, - valign = "center", - halign = "center", - id = "icon_role", - }, - widget = wibox.container.constraint, - stragety = "exact", - width = dpi(24), - height = dpi(24), - id = "const" - }, - { - widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" - }, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + widget = wibox.widget.imagebox, + image = gfilesystem.get_configuration_dir() .. 'src/assets/CT.svg', + valign = 'center', + halign = 'center', + resize = true, + id = 'icon_role', }, - margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.constraint, + width = User_config.dock_icon_size, + height = User_config.dock_icon_size, }, - widget = wibox.container.background, - }, - entries = action_entries, - spacing = dpi(10), - } - - dock_element:buttons(gears.table.join( - awful.button({ - modifiers = {}, - button = 1, - on_release = function() - Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(program.exec, nil, 0)) - end - }), - awful.button({ - modifiers = {}, - button = 3, - on_release = function() - if not context_menu then - return - end - -- add offset so mouse is above widget, this is so the mouse::leave event triggers always - context_menu:toggle() - end - }) - )) - - capi.awesome.connect_signal( - "context_menu::hide", - function() - cm_open = false - capi.awesome.emit_signal("dock::check_for_dock_hide") - end - ) - - awful.tooltip { - objects = { dock_element }, - text = program.name, - mode = "outside", - preferred_alignments = "middle", - margins = dpi(10) - } - dock_element_ammount = dock_element_ammount + 1 - - return dock_element - end - - --- Indicators under the elements to indicate various open states - local function create_incicator_widget() - local container = { layout = wibox.layout.flex.horizontal } - - local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r") - - if not data then - return - end - - local prog = json:decode(data:read("a")) - data:close() - for _, pr in ipairs(prog) do - local indicators = { layout = wibox.layout.flex.horizontal, spacing = dpi(5) } - local col = Theme_config.dock.indicator_bg - for _, c in ipairs(capi.client.get()) do - local icon_name = string.lower(pr.icon) - if not c or not c.valid then return end - local cls = c.class or "" - local class = string.lower(cls) - icon_name = string.match(icon_name, ".*/(.*)%.[svg|png]") - if class == icon_name or class:match(icon_name) or icon_name:match(class) then - if c == capi.client.focus then - col = Theme_config.dock.indicator_focused_bg - elseif c.urgent then - col = Theme_config.dock.indicator_urgent_bg - elseif c.maximized then - col = Theme_config.dock.indicator_maximized_bg - elseif c.minimized then - col = Theme_config.dock.indicator_minimized_bg - elseif c.fullscreen then - col = Theme_config.dock.indicator_fullscreen_bg - else - col = Theme_config.dock.indicator_bg - end - table.insert(indicators, wibox.widget { - widget = wibox.container.background, - shape = gears.shape.rounded_rect, - forced_height = dpi(3), - bg = col, - forced_width = dpi(5), - }) - end - end - table.insert(container, wibox.widget { - indicators, - forced_height = dpi(5), - forced_width = dpi(User_config.dock_icon_size), - left = dpi(5), - right = dpi(5), widget = wibox.container.margin, - }) - end - return wibox.widget { - container, - bottom = dpi(5), - widget = wibox.container.margin, - } - end - - --- The container bar where the elements/program widgets sit in - local dock = awful.popup { + margins = dpi(5), + }, + widget = wibox.container.constraint, + width = User_config.dock_icon_size + dpi(10), -- + margins + height = User_config.dock_icon_size + dpi(10), + strategy = 'exact', + }, + bg = Theme_config.dock.element.bg, + shape = Theme_config.dock.element.shape, widget = wibox.container.background, - ontop = true, - bg = Theme_config.dock.bg, - visible = true, - screen = screen, - type = "dock", - height = dpi(User_config.dock_icon_size + 10), - placement = function(c) awful.placement.bottom(c, { margins = dpi(10) }) end } - --- A fakedock to send a signal when the mouse is over it - local fakedock = awful.popup { - widget = wibox.container.background, - ontop = true, - bg = '#00000000', - visible = true, - screen = screen, - type = "dock", - id = "fakedock", - height = dpi(10), - placement = function(c) awful.placement.bottom(c) end, + hover.bg_hover { + widget = widget, + overlay = 12, + press_overlay = 24, } - --- List of all elements/program widgets - local dock_elements = { layout = wibox.layout.fixed.horizontal } + widget:buttons(gtable.join { + abutton({}, 1, function() + capi.awesome.emit_signal('application_launcher::show') + end), + }) + return widget +end - --- This function creates a list with all dock elements/program widgets - ---@return table|nil string list of widgets - local function get_dock_elements() - dock_element_ammount = 0 - dock_elements = { layout = wibox.layout.fixed.horizontal } +---Unpins an element from the dock by removing it from the pinned table, then writes the table to the file +---emits the signal `dock::unpin_element` then successfully removed from the table +---@param args {desktop_file: string} The path to the .desktop file +function dock:unpin_element(args) + if not args then return end - local data = io.open("/home/crylia/.config/awesome/src/config/dock.json", "r") - if not data then - return + for index, value in ipairs(elements['pinned']) do + if value == args.desktop_file then + table.remove(elements['pinned'], index) + break; end - local dock_data = json:decode(data:read("a")) - data:close() - for _, program in ipairs(dock_data) do - table.insert(dock_elements, create_dock_element(program, User_config.dock_icon_size)) - end - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } + end + self:emit_signal('dock::unpin_element', args.desktop_file) + + self:write_elements_to_file_async() +end + +function dock:get_all_elements() + return elements +end + +function dock:get_applauncher_starter_element() + return elements['applauncher_starter'] +end + +function dock:get_pinned_elements() + return elements['pinned'] +end + +function dock:get_running_elements() + return elements['running'] +end + +function dock:get_dock_for_screen(screen) + return instances[screen] +end + +local function check_for_dock_hide(self, a_popup) + if self.cm_open then return end + local clients_on_tag = self.screen.selected_tag:clients() + + -- If there is no client on the current tag show the dock + if #clients_on_tag < 1 then + self.visible = true + return end - get_dock_elements() - - --- Function to get an empty list with the same ammount as dock_element - local function get_fake_elements() - local fake_elements = { layout = wibox.layout.fixed.horizontal } - - for i = 0, dock_element_ammount, 1 do - fake_elements[i] = wibox.widget { - bg = '00000000', - forced_width = User_config.dock_icon_size + dpi(20), - forced_height = dpi(10), - id = "fake", - widget = wibox.container.background - } - end - return fake_elements - end - - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - - ---Check if the dock needs to be hidden, I also put the topbar check here since it shares that logic - ---@param s screen The screen to check for hide - local function check_for_dock_hide(s) - local clients_on_tag = s.selected_tag:clients() - - -- If there is no client on the current tag show the dock - if #clients_on_tag < 1 then - dock.visible = true - return - end - - -- If there is a maximized client hide the dock and if fullscreened hide the activation area - for _, client in ipairs(clients_on_tag) do - if client.maximized or client.fullscreen then - dock.visible = false - if client.fullscreen then - fakedock.visible = false - capi.awesome.emit_signal("notification_center_activation::toggle", s, false) - end - elseif not client.fullscreen then - fakedock.visible = true - capi.awesome.emit_signal("notification_center_activation::toggle", s, true) - end - end - - - - if s == capi.mouse.screen then - local minimized = false - for _, c in ipairs(clients_on_tag) do - if c.minimized then - minimized = true - else - minimized = false - local y = c:geometry().y - local h = c.height - if (y + h) >= s.geometry.height - User_config.dock_icon_size - 35 then - dock.visible = false - return - else - dock.visible = true - end - end - end - if minimized then - dock.visible = true - end - else + -- If there is a maximized client hide the dock and if fullscreened hide the activation area + for _, client in ipairs(clients_on_tag) do + if client.maximized or client.fullscreen then dock.visible = false + if client.fullscreen then + a_popup.visible = false + capi.awesome.emit_signal('notification_center_activation::toggle', self.screen, false) + end + elseif not client.fullscreen then + a_popup.visible = true + capi.awesome.emit_signal('notification_center_activation::toggle', self.screen, true) end end + if self.screen == capi.mouse.screen then + local minimized = false + for _, c in ipairs(clients_on_tag) do + if c.minimized then + minimized = true + else + minimized = false + local y = c:geometry().y + local h = c.height + if (y + h) >= self.screen.geometry.height - User_config.dock_icon_size - 35 then + self.visible = false + return + else + self.visible = true + end + end + end + if minimized then + self.visible = true + end + else + self.visible = false + end +end + +function dock:activation_area() + local activation = apopup { + widget = { + width = self.screen.geometry.width / 4, + height = 1, + strategy = 'exact', + widget = wibox.container.constraint, + }, + ontop = true, + bg = gcolor.transparent, + visible = false, + screen = self.screen, + type = 'dock', + placement = function(c) aplacement.bottom(c) end, + } + -- Call the function every second to check if the dock needs to be hidden - local dock_intelligent_hide = gears.timer { + local dock_hide = gtimer { timeout = 1, autostart = true, call_now = true, callback = function() - check_for_dock_hide(screen) - end + check_for_dock_hide(self, activation) + end, } - --- Hover function to show the dock - fakedock:connect_signal( - "mouse::enter", - function() - if #screen.clients < 1 then - dock.visible = true - dock_intelligent_hide:stop() + activation:connect_signal('mouse::enter', function() + if #self.screen.clients < 1 then + self.visible = true + dock_hide:stop() + return + end + for _, c in ipairs(self.screen.clients) do + if not c.fullscreen then + self.visible = true + dock_hide:stop() + end + end + end) + + self:connect_signal('mouse::enter', function() + dock_hide:stop() + end) + + self:connect_signal('mouse::leave', function() + --[[ if cm_open then return - end - for _, c in ipairs(screen.clients) do - if not c.fullscreen then - dock.visible = true - dock_intelligent_hide:stop() - end - end - end - ) - - capi.client.connect_signal( - "manage", - function() - check_for_dock_hide(screen) - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - end - ) - - capi.client.connect_signal( - "property::minimized", - function() - check_for_dock_hide(screen) - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - end - ) - - capi.client.connect_signal( - "unmanage", - function() - check_for_dock_hide(screen) - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - end - ) - - capi.client.connect_signal( - "focus", - function() - check_for_dock_hide(screen) - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - end - ) - - capi.awesome.connect_signal( - "dock::changed", - function() - get_dock_elements() - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } - fakedock:setup { - get_fake_elements(), - type = 'dock', - layout = wibox.layout.fixed.vertical - } - end - ) - - capi.awesome.connect_signal( - "dock::check_for_dock_hide", - function() - dock_intelligent_hide:again() - end - ) - - dock:connect_signal( - "mouse::enter", - function() - dock_intelligent_hide:stop() - end - ) - - dock:connect_signal( - "mouse::leave", - function() - if cm_open then - return - end - check_for_dock_hide(screen) - dock_intelligent_hide:again() - end - ) - dock:setup { - dock_elements, - create_incicator_widget(), - layout = wibox.layout.fixed.vertical - } + end ]] + check_for_dock_hide(self, activation) + dock_hide:again() + end) end + +function dock.new(args) + args = args or {} + + local w = apopup { + widget = { + { + { + spacing = dpi(5), + id = 'applauncher_starter', + layout = wibox.layout.fixed.horizontal, + }, + wibox.widget.separator { + forced_width = dpi(2), + forced_height = dpi(20), + thickness = dpi(2), + color = Theme_config.dock.element.border, + }, + { + spacing = dpi(5), + id = 'pinned', + layout = wibox.layout.fixed.horizontal, + }, + { + id = 'running', + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }, + spacing = dpi(10), + id = 'elements', + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.margin, + margins = dpi(5), + }, + ontop = true, + visible = true, + placement = function(c) aplacement.bottom(c, { margins = dpi(10) }) end, + bg = Theme_config.dock.bg, + screen = args.screen, + } + + gtable.crush(w, dock) + + instances[args.screen] = w + + w:activation_area() + + w.task_list = awidget.tasklist { + screen = args.screen, + layout = wibox.layout.fixed.horizontal, + filter = awidget.tasklist.filter.alltags, + update_function = function(widget, _, _, _, clients) + widget:reset() + + if #clients == 0 then + return widget + end + + widget:add { + { + widget = wibox.widget.separator, + forced_height = dpi(20), + forced_width = dpi(2), + thickness = dpi(2), + color = Theme_config.dock.element.border, + }, + widget = wibox.container.margin, + right = dpi(5), + } + + for _, client in ipairs(clients) do + local element = wibox.widget { + { + { + { + { + widget = wibox.widget.imagebox, + image = client.icon, + valign = 'center', + halign = 'center', + resize = true, + id = 'icon_role', + }, + widget = wibox.container.constraint, + width = User_config.dock_icon_size, + height = User_config.dock_icon_size, + }, + widget = wibox.container.margin, + margins = dpi(5), + }, + widget = wibox.container.constraint, + width = User_config.dock_icon_size + dpi(10), -- + margins + height = User_config.dock_icon_size + dpi(10), + strategy = 'exact', + }, + bg = Theme_config.dock.element.bg, + shape = Theme_config.dock.element.shape, + widget = wibox.container.background, + } + + hover.bg_hover { + widget = element, + overlay = 12, + press_overlay = 24, + } + + element:buttons(gtable.join( + abutton({}, 1, function(c) + if c == client.focus then + c.minimized = true + else + c:emit_signal('request::activate', 'tasklist', { raise = true }) + end + end), + abutton({}, 3, function() + amenu.client_list { theme = { width = dpi(250) } } + end) + )) + + widget:add(element) + widget:set_spacing(dpi(5)) + end + + return widget + end, + } + + w.widget.elements.applauncher_starter:add(w:add_start_element()) + + w.widget.elements.running:add(w.task_list) + + w:connect_signal('dock::element_added', function(_, widget) + w.widget.elements.pinned:add(widget) + end) + + w:connect_signal('dock::element_removed', function(_, widget) + w.widget.elements.pinned:remove_widgets(widget) + end) + + w:connect_signal('dock::pin_element', function(_, element) + w:get_element_widget(element) + end) + + capi.awesome.connect_signal('dock::pin_element', function(args) + w:pin_element(args) + end) + + w:connect_signal('dock::unpin_element', function(_, widget) + w:remove_element_widget(widget) + end) + + w:read_elements_from_file_async() + + return w +end + +return setmetatable(dock, { __call = function(_, ...) return dock.new(...) end }) diff --git a/awesome/src/modules/crylia_bar/init.lua b/awesome/src/modules/crylia_bar/init.lua index 5d29bb1..c803644 100644 --- a/awesome/src/modules/crylia_bar/init.lua +++ b/awesome/src/modules/crylia_bar/init.lua @@ -10,42 +10,42 @@ return function(s) local widget_table = {} if widgets then for _, widget in ipairs(widgets) do - if widget == "Audio" then - table.insert(widget_table, require("src.widgets.audio")(s)) - elseif widget == "Battery" then - table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind)) - elseif widget == "Bluetooth" then - table.insert(widget_table, require("src.widgets.bluetooth")(s)) - elseif widget == "Clock" then - table.insert(widget_table, require("src.widgets.clock")()) - elseif widget == "Cpu Frequency" then - table.insert(widget_table, require("src.widgets.cpu_info")("freq")) - elseif widget == "Cpu Temperature" then - table.insert(widget_table, require("src.widgets.cpu_info")("temp")) - elseif widget == "Cpu Usage" then - table.insert(widget_table, require("src.widgets.cpu_info")("usage")) - elseif widget == "Date" then - table.insert(widget_table, require("src.widgets.date")(s)) - elseif widget == "Gpu Temperature" then - table.insert(widget_table, require("src.widgets.gpu_info")("temp")) - elseif widget == "Gpu Usage" then - table.insert(widget_table, require("src.widgets.gpu_info")("usage")) - elseif widget == "Keyboard Layout" then - table.insert(widget_table, require("src.widgets.kblayout")(s)) - elseif widget == "Tiling Layout" then - table.insert(widget_table, require("src.widgets.layout_list")()) - elseif widget == "Network" then - table.insert(widget_table, require("src.widgets.network") { screen = s }) - elseif widget == "Power Button" then - table.insert(widget_table, require("src.widgets.power")()) - elseif widget == "Ram Usage" then - table.insert(widget_table, require("src.widgets.ram_info")()) - elseif widget == "Systray" then - table.insert(widget_table, require("src.widgets.systray")(s)) - elseif widget == "Taglist" then - table.insert(widget_table, require("src.widgets.taglist")(s)) - elseif widget == "Tasklist" then - table.insert(widget_table, require("src.widgets.tasklist")(s)) + if widget == 'Audio' then + table.insert(widget_table, require('src.widgets.audio')(s)) + elseif widget == 'Battery' then + table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind)) + elseif widget == 'Bluetooth' then + table.insert(widget_table, require('src.widgets.bluetooth')(s)) + elseif widget == 'Clock' then + table.insert(widget_table, require('src.widgets.clock')()) + elseif widget == 'Cpu Frequency' then + table.insert(widget_table, require('src.widgets.cpu_info')('freq')) + elseif widget == 'Cpu Temperature' then + table.insert(widget_table, require('src.widgets.cpu_info')('temp')) + elseif widget == 'Cpu Usage' then + table.insert(widget_table, require('src.widgets.cpu_info')('usage')) + elseif widget == 'Date' then + table.insert(widget_table, require('src.widgets.date')(s)) + elseif widget == 'Gpu Temperature' then + table.insert(widget_table, require('src.widgets.gpu_info')('temp')) + elseif widget == 'Gpu Usage' then + table.insert(widget_table, require('src.widgets.gpu_info')('usage')) + elseif widget == 'Keyboard Layout' then + table.insert(widget_table, require('src.widgets.kblayout')(s)) + elseif widget == 'Tiling Layout' then + table.insert(widget_table, require('src.widgets.layout_list')()) + elseif widget == 'Network' then + table.insert(widget_table, require('src.widgets.network') { screen = s }) + elseif widget == 'Power Button' then + table.insert(widget_table, require('src.widgets.power')()) + elseif widget == 'Ram Usage' then + table.insert(widget_table, require('src.widgets.ram_info')()) + elseif widget == 'Systray' then + table.insert(widget_table, require('src.widgets.systray')()) + elseif widget == 'Taglist' then + table.insert(widget_table, require('src.widgets.taglist')(s)) + elseif widget == 'Tasklist' then + table.insert(widget_table, require('src.widgets.tasklist')(s)) end end end @@ -56,16 +56,16 @@ return function(s) for index, screen in ipairs(User_config.crylia_bar) do if index == s.index then if screen.left_bar then - require("src.modules.crylia_bar.left_bar")(s, get_widgets(screen.left_bar)) + require('src.modules.crylia_bar.left_bar')(s, get_widgets(screen.left_bar)) end if screen.center_bar then - require("src.modules.crylia_bar.center_bar")(s, get_widgets(screen.center_bar)) + require('src.modules.crylia_bar.center_bar')(s, get_widgets(screen.center_bar)) end if screen.right_bar then - require("src.modules.crylia_bar.right_bar")(s, get_widgets(screen.right_bar)) + require('src.modules.crylia_bar.right_bar')(s, get_widgets(screen.right_bar)) end end end end - require("src.modules.crylia_bar.dock")(s) + require('src.modules.crylia_bar.dock') { screen = s } end diff --git a/awesome/src/modules/crylia_bar/left_bar.lua b/awesome/src/modules/crylia_bar/left_bar.lua index a1e22bf..ab1c7da 100644 --- a/awesome/src/modules/crylia_bar/left_bar.lua +++ b/awesome/src/modules/crylia_bar/left_bar.lua @@ -2,16 +2,15 @@ -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local wibox = require("wibox") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') return function(s, w) - local function prepare_widgets(widgets) local layout = { forced_height = dpi(50), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, } for i, widget in pairs(widgets) do if i == 1 then @@ -22,7 +21,7 @@ return function(s, w) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) elseif i == #widgets then table.insert(layout, @@ -32,7 +31,7 @@ return function(s, w) right = dpi(6), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) else table.insert(layout, @@ -42,7 +41,7 @@ return function(s, w) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) end end @@ -50,17 +49,17 @@ return function(s, w) end local top_left = awful.popup { - screen = s, - widget = prepare_widgets(w), - ontop = false, - bg = Theme_config.left_bar.bg, - visible = true, - maximum_width = dpi(650), - placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end - } + screen = s, + widget = prepare_widgets(w), + ontop = false, + bg = Theme_config.left_bar.bg, + visible = true, + maximum_width = dpi(650), + placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end, + } top_left:struts { - top = dpi(55) + top = dpi(55), } Global_config.top_struts = dpi(55) diff --git a/awesome/src/modules/crylia_bar/right_bar.lua b/awesome/src/modules/crylia_bar/right_bar.lua index 58684ac..2fd677d 100644 --- a/awesome/src/modules/crylia_bar/right_bar.lua +++ b/awesome/src/modules/crylia_bar/right_bar.lua @@ -2,16 +2,15 @@ -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local wibox = require("wibox") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') return function(s, w) - local function prepare_widgets(widgets) local layout = { forced_height = dpi(50), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, } for i, widget in pairs(widgets) do if i == 1 then @@ -22,7 +21,7 @@ return function(s, w) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) elseif i == #widgets then table.insert(layout, @@ -32,7 +31,7 @@ return function(s, w) right = dpi(6), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) else table.insert(layout, @@ -42,7 +41,7 @@ return function(s, w) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) end end @@ -55,11 +54,11 @@ return function(s, w) bg = Theme_config.right_bar.bg, visible = true, screen = s, - placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end + placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end, } top_right:struts { - top = dpi(55) + top = dpi(55), } Global_config.top_struts = top_right diff --git a/awesome/src/modules/crylia_wibox/init.lua b/awesome/src/modules/crylia_wibox/init.lua index a85e278..08c446f 100644 --- a/awesome/src/modules/crylia_wibox/init.lua +++ b/awesome/src/modules/crylia_wibox/init.lua @@ -1,9 +1,9 @@ -------------------------------------------------------------------------------------------------------------- -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -local wibox = require("wibox") -local dpi = require("beautiful").xresources.apply_dpi -local gshape = require("gears.shape") +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi +local gshape = require('gears.shape') return function(s) ---Lookup function to return the widget from its easy name string @@ -13,42 +13,42 @@ return function(s) local widget_table = {} if widgets then for _, widget in ipairs(widgets) do - if widget == "Audio" then - table.insert(widget_table, require("src.widgets.audio")(s)) - elseif widget == "Battery" then - table.insert(widget_table, require("src.widgets.battery")(User_config.battery_kind)) - elseif widget == "Bluetooth" then - table.insert(widget_table, require("src.widgets.bluetooth")()) - elseif widget == "Clock" then - table.insert(widget_table, require("src.widgets.clock")()) - elseif widget == "Cpu Frequency" then - table.insert(widget_table, require("src.widgets.cpu_info")("freq", User_config.cpu_frequency)) - elseif widget == "Cpu Temperature" then - table.insert(widget_table, require("src.widgets.cpu_info")("temp")) - elseif widget == "Cpu Usage" then - table.insert(widget_table, require("src.widgets.cpu_info")("usage")) - elseif widget == "Date" then - table.insert(widget_table, require("src.widgets.date")()) - elseif widget == "Gpu Temperature" then - table.insert(widget_table, require("src.widgets.gpu_info")("temp")) - elseif widget == "Gpu Usage" then - table.insert(widget_table, require("src.widgets.gpu_info")("usage")) - elseif widget == "Keyboard Layout" then - table.insert(widget_table, require("src.widgets.kblayout")(s)) - elseif widget == "Tiling Layout" then - table.insert(widget_table, require("src.widgets.layout_list")()) - elseif widget == "Network" then - table.insert(widget_table, require("src.widgets.network")()) - elseif widget == "Power Button" then - table.insert(widget_table, require("src.widgets.power")()) - elseif widget == "Ram Usage" then - table.insert(widget_table, require("src.widgets.ram_info")()) - elseif widget == "Systray" then - table.insert(widget_table, require("src.widgets.systray")(s)) - elseif widget == "Taglist" then - table.insert(widget_table, require("src.widgets.taglist")(s)) - elseif widget == "Tasklist" then - table.insert(widget_table, require("src.widgets.tasklist")(s)) + if widget == 'Audio' then + table.insert(widget_table, require('src.widgets.audio')(s)) + elseif widget == 'Battery' then + table.insert(widget_table, require('src.widgets.battery')(User_config.battery_kind)) + elseif widget == 'Bluetooth' then + table.insert(widget_table, require('src.widgets.bluetooth')()) + elseif widget == 'Clock' then + table.insert(widget_table, require('src.widgets.clock')()) + elseif widget == 'Cpu Frequency' then + table.insert(widget_table, require('src.widgets.cpu_info')('freq', User_config.cpu_frequency)) + elseif widget == 'Cpu Temperature' then + table.insert(widget_table, require('src.widgets.cpu_info')('temp')) + elseif widget == 'Cpu Usage' then + table.insert(widget_table, require('src.widgets.cpu_info')('usage')) + elseif widget == 'Date' then + table.insert(widget_table, require('src.widgets.date')()) + elseif widget == 'Gpu Temperature' then + table.insert(widget_table, require('src.widgets.gpu_info')('temp')) + elseif widget == 'Gpu Usage' then + table.insert(widget_table, require('src.widgets.gpu_info')('usage')) + elseif widget == 'Keyboard Layout' then + table.insert(widget_table, require('src.widgets.kblayout')(s)) + elseif widget == 'Tiling Layout' then + table.insert(widget_table, require('src.widgets.layout_list')()) + elseif widget == 'Network' then + table.insert(widget_table, require('src.widgets.network')()) + elseif widget == 'Power Button' then + table.insert(widget_table, require('src.widgets.power')()) + elseif widget == 'Ram Usage' then + table.insert(widget_table, require('src.widgets.ram_info')()) + elseif widget == 'Systray' then + table.insert(widget_table, require('src.widgets.systray')()) + elseif widget == 'Taglist' then + table.insert(widget_table, require('src.widgets.taglist')(s)) + elseif widget == 'Tasklist' then + table.insert(widget_table, require('src.widgets.tasklist')(s)) end end end @@ -61,7 +61,7 @@ return function(s) local function prepare_widgets(widgets) local layout = { forced_height = dpi(50), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, } for i, widget in pairs(widgets) do if i == 1 then @@ -72,7 +72,7 @@ return function(s) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) elseif i == #widgets then table.insert(layout, @@ -82,7 +82,7 @@ return function(s) right = dpi(6), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) else table.insert(layout, @@ -92,7 +92,7 @@ return function(s) right = dpi(3), top = dpi(6), bottom = dpi(6), - widget = wibox.container.margin + widget = wibox.container.margin, }) end end @@ -109,17 +109,17 @@ return function(s) visible = true, x = 0, y = 1035, - type = "desktop", + type = 'desktop', height = dpi(55), width = 1920, - bg = "#212121", + bg = '#212121', shape = function(cr, width, height) gshape.partially_rounded_rect(cr, width, height, true, true, false, false, 8) end, } w:struts { - bottom = dpi(55) + bottom = dpi(55), } Global_config.bottom_struts = dpi(55) diff --git a/awesome/src/modules/desktop/context_menu.lua b/awesome/src/modules/desktop/context_menu.lua deleted file mode 100644 index 80276fe..0000000 --- a/awesome/src/modules/desktop/context_menu.lua +++ /dev/null @@ -1,52 +0,0 @@ -local base = require("wibox.widget.base") -local awful = require("awful") -local gtable = require("gears.table") -local gfilesystem = require("gears.filesystem") -local gcolor = require("gears.color") -local wibox = require("wibox") -local dpi = require("beautiful").xresources.apply_dpi -local gobject = require("gears.object") - - -local cm = require("src.modules.context_menu.init") - -local capi = { - awesome = awesome -} - -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/" - -local context_menu = { mt = {} } -context_menu._private = {} - -function context_menu:toggle() - self._private.popup.x = mouse.coords().x - 10 - self._private.popup.y = mouse.coords().y - 10 - self._private.popup.visible = not self._private.popup.visible -end - -function context_menu.new(args) - args = args or {} - - local ret = gobject {} - gtable.crush(ret, context_menu, true) - - capi.awesome.connect_signal("context_menu:show", function() - ret:toggle() - mousegrabber.run(function() - if mouse.current_wibox ~= ret._private.popup then - ret:toggle() - return false - end - return true - end, nil) - end) - - return ret -end - -function context_menu.mt:__call(...) - return context_menu.new(...) -end - -return setmetatable(context_menu, context_menu.mt) diff --git a/awesome/src/modules/desktop/desktop.lua b/awesome/src/modules/desktop/desktop.lua index d2e5fa5..d8e62b9 100644 --- a/awesome/src/modules/desktop/desktop.lua +++ b/awesome/src/modules/desktop/desktop.lua @@ -1,33 +1,30 @@ -local base = require("wibox.widget.base") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local gshape = require("gears.shape") -local grid = require("wibox.layout.grid") -local wibox = require("wibox") -local abutton = require("awful.button") -local awful = require("awful") -local gcolor = require("gears.color") -local json = require("src.lib.json-lua.json-lua") -local gfilesystem = require("gears.filesystem") -local Gio = require("lgi").Gio +local Gio = require('lgi').Gio +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local grid = require('wibox.layout.grid') +local gshape = require('gears.shape') +local gtable = require('gears.table') +local wibox = require('wibox') -local element = require("src.modules.desktop.element") -local cm = require("src.modules.context_menu.init") +local config = require('src.tools.config') +local element = require('src.modules.desktop.element') +local cm = require('src.modules.context_menu.init') local capi = { mouse = mouse, awesome = awesome, screen = screen, } - -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/desktop/' local desktop = { mt = {} } function desktop:save_layout() local layout = {} - local dir = gfilesystem.get_configuration_dir() .. "src/config/files/desktop/icons/" + local dir = gfilesystem.get_configuration_dir() .. 'src/config/files/desktop/icons/' if not gfilesystem.dir_readable(dir) then gfilesystem.make_directories(dir) end @@ -40,54 +37,45 @@ function desktop:save_layout() col = pos.col, widget = { icon = widget.icon, - label = widget:get_children_by_id("text_role")[1].text, + label = widget.label, exec = widget.exec, - icon_size = widget.icon_size - } + icon_size = widget.icon_size, + }, } end - dir = gfilesystem.get_configuration_dir() .. "src/config" + dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json' gfilesystem.make_directories(dir) - if not gfilesystem.file_readable(dir .. "/desktop.json") then - os.execute("touch " .. dir .. "/desktop.json") - end - local handler = io.open(dir .. "/desktop.json", "w") - if not handler then return end - - handler:write(json:encode(layout)) - handler:close() + config.write_json(dir, layout) end function desktop:load_layout() - local dir = gfilesystem.get_configuration_dir() .. "src/config" - if not gfilesystem.file_readable(dir .. "/desktop.json") then - return - end - local handler = io.open(dir .. "/desktop.json", "r") - if not handler then return end + local dir = gfilesystem.get_configuration_dir() .. 'src/config/desktop.json' + if not gfilesystem.file_readable(dir) then return end - local layout = json:decode(handler:read("*all")) - handler:close() - if not layout then return end - for i, value in pairs(layout) do + local data = config.read_json(dir) + if not data then return end + for _, value in pairs(data) do self:add_element(value.widget, { x = value.row, y = value.col }) end end function desktop:get_element_at(x, y) - return self.widget.mrgn.grid:get_widgets_at(x, y)[1] + local w = self.widget.mrgn.grid:get_widgets_at(x, y) + return w and w[1] or nil end function desktop:add_desktop_file(app_info) - self:add_element({ + self:add_element { icon = app_info.icon, label = app_info.label, exec = app_info.exec, - icon_size = dpi(96), + icon_size = dpi(48), desktop_file = app_info.desktop_file, parent = self.widget.mrgn.grid, - }) + width = self.widget_width, + height = self.widget_height, + } end --[[ @@ -98,18 +86,17 @@ function desktop:remove_element(e) end function desktop:get_grid_index_at(y, x) - local col, row = 1, 1 + local margin_x, margin_y = dpi(10), dpi(10) + local screen_width, screen_height = self.args.screen.geometry.width - margin_x * 2, self.args.screen.geometry.height - dpi(75) - dpi(95) - margin_y * 2 + local cell_width, cell_height = screen_width / 20, screen_height / 11 - local width = dpi(96) * 1.75 * (4 / 3) - local height = dpi(96) * 1.75 - local spacing = dpi(10) + local col = math.floor((x - margin_x) / cell_width) + 1 + col = math.min(col, 20) + col = math.max(col, 1) - while width * col + spacing * (col - 1) < x do - col = col + 1 - end - while height * row + spacing * (row - 1) < y do - row = row + 1 - end + local row = math.floor((y - margin_y) / cell_height) + 1 + row = math.min(row, 11) + row = math.max(row, 1) return col, row end @@ -133,7 +120,9 @@ function desktop:add_element(args, pos) exec = args.exec, icon_size = args.icon_size, desktop_file = args.desktop_file, - parent = args.parent + parent = args.parent, + width = self.widget_width, + height = self.widget_height, } local cm_popup = cm { @@ -144,106 +133,98 @@ function desktop:add_element(args, pos) { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role", + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, }, spacing = dpi(10), entries = { { - name = "Open with", - icon = gcolor.recolor_image(icondir .. "launch.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Open with', + icon = gcolor.recolor_image(icondir .. 'launch.svg', Theme_config.desktop.context_menu.icon_color), submenu = { --!TODO: Fetch programs and add them as entries - } + }, }, { - name = "Copy", - icon = gcolor.recolor_image(icondir .. "copy.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Copy', + icon = gcolor.recolor_image(icondir .. 'copy.svg', Theme_config.desktop.context_menu.icon_color), callback = function() - end + end, }, { - name = "Cut", - icon = gcolor.recolor_image(icondir .. "cut.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Cut', + icon = gcolor.recolor_image(icondir .. 'cut.svg', Theme_config.desktop.context_menu.icon_color), callback = function() - end + end, }, { - name = "Rename", - icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Rename', + icon = gcolor.recolor_image(icondir .. 'edit.svg', Theme_config.desktop.context_menu.icon_color), callback = function() - end + end, }, { - name = "Remove", - icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Remove', + icon = gcolor.recolor_image(icondir .. 'delete.svg', Theme_config.desktop.context_menu.icon_color), callback = function() self:remove_element(e) self:save_layout() - end + end, }, { - name = "Actions", - icon = gcolor.recolor_image(icondir .. "dots-vertical.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Actions', + icon = gcolor.recolor_image(icondir .. 'dots-vertical.svg', Theme_config.desktop.context_menu.icon_color), submenu = { -- TODO: fetch actions from desktop file - } + }, }, - } + }, } - cm_popup:connect_signal("mouse::leave", function() + cm_popup:connect_signal('mouse::leave', function() cm_popup.visible = false end) - local cols = math.floor(self.args.screen.geometry.width / (args.icon_size * 1.75 * (4 / 3))) - local rows = math.floor((self.args.screen.geometry.height - 75 + 95) / (args.icon_size * 1.75)) - print(cols, rows) -- While the mouse is down, remove the element from the grid and add it to manual then move it -- until the mouse is released and then add it back to the grid. - e:connect_signal("button::press", function(_, _, _, b) - local start_pos = mouse.coords() - + e:connect_signal('button::press', function(_, _, _, b) if not mousegrabber.isrunning() then - local width = (self.args.screen.geometry.width - 20 - ((cols - 1) * 10)) / cols - local height = (self.args.screen.geometry.height - 170 - 20) / rows - local dnd_widget = element { icon = args.icon, label = args.label, - on_click = args.on_click, + exec = args.exec, icon_size = args.icon_size, + desktop_file = args.desktop_file, parent = args.parent, - width = width, - height = height, + width = self.widget_width, + height = self.widget_height, } dnd_widget.visible = false - dnd_widget:get_children_by_id("icon_role")[1].opacity = 0.6 - - local xp, yp = capi.mouse.coords() - dnd_widget.point = { x = xp, y = yp } + dnd_widget:get_children_by_id('icon_role')[1].opacity = 0.6 + local start_pos = capi.mouse.coords() + dnd_widget.point = { x = math.floor(start_pos.x - self.args.screen.geometry.x), y = math.floor(start_pos.y - self.args.screen.geometry.y) } local old_pos = self.widget.mrgn.grid:get_widget_position(e) self.widget.manual:add(dnd_widget) mousegrabber.run(function(m) @@ -254,22 +235,29 @@ function desktop:add_element(args, pos) m.buttons[1] then self:remove_element(e) dnd_widget.visible = true - dnd_widget.bg = gcolor("#0ffff088") - dnd_widget.border_color = gcolor("#0ffff0") - self.widget.manual:move_widget(dnd_widget, { x = m.x - dnd_widget.width / 2, y = m.y - dnd_widget.height / 2 }) + dnd_widget.bg = gcolor('#0ffff088') + dnd_widget.border_color = gcolor('#0ffff0') + + self.widget.manual:move_widget(dnd_widget, { + x = (m.x - dnd_widget.width / 2) - self.args.screen.geometry.x, + y = (m.y - dnd_widget.height / 2) - self.args.screen.geometry.y, + }) end if not m.buttons[1] then if b == 1 then - dnd_widget.bg = gcolor("#0ffff088") - dnd_widget.border_color = gcolor("#0ffff0") + dnd_widget.bg = gcolor('#0ffff088') + dnd_widget.border_color = gcolor('#0ffff0') if dnd_widget.visible then dnd_widget.visible = false - local np_x, np_y = self:get_grid_index_at(m.y, m.x) - if not self.widget.mrgn.grid:get_widgets_at(np_y, np_x) then - self.widget.mrgn.grid:add_widget_at(e, np_y, np_x) + local newp_x, newp_y = self:get_grid_index_at( + (m.y - dnd_widget.height / 2) - self.args.screen.geometry.y, + (m.x - dnd_widget.width / 2) - self.args.screen.geometry.x + ) + if not self.widget.mrgn.grid:get_widgets_at(newp_y, newp_x) then + self.widget.mrgn.grid:add_widget_at(e, newp_y, newp_x) self:save_layout() else self.widget.mrgn.grid:add_widget_at(e, old_pos.row, old_pos.col) @@ -286,7 +274,7 @@ function desktop:add_element(args, pos) end return m.buttons[1] - end, "left_ptr") + end, 'left_ptr') end end) @@ -299,62 +287,83 @@ function desktop:draw_selector() if not mousegrabber.isrunning() then local selector = wibox.widget { widget = wibox.container.background, - bg = gcolor("#0ffff088"), - border_color = gcolor("#0ffff0"), + bg = gcolor('#0ffff088'), + border_color = gcolor('#0ffff0'), border_width = dpi(2), forced_width = 0, forced_height = 0, - x = start_pos.x, - y = start_pos.y, + x = start_pos.x - self.args.screen.geometry.x, + y = start_pos.y - self.args.screen.geometry.y, visible = true, shape = function(cr, w, h) gshape.rounded_rect(cr, w, h, dpi(10)) - end + end, } - selector.point = { x = start_pos.x, y = start_pos.y } + selector.point = { x = start_pos.x - self.args.screen.geometry.x, y = start_pos.y - self.args.screen.geometry.y } self.widget.manual:add(selector) mousegrabber.run(function(m) if m.buttons[1] then selector.visible = true end if not m.buttons[1] then - print("stop") mousegrabber.stop() selector.visible = false self.widget.manual:reset() end - selector.forced_width = selector.forced_width + ((start_pos.x - m.x) * -1) - selector.forced_height = selector.forced_width + ((start_pos.y - m.y) * -1) - - print(selector.forced_width, selector.forced_height) + local dx = m.x - start_pos.x + local dy = m.y - start_pos.y + local gx, gy = self:get_grid_index_at(math.abs(dy), math.abs(dx)) + selector.forced_width = math.abs(dx) + selector.forced_height = math.abs(dy) + --if the mouse is moving to the left, move the widget to the left + if dx < 0 then + selector.x = start_pos.x - self.args.screen.geometry.x + dx + selector.point.x = start_pos.x - self.args.screen.geometry.x + dx + gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x) + end + --if the mouse is moving up, move the widget up + if dy < 0 then + selector.y = start_pos.y - self.args.screen.geometry.y + dy + selector.point.y = start_pos.y - self.args.screen.geometry.y + dy + gx, gy = self:get_grid_index_at(selector.point.y, selector.point.x) + end + -- check if a widget is inside the selector + local w = self:get_element_at(gx, gy) + if w then + w.bg = gcolor('#0ffff088') + w.border_color = gcolor('#0ffff0') + end return m.buttons[1] - end, "left_ptr") + end, 'left_ptr') end end function desktop:add_xdg() - self:add_element({ - icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg", - label = "Papierkorb", - exec = "nautilus trash:/", - icon_size = 96, - }) + self:add_element { + icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-trash.svg', + label = 'Papierkorb', + exec = 'nautilus trash:/', + icon_size = dpi(48), + } - self:add_element({ - icon = "/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg", - label = "Persönlicher Ordner", - exec = "nautilus file:/home/crylia", - icon_size = 96, - }) + self:add_element { + icon = '/usr/share/icons/Papirus-Dark/96x96/places/user-home.svg', + label = 'Persönlicher Ordner', + exec = 'nautilus file:/home/crylia', + icon_size = dpi(48), + } end function desktop.new(args) args = args or {} - local icon_size = args.icon_size or dpi(96) + args.icon_size = dpi(48) + + local rows = 20 + local cols = 11 + local h_spacing = dpi(10) + local v_spacing = dpi(20) - local cols = math.floor(args.screen.geometry.width / (icon_size * 1.75 * (4 / 3))) - local rows = math.floor((args.screen.geometry.height - 75 + 95) / (icon_size * 1.75)) --[[ The wibox has a stacked layout with a manual layout over a grid. @@ -368,10 +377,10 @@ function desktop.new(args) local w = wibox { ontop = false, visible = true, - type = "desktop", + type = 'desktop', input_passthrough = false, - x = 0, - y = 0, + x = args.screen.geometry.x, + y = args.screen.geometry.y, bg = gcolor.transparent, width = args.screen.geometry.width, height = args.screen.geometry.height, @@ -381,26 +390,27 @@ function desktop.new(args) { layout = grid, homogeneous = true, - spacing = 10, - expand = true, - orientation = "horizontal", - forced_num_cols = cols, - forced_num_rows = rows, - id = "grid", + horizontal_spacing = h_spacing, + vertical_spacing = v_spacing, + expand = false, + orientation = 'horizontal', + forced_num_cols = rows, + forced_num_rows = cols, + id = 'grid', }, widget = wibox.container.margin, left = dpi(10), right = dpi(10), top = dpi(75), bottom = dpi(95), - id = "mrgn" + id = 'mrgn', }, { layout = wibox.layout.manual, - id = "manual", + id = 'manual', }, layout = wibox.layout.stack, - } + }, } w.args = args @@ -413,158 +423,158 @@ function desktop.new(args) { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role", + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, }, spacing = dpi(10), entries = { { - name = "Create new", - icon = gcolor.recolor_image(icondir .. "file_add.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Create new', + icon = gcolor.recolor_image(icondir .. 'file_add.svg', Theme_config.desktop.context_menu.icon_color), submenu = { { - name = "Folder", - icon = gcolor.recolor_image(icondir .. "folder.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Folder', + icon = gcolor.recolor_image(icondir .. 'folder.svg', Theme_config.desktop.context_menu.icon_color), callback = function() --create a new folder and if it exists add a number to the end - local folder_name = "New folder" - local folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name + local folder_name = 'New folder' + local folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name local i = 1 while gfilesystem.dir_readable(folder_path) do - folder_name = "New folder " .. "(" .. i .. ")" - folder_path = os.getenv("HOME") .. "/Desktop/" .. folder_name + folder_name = 'New folder ' .. '(' .. i .. ')' + folder_path = os.getenv('HOME') .. '/Desktop/' .. folder_name i = i + 1 end gfilesystem.make_directories(folder_path) - w:add_element({ - icon = "/usr/share/icons/Papirus-Dark/24x24/places/folder.svg", + w:add_element { + icon = '/usr/share/icons/Papirus-Dark/24x24/places/folder.svg', label = folder_name, - exec = "nautilus file:\"" .. folder_path .. "\"", - icon_size = icon_size, - }) - end + exec = 'nautilus file:\"' .. folder_path .. '\"', + icon_size = dpi(48), + } + end, }, { - name = "File", - icon = gcolor.recolor_image(icondir .. "file.svg", Theme_config.desktop.context_menu.icon_color), + name = 'File', + icon = gcolor.recolor_image(icondir .. 'file.svg', Theme_config.desktop.context_menu.icon_color), callback = function() --create new text file and if it exists add a number to the end - local file_name = "New file.txt" - local file_path = os.getenv("HOME") .. "/Desktop/" .. file_name + local file_name = 'New file.txt' + local file_path = os.getenv('HOME') .. '/Desktop/' .. file_name local i = 1 while gfilesystem.file_readable(file_path) do - file_name = "New file " .. "(" .. i .. ")" - file_path = os.getenv("HOME") .. "/Desktop/" .. file_name + file_name = 'New file ' .. '(' .. i .. ')' + file_path = os.getenv('HOME') .. '/Desktop/' .. file_name i = i + 1 end - awful.spawn.with_shell("touch " .. file_path) - w:add_element({ - icon = "/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg", + awful.spawn.with_shell('touch ' .. file_path) + w:add_element { + icon = '/usr/share/icons/Papirus-Dark/24x24/mimetypes/text-plain.svg', label = file_name, - exec = "xdg-open " .. file_path, - icon_size = icon_size, - }) - end - } - } + exec = 'xdg-open ' .. file_path, + icon_size = dpi(48), + } + end, + }, + }, }, { - name = "Terminal", - icon = gcolor.recolor_image(icondir .. "terminal.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Terminal', + icon = gcolor.recolor_image(icondir .. 'terminal.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.terminal) - end + end, }, { - name = "Web Browser", - icon = gcolor.recolor_image(icondir .. "web_browser.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Web Browser', + icon = gcolor.recolor_image(icondir .. 'web_browser.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.web_browser) - end + end, }, { - name = "File Manager", - icon = gcolor.recolor_image(icondir .. "file_manager.svg", Theme_config.desktop.context_menu.icon_color), + name = 'File Manager', + icon = gcolor.recolor_image(icondir .. 'file_manager.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.file_manager) - end + end, }, { - name = "Text Editor", - icon = gcolor.recolor_image(icondir .. "text_editor.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Text Editor', + icon = gcolor.recolor_image(icondir .. 'text_editor.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.text_editor) - end + end, }, { - name = "Music Player", - icon = gcolor.recolor_image(icondir .. "music_player.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Music Player', + icon = gcolor.recolor_image(icondir .. 'music_player.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.music_player) - end + end, }, { - name = "Applications", - icon = gcolor.recolor_image(icondir .. "application.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Applications', + icon = gcolor.recolor_image(icondir .. 'application.svg', Theme_config.desktop.context_menu.icon_color), callback = function() - end + end, }, { - name = "GTK Settings", - icon = gcolor.recolor_image(icondir .. "gtk_settings.svg", Theme_config.desktop.context_menu.icon_color), + name = 'GTK Settings', + icon = gcolor.recolor_image(icondir .. 'gtk_settings.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.gtk_settings) - end + end, }, { - name = "Energy Settings", - icon = gcolor.recolor_image(icondir .. "energy_settings.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Energy Settings', + icon = gcolor.recolor_image(icondir .. 'energy_settings.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.energy_manager) - end + end, }, { - name = "Screen Settings", - icon = gcolor.recolor_image(icondir .. "screen_settings.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Screen Settings', + icon = gcolor.recolor_image(icondir .. 'screen_settings.svg', Theme_config.desktop.context_menu.icon_color), callback = function() awful.spawn(User_config.screen_settings) - end + end, }, { - name = "Reload Awesome", - icon = gcolor.recolor_image(icondir .. "refresh.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Reload Awesome', + icon = gcolor.recolor_image(icondir .. 'refresh.svg', Theme_config.desktop.context_menu.icon_color), callback = function() capi.awesome.restart() - end + end, }, { - name = "Quit", - icon = gcolor.recolor_image(icondir .. "quit.svg", Theme_config.desktop.context_menu.icon_color), + name = 'Quit', + icon = gcolor.recolor_image(icondir .. 'quit.svg', Theme_config.desktop.context_menu.icon_color), callback = function() capi.awesome.quit() - end + end, }, --cm_awesome - } + }, } w.widget.manual:buttons(gtable.join( @@ -583,9 +593,12 @@ function desktop.new(args) gtable.crush(w, desktop, true) + w.widget_width = (args.screen.geometry.width - 20 - ((h_spacing - 1) * rows)) / rows + w.widget_height = (args.screen.geometry.height - 170 - ((v_spacing - 1) * cols)) / cols + w:load_layout() - capi.awesome.connect_signal("desktop::add_to_desktop", function(args2) + capi.awesome.connect_signal('desktop::add_to_desktop', function(args2) w:add_desktop_file(args2) end) diff --git a/awesome/src/modules/desktop/element.lua b/awesome/src/modules/desktop/element.lua index 17e24be..89a0e50 100644 --- a/awesome/src/modules/desktop/element.lua +++ b/awesome/src/modules/desktop/element.lua @@ -1,17 +1,11 @@ -local base = require("wibox.widget.base") -local wibox = require("wibox") -local gtable = require("gears.table") -local dpi = require("beautiful").xresources.apply_dpi -local gshape = require("gears.shape") -local gfilesystem = require("gears.filesystem") -local gcolor = require("gears.color") -local abutton = require("awful.button") - -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/desktop/" - -local capi = { - mouse = mouse -} +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gshape = require('gears.shape') +local gtable = require('gears.table') +local lgi = require('lgi') +local cairo = lgi.cairo +local wibox = require('wibox') local element = { mt = {} } @@ -34,30 +28,174 @@ function element:get_widget() end function element:on_hover() - self:connect_signal("mouse::enter", function() - self.bg = "#0ffff033" - self.border_color = "#0ffff099" + self:connect_signal('mouse::enter', function() + self.bg = '#0ffff033' + self.border_color = '#0ffff099' end) - --[[ self:connect_signal("mouse::leave", function() + self:connect_signal('mouse::leave', function() self.bg = gcolor.transparent self.border_color = gcolor.transparent - end) ]] - - self:connect_signal("button::press", function() - self.bg = "#0ffff088" - self.border_color = "#0ffff0dd" end) - self:connect_signal("button::release", function() - self.bg = "#0ffff033" - self.border_color = "#0ffff099" + self:connect_signal('button::press', function() + self.bg = '#0ffff088' + self.border_color = '#0ffff0dd' end) + + self:connect_signal('button::release', function() + self.bg = '#0ffff033' + self.border_color = '#0ffff099' + end) +end + +---Get the cairo extents for any text with its give size and font +---@param font string A font +---@param font_size number Font size +---@param text string Text to get the extent for +---@param args table Additional arguments +---@return userdata cairo.Extent +local function cairo_text_extents(font, font_size, text, args) + local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0) + local cr = cairo.Context(surface) + cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + cr:set_font_size(font_size) + cr:set_antialias(cairo.Antialias.BEST) + return cr:text_extents(text) +end + +local function split_string(str, max_width) + local line1 = '' + local line2 = '' + local line1_width = 0 + local line2_width = 0 + local font = 'JetBrainsMono Nerd Font' + local font_size = dpi(16) + local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD } + + for word in str:gmatch('%S+') do + local word_width = cairo_text_extents(font, font_size, word, font_args).width + if line1_width + word_width < max_width then + line1 = line1 .. word .. ' ' + line1_width = line1_width + word_width + else + line2 = line2 .. word .. ' ' + line2_width = line2_width + word_width + end + end + + return line1, line2 +end + +---This function takes any text and uses cairo to draw an outline and a shadow +---It also wraps the text correctly if max_width would be violated. It only uses two lines for wraping +---the rest is cut off. +---@param text string Text to be changed +---@param max_width number max width the text won't go over +---@return cairo.Surface cairo_surface manupulated text as a cairo surface +---@return table `width`,`height` The surface dimensions +local function outlined_text(text, max_width) + local font = 'JetBrainsMono Nerd Font' + local font_size = dpi(16) + local spacing = dpi(5) + local margin = dpi(5) + max_width = max_width - (margin * 2) + local shadow_offset_x, shadow_offset_y = 1, 1 + local font_args = { cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD } + + -- Get the dimensions from the text + local extents = cairo_text_extents(font, font_size, text, font_args) + + -- if its bigger it needs special treatment + if extents.width > max_width then + + local line1, line2 = split_string(text, max_width) + + -- Get the dimensions for both lines + local extents1 = cairo_text_extents(font, font_size, line1, font_args) + local extents2 = cairo_text_extents(font, font_size, line2, font_args) + + -- The surface width will be the biggest of the two lines + local s_width = extents1.width + if extents1.width < extents2.width then + s_width = extents2.width + end + + -- Create a new surface based on the widest line, and both line's height + the spacing between them and the shadow offset + local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, s_width + shadow_offset_x, extents1.height + extents2.height + spacing + (shadow_offset_y * 3)) + local cr = cairo.Context(surface) + + -- Create the font with best antialias + cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + cr:set_font_size(font_size) + cr:set_antialias(cairo.Antialias.BEST) + + -- To center both lines get the surface center then substract half the line width + local text_x = s_width / 2 - ((extents1.width) / 2) + local text_x2 = s_width / 2 - ((extents2.width) / 2) + + -- This makes the first text to be blow the main text + cr:set_operator(cairo.Operator.OVER) + + -- Draw the text shadow + cr:move_to(text_x + shadow_offset_x, -extents1.y_bearing + shadow_offset_y) + cr:set_source_rgba(0, 0, 0, 0.5) + cr:show_text(line1) + + cr:set_operator(cairo.Operator.OVER) + + -- Draw the second shadow + cr:move_to(text_x2 + shadow_offset_x, extents1.height + extents2.height + spacing + shadow_offset_y) + cr:set_source_rgba(0, 0, 0, 0.5) + cr:show_text(line2) + + -- Draw the first and second line + cr:move_to(text_x, -extents1.y_bearing) + cr:set_source_rgb(1, 1, 1) + cr:text_path(line1) + cr:move_to(text_x2, extents1.height + extents2.height + spacing) + cr:text_path(line2) + + -- Color it and set the stroke + cr:fill_preserve() + cr:set_source_rgb(0, 0, 0) + cr:set_line_width(0.1) + cr:stroke() + + return surface, { width = extents.width, height = extents1.height + extents2.height + spacing } + else + -- The size is the dimension from above the if + local surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, extents.width, extents.height + shadow_offset_y) + local cr = cairo.Context(surface) + + -- Set the font, then draw the text and its stroke + cr:select_font_face(font, cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + cr:set_font_size(font_size) + + -- This makes the first text to be blow the main text + cr:set_operator(cairo.Operator.OVER) + + -- Draw the text shadow + cr:move_to(-extents.x_bearing + shadow_offset_x, -extents.y_bearing + shadow_offset_y) + cr:set_source_rgba(0, 0, 0, 0.5) + cr:show_text(text) + + cr:move_to(-extents.x_bearing, -extents.y_bearing) + cr:set_source_rgb(1, 1, 1) + cr:text_path(text) + cr:fill_preserve() + cr:set_source_rgb(0, 0, 0) + cr:set_line_width(0.1) + cr:stroke() + return surface, { width = extents.width, height = extents.height } + end end function element.new(args) args = args or {} + local text_img, size = outlined_text(args.label, args.width) + local w = base.make_widget_from_value(wibox.widget { { { @@ -66,31 +204,34 @@ function element.new(args) image = args.icon, resize = true, clip_shape = gshape.rounded_rect, - valign = "center", - halign = "center", - id = "icon_role", - widget = wibox.widget.imagebox + valign = 'top', + halign = 'center', + id = 'icon_role', + forced_width = args.icon_size, + forced_height = args.icon_size, + widget = wibox.widget.imagebox, }, - strategy = "exact", - height = args.icon_size, - width = args.icon_size, - widget = wibox.container.constraint + widget = wibox.container.margin, + top = dpi(5), + left = dpi(20), + right = dpi(20), + bottom = dpi(5), }, { - text = args.label, - id = "text_role", - valign = "center", - halign = "center", - widget = wibox.widget.textbox + image = text_img, + resize = false, + valign = 'bottom', + halign = 'center', + widget = wibox.widget.imagebox, }, spacing = dpi(10), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.align.vertical, }, + valign = 'center', + halign = 'center', widget = wibox.container.place, - valign = "center", - halign = "center" }, - fg = "#ffffff", + fg = '#ffffff', bg = gcolor.transparent, border_color = gcolor.transparent, border_width = dpi(2), @@ -102,9 +243,12 @@ function element.new(args) exec = args.exec, icon_size = args.icon_size, icon = args.icon, - widget = wibox.container.background + label = args.label, + widget = wibox.container.background, }) + assert(w, 'No widget returned') + gtable.crush(w, element, true) w:on_hover() diff --git a/awesome/src/modules/init.lua b/awesome/src/modules/init.lua index 5a35788..a15c1c8 100644 --- a/awesome/src/modules/init.lua +++ b/awesome/src/modules/init.lua @@ -2,27 +2,45 @@ -- This is the statusbar, every widget, module and so on is combined to all the stuff you see on the screen -- -------------------------------------------------------------------------------------------------------------- -- Awesome Libs -local awful = require("awful") +local awful = require('awful') awful.screen.connect_for_each_screen(function(s) -- Create 9 tags awful.layout.append_default_layouts(User_config.layouts) - awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, User_config.layouts[1]) + awful.tag({ '1', '2', '3', '4', '5', '6', '7', '8', '9' }, s, User_config.layouts[1]) - require("src.modules.desktop.desktop") { screen = s } - require("src.modules.powermenu.powermenu")(s) - require("src.modules.audio.volume_osd") { screen = s } - --require("src.modules.audio.volume_controller") { screen = s } - require("src.modules.brightness.brightness_osd") { screen = s } - require("src.modules.crylia_bar.init")(s) - --require("src.modules.crylia_wibox.init")(s) - require("src.modules.notification-center.init")(s) - require("src.modules.window_switcher.init")(s) - require("src.modules.application_launcher.init") { screen = s } - --require("src.modules.network_controller.init") { screen = s } + require('src.modules.desktop.desktop') { screen = s } + require('src.modules.crylia_bar.init')(s) + --require('src.modules.crylia_wibox.init')(s) + require('src.modules.notification-center.init') { screen = s } + --require('src.modules.window_switcher.init')(s) + require('src.modules.application_launcher.init') { screen = s } end) -do - require("src.lib.nice") { titlebar_font = User_config.font.bold, - titlebar_items = { left = { "icon" }, right = { "minimize", "maximize", "close" } } } -end +local ip = require('src.modules.inputbox.new') { + text = 'inputboxtest', + cursor_pos = 4, + highlight = { + start_pos = 1, + end_pos = 4, + }, + text_hint = 'Input Some Text', +} + +awful.popup { + widget = ip.widget, + bg = '#212121', + visible = true, + screen = 1, + placement = awful.placement.centered, +} + +--[[ require('src.modules.inputbox.init') { + text = 'inputboxtest', + cursor_pos = 4, + highlight = { + start_pos = 5, + end_pos = 8, + }, +} + ]] diff --git a/awesome/src/modules/inputbox/init.lua b/awesome/src/modules/inputbox/init.lua new file mode 100644 index 0000000..18a2604 --- /dev/null +++ b/awesome/src/modules/inputbox/init.lua @@ -0,0 +1,796 @@ +--------------------------------------------------------------------------- +-- This widget can be used to type text and get the text from it. +--@DOC_wibox_widget_defaults_inputbox_EXAMPLE@ +-- +-- @author Rene Kievits +-- @copyright 2022, Rene Kievits +-- @module awful.widget.inputbox +--------------------------------------------------------------------------- + +local setmetatable = setmetatable +local beautiful = require('beautiful') +local gtable = require('gears.table') +local base = require('wibox.widget.base') +local gstring = require('gears.string') +local akeygrabber = require('awful.keygrabber') +local akey = require('awful.key') +local textbox = require('wibox.widget.textbox') +local imagebox = require('wibox.widget.imagebox') +local cairo = require('lgi').cairo +local apopup = require('awful.popup') +local aplacement = require('awful.placement') +local gsurface = require('gears.surface') +local wibox = require('wibox') +local abutton = require('awful.button') + +local capi = { + selection = selection, + mousegrabber = mousegrabber, + mouse = mouse, +} + +local inputbox = { mt = {} } + +--- Formats the text with a cursor and highlights if set. +--[[ local function text_with_cursor(text, cursor_pos, self) + local char, spacer, text_start, text_end + + local cursor_fg = beautiful.inputbox_cursor_fg or '#313131' + local cursor_bg = beautiful.inputbox_cursor_bg or '#0dccfc' + local placeholder_text = self.hint_text or '' + local placeholder_fg = beautiful.inputbox_placeholder_fg or '#777777' + local highlight_bg = beautiful.inputbox_highlight_bg or '#35ffe4' + local highlight_fg = beautiful.inputbox_highlight_fg or '#000000' + + if text == '' then + return "" .. placeholder_text .. '' + end + + local offset = 0 + if text:sub(cursor_pos - 1, cursor_pos - 1) == -1 then + offset = 1 + end + + if #text < cursor_pos then + char = ' ' + spacer = '' + text_start = gstring.xml_escape(text) + text_end = '' + else + char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset)) + spacer = ' ' + text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1)) + text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1)) + end + + if self._private.highlight and self._private.highlight.start_pos and self._private.highlight.end_pos then + -- split the text into 3 parts based on the highlight and cursor position + local text_start_highlight = gstring.xml_escape(text:sub(1, self._private.highlight.start_pos - 1)) + local text_highlighted = gstring.xml_escape(text:sub(self._private.highlight.start_pos, + self._private.highlight.end_pos)) + local text_end_highlight = gstring.xml_escape(text:sub(self._private.highlight.end_pos + 1)) + + return text_start_highlight .. + "" .. + text_highlighted .. '' .. text_end_highlight + else + return text_start .. "" .. + char .. '' .. text_end .. spacer + end +end ]] + +local function text_extents(text, font, font_size, args) + local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0) + local cr = cairo.Context(surface) + cr:select_font_face(font, args) + cr:set_font_size(font_size) + return cr:text_extents(text) +end + +--[[ + calculate width/height of the text + create new surface with the calculated width/height + draw a vertical line on the surface as the cursor + the position of the vertical line will be the cursor_pos - text length and the text extend + draw the "text" .. "cursor" .. "rest of the text" + return the surface + + mouse_coord holds the coordinates where the user clicked + if its not empty then draw the cursor where the user clicked, + if its on a character then set the cursor to the closest space + + if some text is highlighted then draw the text with the highlights +]] +--inputbox.text +--inputbox.cursor_pos <<-- 1 = before the text, 2 = after the first character, 3 = after the second character, etc +--inputbox.highlight <<-- { start_pos, end_pos } +--inputbox.mouse_coord <<-- { x, y } (Will be saved after the user clicked, it will only be overwritten when the user clicks again) +function inputbox:draw_text_surface(x, override_cursor) + -- x can be 0 for the first time its drawn with a default cursor position + x = x or 0 + + --Colors need to be in rgba 0-1 format, table.unpack is used to unpack the table into function arguments + local fg, fg_highlight, bg_highlight, fg_cursor = { 1, 1, 1 }, { 1, 1, 1 }, { 0.1, 1, 1, 0.5 }, { 1, 1, 1 } + + -- Main text_entent mainly to align everything to this one (it knows the highest and lowest point of the text) + local text_extent = text_extents(self:get_text(), self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + + --The offset if so the user has some space to click on the left and right side of the text + local start_offset = 4 + local end_offset = 4 + local surface = cairo.ImageSurface(cairo.Format.ARGB32, text_extent.width + start_offset + end_offset, text_extent.height) + local cr = cairo.Context(surface) + + --Split the text initially into 2 or 3 parts (most likely split again later) + local text = self:get_text() + local text_start, text_end, text_highlight + if self._private.highlight.start_pos ~= self._private.highlight.end_pos then + text_start = text:sub(1, self._private.highlight.start_pos - 1) + text_highlight = text:sub(self._private.highlight.start_pos, self._private.highlight.end_pos) + text_end = text:sub(self._private.highlight.end_pos + 1) + else + text_start = text:sub(1, self._private.cursor_pos - 1) + text_end = text:sub(self._private.cursor_pos) + end + + --Figure out the cursor position based on the mouse coordinates + if override_cursor then + local cursor_pos = 1 + for i = 1, #text, 1 do + -- Not sure if I need new context's to check the character width but I got inconsistent results without it + local ccr = cairo.Context(surface) + ccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + ccr:set_font_size(self.font_size) + local ext_c = ccr:text_extents(text:sub(1, i)) + if ext_c.width >= x then + local cccr = cairo.Context(surface) + cccr:select_font_face(self.font, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + cccr:set_font_size(self.font_size) + if math.abs(cccr:text_extents(text:sub(1, i - 1)).width - x) <= math.abs(ext_c.width - x) then + cursor_pos = i + else + cursor_pos = i + 1 + end + break + else + cursor_pos = #text + 1 + end + end + self._private.cursor_pos = cursor_pos + end + -- Text extents for the start and highlight without any splitting (less calculating, text_end is not needed) + local text_start_extents = text_extents(text_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + local text_highlight_extents = text_extents(text_highlight, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + + cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.REGULAR) + cr:set_font_size(self.font_size) + --[[ + The following code is a bit of a mess because I have to check if the cursor is inside the highlighted text, + the text_start or text_end and then split either of them again to draw the cursor between. + ]] + if (self._private.cursor_pos > 1) and text_highlight then + -- If the cursor is inside the highlighted text + if (self._private.highlight.start_pos <= self._private.cursor_pos) and (self._private.highlight.end_pos >= self._private.cursor_pos) then + -- Draw the text_start + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset, -text_extent.y_bearing) + cr:show_text(text_start) + + -- split the text_highlight at the cursor_pos + local text_highlight_start = text_highlight:sub(1, self._private.cursor_pos - self._private.highlight.start_pos) + local text_highlight_end = text_highlight:sub(self._private.cursor_pos - self._private.highlight.start_pos + 1) + -- The text_highlight_start extents are needed for the cursor position and the text_highlight_end position + local text_highlight_start_extents = text_extents(text_highlight_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + + -- Draw the first highlighted part(text_highlight_start) + cr:set_source_rgb(table.unpack(fg_highlight)) + cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_highlight_start) + + -- Draw the cursor + cr:set_source_rgb(table.unpack(fg_cursor)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.y_bearing) + cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, text_extent.height) + cr:stroke() + + -- Draw the second highlighted part(text_highlight_end) + cr:set_source_rgb(table.unpack(fg_highlight)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_highlight_end) + + -- Draw the text_end + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_end) + + -- Draw the background highlight + cr:set_source_rgba(table.unpack(bg_highlight)) + cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height) + cr:fill() + elseif self._private.cursor_pos < self._private.highlight.start_pos then -- If its inside the text_start + -- Split the text_start at the cursor_pos + local text_start_start = text_start:sub(1, self._private.cursor_pos - 1) + local text_start_end = text_start:sub(self._private.cursor_pos) + -- The text_start_start extents is needed for the cursor position and the text_start_end position + local text_start_start_extents = text_extents(text_start_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + + -- Draw the first part of the text_start(text_start_start) + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset, -text_extent.y_bearing) + cr:show_text(text_start_start) + + -- Draw the cursor + cr:set_source_rgb(table.unpack(fg_cursor)) + cr:move_to(start_offset + text_start_start_extents.x_advance, text_extent.y_bearing) + cr:line_to(start_offset + text_start_start_extents.x_advance, text_extent.height) + cr:stroke() + + -- Draw the second part of the text_start(text_start_end) + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_start_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_start_end) + + -- Draw the text_highlight + cr:set_source_rgb(table.unpack(fg_highlight)) + cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_highlight) + + -- Draw the text_end + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_end) + + -- Draw the highlight background + cr:set_source_rgba(table.unpack(bg_highlight)) + cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height) + cr:fill() + elseif self._private.cursor_pos > self._private.highlight.end_pos then -- If its inside the text_end + -- Draw the text start + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset, -text_extent.y_bearing) + cr:show_text(text_start) + + -- Draw the text highlight + cr:set_source_rgb(table.unpack(fg_highlight)) + cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_highlight) + + --split the text_end at the cursor_pos + local text_end_start = text_end:sub(1, self._private.cursor_pos - self._private.highlight.end_pos - 1) + local text_end_end = text_end:sub(self._private.cursor_pos - self._private.highlight.end_pos) + -- Text end_start extents needed for the cursor position and the text_end_end + local text_end_start_extents = text_extents(text_end_start, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + + -- Draw the first part of the text_end (text_end_start) + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_end_start) + + -- Draw the cursor + cr:set_source_rgb(table.unpack(fg_cursor)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.y_bearing) + cr:line_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, text_extent.height) + cr:stroke() + + -- Draw the second part of the text_end (text_end_end) + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_start_extents.x_advance + text_highlight_extents.x_advance + text_end_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_end_end) + + -- Draw the highlight background + cr:set_source_rgba(table.unpack(bg_highlight)) + cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height) + cr:fill() + end + else -- If the cursor is all the way to the left no split is needed + -- text_start + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset, -text_extent.y_bearing) + cr:show_text(text_start) + + -- Cursor + cr:set_source_rgb(table.unpack(fg_cursor)) + cr:move_to(start_offset + text_start_extents.x_advance, text_extent.y_bearing) + cr:line_to(start_offset + text_start_extents.x_advance, text_extent.height) + cr:stroke() + + -- text_highlight + if text_highlight then + cr:set_source_rgb(table.unpack(fg_highlight)) + cr:move_to(start_offset + text_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_highlight) + cr:set_source_rgba(table.unpack(bg_highlight)) + cr:rectangle(start_offset + text_start_extents.x_advance, text_extent.y_advance, text_highlight_extents.width, text_extent.height) + cr:fill() + end + + -- text_end + cr:set_source_rgb(table.unpack(fg)) + cr:move_to(start_offset + text_highlight_extents.x_advance + text_start_extents.x_advance, -text_extent.y_bearing) + cr:show_text(text_end) + end + return surface +end + +function inputbox:layout(_, width, height) + if self._private.widget then + return { base.place_widget_at(self._private.widget, 0, 0, width, height) } + end +end + +function inputbox:fit(context, width, height) + local w, h = 0, 0 + if self._private.widget then + w, h = base.fit_widget(self, context, self._private.widget, width, height) + end + return w, h +end + +inputbox.set_widget = base.set_widget_common + +--- Clears the current text +function inputbox:clear() + self:set_text('') +end + +function inputbox:get_text() + return self._private.text or '' +end + +function inputbox:set_text(text) + self._private.text = text + --self.markup = text_with_cursor(self:get_text(), #self:get_text(), self) + self:emit_signal('property::text', text) +end + +--- Stop the keygrabber and mousegrabber +function inputbox:stop() + if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end + self:emit_signal('stopped') + self.akeygrabber.stop() +end + +function inputbox:focus() + if (not self.akeygrabber) or (not self.akeygrabber.is_running) then + akeygrabber.stop() + self:run() + end + + self:connect_signal('button::press', function() + if capi.mouse.current_widget ~= self then + self:emit_signal('keygrabber::stop', '') + end + end) +end + +--- Init the inputbox and start the keygrabber +function inputbox:run() + if not self._private.text then self._private.text = '' end + + -- Init the cursor position, but causes on refocus the cursor to move to the left + local cursor_pos = self._private.cursor_pos or #self:get_text() + 1 + + -- Init and reset(when refocused) the highlight + self._private.highlight = {} + + self.akeygrabber = akeygrabber { + autostart = true, + start_callback = function() + self:emit_signal('started') + end, + stop_callback = function(_, stop_key) + if stop_key == 'Return' then + self:emit_signal('submit', self:get_text(), stop_key) + else + self:emit_signal('stopped', stop_key) + end + end, + stop_key = { 'Escape', 'Return' }, + keybindings = { + --lShift, rShift = #50, #62 + --lControl, rControl = #37, #105 + akey { + modifiers = { 'Shift' }, + key = 'Left', -- left + on_press = function() + if cursor_pos > 1 then + local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0 + if not self._private.highlight.start_pos then + self._private.highlight.start_pos = cursor_pos - 1 + end + if not self._private.highlight.end_pos then + self._private.highlight.end_pos = cursor_pos + end + + if self._private.highlight.start_pos < cursor_pos then + self._private.highlight.end_pos = self._private.highlight.end_pos - 1 + else + self._private.highlight.start_pos = self._private.highlight.start_pos + end + + cursor_pos = cursor_pos - 1 + end + if cursor_pos < 1 then + cursor_pos = 1 + elseif cursor_pos > #self._private.text + 1 then + cursor_pos = #self._private.text + 1 + end + self._private.cursor_pos = cursor_pos + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Shift', 'Left') + end, + }, + akey { + modifiers = { 'Shift' }, + key = 'Right', -- right + on_press = function() + if #self._private.text >= cursor_pos then + if not self._private.highlight.end_pos then + self._private.highlight.end_pos = cursor_pos - 1 + end + if not self._private.highlight.start_pos then + self._private.highlight.start_pos = cursor_pos + end + + if self._private.highlight.end_pos <= cursor_pos then + self._private.highlight.end_pos = self._private.highlight.end_pos + 1 + else + self._private.highlight.start_pos = self._private.highlight.start_pos + 1 + end + cursor_pos = cursor_pos + 1 + if cursor_pos > #self._private.text + 1 then + self._private.highlight = {} + end + end + if cursor_pos < 1 then + cursor_pos = 1 + elseif cursor_pos > #self._private.text + 1 then + cursor_pos = #self._private.text + 1 + end + self._private.cursor_pos = cursor_pos + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Shift', 'Right') + end, + }, + akey { + modifiers = { 'Control' }, + key = 'a', -- a + on_press = function() + -- Mark the entire text + self._private.highlight = { + start_pos = 1, + end_pos = #self._private.text, + } + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Control', 'a') + end, + }, + akey { + modifiers = { 'Control' }, + key = 'v', -- v + on_press = function() + local sel = capi.selection() + if sel then + sel = sel:gsub('\n', '') + if self._private.highlight and self._private.highlight.start_pos and + self._private.highlight.end_pos then + -- insert the text into the selected part + local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1) + local text_end = self._private.text:sub(self._private.highlight.end_pos + 1) + self:set_text(text_start .. sel .. text_end) + self._private.highlight = {} + cursor_pos = #text_start + #sel + 1 + else + self:set_text(self._private.text:sub(1, cursor_pos - 1) .. + sel .. self._private.text:sub(cursor_pos)) + cursor_pos = cursor_pos + #sel + end + end + + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Control', 'v') + end, + }, + akey { + modifiers = { 'Control' }, + key = 'c', -- c + on_press = function() + --TODO + end, + }, + akey { + modifiers = { 'Control' }, + key = 'x', -- x + on_press = function() + --TODO + end, + }, + akey { + modifiers = { 'Control' }, + key = 'Left', -- left + on_press = function() + -- Find all spaces + local spaces = {} + local t, i = self._private.text, 0 + + while t:find('%s') do + i = t:find('%s') + table.insert(spaces, i) + t = t:sub(1, i - 1) .. '-' .. t:sub(i + 1) + end + + local cp = 1 + for _, v in ipairs(spaces) do + if (v < cursor_pos) then + cp = v + end + end + cursor_pos = cp + if cursor_pos < 1 then + cursor_pos = 1 + elseif cursor_pos > #self._private.text + 1 then + cursor_pos = #self._private.text + 1 + end + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Control', 'Left') + end, + }, + akey { + modifiers = { 'Control' }, + key = 'Right', -- right + on_press = function() + local next_space = self._private.text:sub(cursor_pos):find('%s') + if next_space then + cursor_pos = cursor_pos + next_space + else + cursor_pos = #self._private.text + 1 + end + + if cursor_pos < 1 then + cursor_pos = 1 + elseif cursor_pos > #self._private.text + 1 then + cursor_pos = #self._private.text + 1 + end + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', 'Control', 'Right') + end, + }, + akey { + modifiers = {}, + key = 'BackSpace', --BackSpace + on_press = function() + -- If text is highlighted delete that, else just delete the character to the left + if self._private.highlight and self._private.highlight.start_pos and + self._private.highlight.end_pos then + local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1) + local text_end = self._private.text:sub(self._private.highlight.end_pos + 1) + self:set_text(text_start .. text_end) + self._private.highlight = {} + cursor_pos = #text_start + 1 + else + if cursor_pos > 1 then + local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or + 0 + self:set_text(self._private.text:sub(1, cursor_pos - 2 - offset) .. + self._private.text:sub(cursor_pos)) + cursor_pos = cursor_pos - 1 - offset + end + end + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', nil, 'BackSpace') + end, + }, + akey { + modifiers = {}, + key = 'Delete', --delete + on_press = function() + -- If text is highlighted delete that, else just delete the character to the right + if self._private.highlight and self._private.highlight.start_pos and + self._private.highlight.end_pos then + local text_start = self._private.text:sub(1, self._private.highlight.start_pos - 1) + local text_end = self._private.text:sub(self._private.highlight.end_pos + 1) + self:set_text(text_start .. text_end) + self._private.highlight = {} + cursor_pos = #text_start + 1 + else + if cursor_pos <= #self._private.text then + self:set_text(self._private.text:sub(1, cursor_pos - 1) .. + self._private.text:sub(cursor_pos + 1)) + end + end + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', nil, 'Delete') + end, + }, + akey { + modifiers = {}, + key = 'Left', --left + on_press = function() + -- Move cursor ro the left + if cursor_pos > 1 then + cursor_pos = cursor_pos - 1 + end + self._private.highlight = {} + end, + }, + akey { + modifiers = {}, + key = 'Right', --right + on_press = function() + -- Move cursor to the right + if cursor_pos <= #self._private.text then + cursor_pos = cursor_pos + 1 + end + self._private.highlight = {} + end, + }, + --self.keybindings + }, + keypressed_callback = function(_, modifiers, key) + if modifiers[1] == 'Shift' then + if key:wlen() == 1 then + self:set_text(self._private.text:sub(1, cursor_pos - 1) .. + string.upper(key) .. self._private.text:sub(cursor_pos)) + cursor_pos = cursor_pos + #key + end + elseif modifiers[1] == 'Mod2' or '' then + if key:wlen() == 1 then + self:set_text(self._private.text:sub(1, cursor_pos - 1) .. + key .. self._private.text:sub(cursor_pos)) + cursor_pos = cursor_pos + #key + end + end + + if cursor_pos < 1 then + cursor_pos = 1 + elseif cursor_pos > #self._private.text + 1 then + cursor_pos = #self._private.text + 1 + end + self.p.widget:get_children_by_id('text_image')[1].image = self:draw_text_surface() + self:emit_signal('inputbox::key_pressed', modifiers, key) + end, + } +end + +--[[ + take the text and cursor position and figure out which character is next + if mx is greater than lx then the right character is the next character + if mx is less than lx then the left character is the next character + + calculate the delta between mx and lx, if the delta is greater than the next + character increase or decrease the cursor position by 1 (depends if the delta is positive or negative) + and set the lx = mx + + return 1 if advanced to the right, -1 if advanced to the left, 0 if not advanced; and the new lx +]] +function inputbox:advanced_by_character(mx, lx) + local delta = mx - lx + local character + if delta < 0 then + character = self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1) + else + character = self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1) + end + + --local character = (self._private.text:sub(self._private.cursor_pos + 1, self._private.cursor_pos + 1) and (delta < 0)) or self._private.text:sub(self._private.cursor_pos - 1, self._private.cursor_pos - 1) + if character then + local cr = cairo.Context(cairo.ImageSurface(cairo.Format.ARGB32, 1, 1)) + cr:select_font_face(self.font, cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL) + cr:set_font_size(self.font_size) + local extents = cr:text_extents(character) + if math.abs(delta) >= extents.x_advance then + self._private.cursor_pos = self._private.cursor_pos + (((delta > 0) and 1) or -1) + lx = mx + return (((delta > 0) and 1) or -1), lx + end + end + return 0, lx +end + +--- Creates a new inputbox widget +-- @tparam table args Arguments for the inputbox widget +-- @tparam string args.text The text to display in the inputbox +-- @tparam[opt=beautiful.fg_normal] string args.fg Text foreground color +-- @tparam[opt=beautiful.border_focus] string args.border_focus_color Border color when focused +-- @tparam[opt=""] string args.placeholder_text placeholder text to be shown when not focused and +-- @tparam[opt=beautiful.inputbox_placeholder_fg] string args.placeholder_fg placeholder text foreground color +-- @tparam[opt=beautiful.inputbox_cursor_bg] string args.cursor_bg Cursor background color +-- @tparam[opt=beautiful.inputbox_cursor_fg] string args.cursor_fg Cursor foreground color +-- @tparam[opt=beautiful.inputbox_highlight_bg] string args.highlight_bg Highlight background color +-- @tparam[opt=beautiful.inputbox_highlight_fg] string args.highlight_fg Highlight foreground color +-- @treturn awful.widget.inputbox The inputbox widget. +-- @constructorfct awful.widget.inputbox +function inputbox.new(args) + args = args or {} + + -- directly pass a possible default text(this is not meant to be a hint) + local w = imagebox() + + --gtable.crush(w, args) + gtable.crush(w, inputbox, true) + w._private = {} + + w._private.text = args.text or '' + w.font_size = 24 + w.font = User_config.font.regular + w._private.cursor_pos = args.cursor_pos + w._private.highlight = args.highlight + + w.p = apopup { + widget = { + { + image = w:draw_text_surface(), + resize = false, + valign = 'bottom', + halign = 'center', + widget = wibox.widget.imagebox, + id = 'text_image', + }, + widget = wibox.container.margin, + margins = 20, + }, + bg = '#212121', + visible = true, + screen = 1, + placement = aplacement.centered, + } + + w.p.widget:get_children_by_id('text_image')[1]:buttons(gtable.join { + abutton({}, 1, function() + -- Get the mouse coordinates realative to the widget + local x, y = mouse.coords().x - p.x - 20, mouse.coords().y - p.y - 20 -- 20 is the margin on either side + p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false) + w.highlight = { start_pos = w.cursor_pos, end_pos = w.cursor_pos } + p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, false) + if not mousegrabber.isrunning() then + local last_x, advanced, cursor_pos, mx = x, nil, w.cursor_pos, nil + mousegrabber.run(function(m) + mx = m.x - p.x - 20 + if (math.abs(mx - x) > 5) then + -- Returns 1 if the mouse has advanced to the right, -1 if it has advanced to the left + advanced, last_x = w:advanced_by_character(mx, last_x) + if advanced == 1 then + print(cursor_pos, w.highlight.start_pos, w.highlight.end_pos) + if cursor_pos <= w.highlight.start_pos then + if w.highlight.end_pos < #w._private.text then + w.highlight.end_pos = w.highlight.end_pos + 1 + end + else + w.highlight.start_pos = w.highlight.start_pos + 1 + end + p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true) + print(w.highlight.start_pos, w.highlight.end_pos) + elseif advanced == -1 then + if cursor_pos >= w.highlight.end_pos then + if w.highlight.start_pos > 1 then + w.highlight.start_pos = w.highlight.start_pos - 1 + end + else + w.highlight.end_pos = w.highlight.end_pos - 1 + end + p.widget:get_children_by_id('text_image')[1].image = w:draw_text_surface(x, true) + print(w.highlight.start_pos, w.highlight.end_pos) + end + end + + return m.buttons[1] + end, 'xterm') + end + w:run() + end), + }) + + --w.font = args.font or beautiful.font + + --w.keybindings = args.keybindings or {} + --w.hint_text = args.hint_text + + --w.markup = args.text or text_with_cursor('', 1, w) + return w +end + +function inputbox.mt:__call(...) + return inputbox.new(...) +end + +return setmetatable(inputbox, inputbox.mt) diff --git a/awesome/src/modules/inputbox/new.lua b/awesome/src/modules/inputbox/new.lua new file mode 100644 index 0000000..2781d1a --- /dev/null +++ b/awesome/src/modules/inputbox/new.lua @@ -0,0 +1,485 @@ +local Pango = require('lgi').Pango +local PangoCairo = require('lgi').PangoCairo +local abutton = require('awful.button') +local akey = require('awful.key') +local akeygrabber = require('awful.keygrabber') +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +local base = require('wibox.widget.base') +local beautiful = require('beautiful') +local cairo = require('lgi').cairo +local gobject = require('gears.object') +local gstring = require('gears.string') +local gsurface = require('gears.surface') +local gtable = require('gears.table') +local gtimer = require('gears.timer') +local imagebox = require('wibox.widget.imagebox') +local setmetatable = setmetatable +local textbox = require('wibox.widget.textbox') +local wibox = require('wibox') +local dpi = beautiful.xresources.apply_dpi + +local capi = { + selection = selection, + mousegrabber = mousegrabber, + mouse = mouse, +} + +local inputbox = {} + +local function get_text_extent(text, font, font_size, args) + local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0) + local cr = cairo.Context(surface) + cr:select_font_face(font, args) + cr:set_font_size(font_size) + return cr:text_extents(text) +end + +function inputbox.draw_text(self) + local text = self:get_text() + local highlight = self:get_highlight() + local fg_color = { 1, 1, 1 } + local cursor_color = { 1, 1, 1, 1 } + + if text == '' then + fg_color = { 0.2, 0.2, 0.2 } + -- Silently change the text, it will be changed back after it is drawn + self._private.layout:set_text(self._private.text_hint) + end + + local _, pango_extent = self._private.layout:get_extents() + + local surface = cairo.ImageSurface(cairo.Format.ARGB32, (pango_extent.width / Pango.SCALE) + pango_extent.x, (pango_extent.height / Pango.SCALE) + pango_extent.y) + local cr = cairo.Context(surface) + + -- Draw highlight + if (highlight.start_pos ~= 0) or (highlight.end_pos ~= 0) then + cr:set_source_rgb(0, 0, 1) + local txt = text:sub(self:get_highlight().start_pos + 1, self:get_highlight().end_pos) + cr:rectangle( + cr:text_extents(text:sub(0, self:get_highlight().start_pos)).x_advance, + pango_extent.y / Pango.SCALE, + cr:text_extents(txt).width, + pango_extent.height / Pango.SCALE + ) + cr:fill() + end + + -- Draw text + PangoCairo.update_layout(cr, self._private.layout) + cr:set_source_rgba(1, 1, 1, 1) + cr:move_to(0, 0) + PangoCairo.show_layout(cr, self._private.layout) + + -- Draw cursor + cr:set_source_rgba(table.unpack(cursor_color)) + local cursor = self:get_cursor_pos() + cr:rectangle( + cursor.x / Pango.SCALE, + cursor.y / Pango.SCALE, + 2, + cursor.height / Pango.SCALE) + cr:fill() + + self.widget:set_image(surface) + return surface +end + +function inputbox:start_keygrabber() + self.akeygrabber = akeygrabber { + autostart = true, + stop_key = { 'Escape', 'Return' }, + start_callback = function() + end, + stop_callback = function() + end, + keybindings = { + akey { + modifiers = {}, + key = 'BackSpace', + on_press = function() + local hl = self:get_highlight() + local text = self:get_text() + local cursor_pos = self:get_cursor_index() + if hl.end_pos ~= hl.start_pos then + self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text)) + self:set_cursor_pos(hl.start_pos) + self:set_highlight { start_pos = 0, end_pos = 0 } + else + self:set_text(text:sub(1, cursor_pos - 1) .. text:sub(cursor_pos + 1)) + self:set_cursor_pos(cursor_pos - 1) + end + end, + }, + akey { + modifiers = {}, + key = 'Delete', + on_press = function() + local hl = self:get_highlight() + local text = self:get_text() + local cursor_pos = self:get_cursor_index() + if hl.end_pos ~= hl.start_pos then + self:set_text(text:sub(0, hl.start_pos) .. text:sub(hl.end_pos + 1, #text)) + self:set_cursor_pos(hl.start_pos) + self:set_highlight { start_pos = 0, end_pos = 0 } + else + self:set_text(text:sub(1, cursor_pos) .. text:sub(cursor_pos + 2, #text)) + end + end, + }, + akey { + modifiers = {}, + key = 'Left', + on_press = function() + self:set_cursor_pos(self:get_cursor_index() - 1) + self:set_highlight { start_pos = 0, end_pos = 0 } + end, + }, + akey { + modifiers = {}, + key = 'Right', + on_press = function() + self:set_cursor_pos(self:get_cursor_index() + 1) + self:set_highlight { start_pos = 0, end_pos = 0 } + end, + }, + akey { + modifiers = {}, + key = 'Home', + on_press = function() + self:set_cursor_pos(0) + self:set_highlight { start_pos = 0, end_pos = 0 } + end, + }, + akey { + modifiers = {}, + key = 'End', + on_press = function() + self:set_cursor_pos(#self:get_text()) + self:set_highlight { start_pos = 0, end_pos = 0 } + end, + }, + akey { + modifiers = { 'Shift' }, + key = 'Left', + on_press = function() + local cursor_pos = self:get_cursor_pos() + local hl = self:get_highlight() + if cursor_pos == hl.start_pos then + self:set_cursor_pos(cursor_pos - 1) + self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos } + elseif cursor_pos == hl.end_pos then + self:set_cursor_pos(cursor_pos - 1) + self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() } + else + if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then + self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos } + hl = self:get_highlight() + self:set_cursor_pos(cursor_pos - 1) + self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos } + end + end + end, + }, + akey { + modifiers = { 'Shift' }, + key = 'Right', + on_press = function() + local cursor_pos = self:get_cursor_pos() + local hl = self:get_highlight() + if cursor_pos == hl.end_pos then + self:set_cursor_pos(cursor_pos + 1) + self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() } + elseif cursor_pos == hl.start_pos then + self:set_cursor_pos(cursor_pos + 1) + self:set_highlight { start_pos = self:get_cursor_pos(), end_pos = hl.end_pos } + else + if (hl.start_pos ~= cursor_pos) and (hl.end_pos ~= cursor_pos) then + self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos } + hl = self:get_highlight() + self:set_cursor_pos(cursor_pos + 1) + self:set_highlight { start_pos = hl.start_pos, end_pos = self:get_cursor_pos() } + end + end + end, + }, + akey { + modifiers = { 'Control' }, + key = 'a', + on_press = function() + self:set_highlight { start_pos = 0, end_pos = #self:get_text() } + self:set_cursor_pos(#self:get_text() - 1) + end, + }, + akey { + modifiers = { 'Control' }, + key = 'c', + on_press = function() + local hl = self:get_highlight() + if hl.start_pos ~= hl.end_pos then + local text = self:get_text():sub(hl.start_pos, hl.end_pos) + --TODO:self:copy_to_clipboard(text) + end + end, + }, + akey { + modifiers = { 'Control' }, + key = 'v', + on_press = function() + local hl = self:get_highlight() + local selection = capi.selection() + if hl.start_pos ~= hl.end_pos then + self:set_text(self:get_text():sub(1, hl.start_pos) .. selection .. self:get_text():sub(hl.end_pos + 1, #self:get_text())) + self:set_cursor_pos(hl.start_pos + #selection) + self:set_highlight { start_pos = 0, end_pos = 0 } + else + self:set_text(self:get_text():sub(1, self:get_cursor_pos()) .. selection .. self:get_text():sub(self:get_cursor_pos() + 1, #self:get_text())) + self:set_cursor_pos(self:get_cursor_pos() + #selection) + end + end, + }, + akey { + modifiers = { 'Control' }, + key = 'x', + on_press = function() + --TODO + end, + }, + akey { + modifiers = { 'Control' }, + key = 'Right', + on_press = function() + + end, + }, + akey { + modifiers = { 'Control' }, + key = 'Left', + on_press = function() + + end, + }, + }, + keypressed_callback = function(_, mod, key) + local text = self:get_text() + local cursor_pos = self:get_cursor_index() + if (mod[1] == 'Mod2' or '') and (key:wlen() == 1) then + self:set_text(text:sub(1, cursor_pos) .. key .. text:sub(cursor_pos + 1, #text)) + self:set_cursor_pos(cursor_pos + #key) + elseif (mod[1] == 'Shift') and (key:wlen() == 1) then + self:set_text(text:sub(1, cursor_pos) .. key:upper() .. text:sub(cursor_pos + 1, #text)) + self:set_cursor_pos(cursor_pos + #key) + end + end, + } +end + +--[[ function inputbox:advanced_by_character(mx, last_x) + local delta = mx - last_x + local character + local text = self:get_text() + local cursor_pos = self:get_cursor_pos() + if delta < 0 then + character = text:sub(cursor_pos + 1, cursor_pos + 1) + else + character = text:sub(cursor_pos - 1, cursor_pos - 1) + end + + if character then + local extents = get_text_extent(character, self.font, self.font_size, { cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL }) + if math.abs(delta) >= extents.x_advance then + self:set_cursor_pos(cursor_pos + (((delta > 0) and 1) or -1)) + last_x = mx + return (((delta > 0) and 1) or -1), last_x + end + end + return 0, last_x +end ]] + +function inputbox:start_mousegrabber(x, y) + --[[ if not mousegrabber.isrunning() then + local last_x, advanced, cursor_pos, mx = x, nil, self:get_cursor_pos(), nil + local hl = self:get_highlight() + self:set_highlight { start_pos = cursor_pos, end_pos = cursor_pos } + local text = self:get_text() + mousegrabber.run(function(m) + mx = m.x + if (math.abs(mx - x) > 5) then + advanced, last_x = self:advanced_by_character(mx, last_x) + if advanced == 1 then + if cursor_pos <= hl.start_pos then + if hl.end_pos < #text then + self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 } + end + else + self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos } + end + elseif advanced == -1 then + if cursor_pos >= hl.end_pos then + if hl.start_pos > 1 then + self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos } + end + else + self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 } + end + end + end + hl = self:get_highlight() + return m.buttons[1] + end, 'xterm') + end ]] + if not mousegrabber.isrunning() then + local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE) + + if not index then return end + + self:set_cursor_pos(index) + -- Remove highlight, but also prepare its position (same pos = no highlight) + self:set_highlight { start_pos = index, end_pos = index } + + local text = self:get_text() + local cursor_pos = self:get_cursor_pos() + local hl = self:get_highlight() + + mousegrabber.run(function(m) + index, _ = self._private.layout:xy_to_index(m.x * Pango.SCALE, m.y * Pango.SCALE) + + if not index then return end + + if math.abs(index - cursor_pos) == 1 then + if cursor_pos <= hl.start_pos then + if hl.end_pos < #text then + self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos + 1 } + end + else + self:set_highlight { start_pos = hl.start_pos + 1, end_pos = hl.end_pos } + end + elseif math.abs(index - cursor_pos) == -1 then + if cursor_pos >= hl.end_pos then + if hl.start_pos > 1 then + self:set_highlight { start_pos = hl.start_pos - 1, end_pos = hl.end_pos } + end + else + self:set_highlight { start_pos = hl.start_pos, end_pos = hl.end_pos - 1 } + end + end + + if index ~= cursor_pos then + self:set_cursor_pos(index) + end + + return m.buttons[1] + end, 'xterm') + end +end + +function inputbox:set_cursor_pos_from_mouse(x, y) + -- When setting the cursor position, trailing is not needed as its handled by the setter + local index, _ = self._private.layout:xy_to_index(x * Pango.SCALE, y * Pango.SCALE) + if not index then return end + + self:set_highlight { start_pos = 0, end_pos = 0 } + self:set_cursor_pos(index) +end + +function inputbox:get_text() + return self._private.layout:get_text() +end + +function inputbox:set_text(text) + if self:get_text() == text then return end + + local attributes, parsed = Pango.parse_markup(text, -1, 0) + + if not attributes then return parsed.message or tostring(parsed) end + + self._private.layout:set_text(parsed, string.len(parsed)) + self._private.layout:set_attributes(attributes) + + self.draw_text(self) +end + +function inputbox:get_cursor_pos() + return self._private.layout:get_cursor_pos(self._private.cursor_pos.index) +end + +function inputbox:get_cursor_index() + return self._private.cursor_pos.index +end + +function inputbox:set_cursor_pos(cursor_pos) + -- moving only moved one character set, to move it multiple times we need to loop as long as the difference to the new cursor isn't 0 + if not cursor_pos or (cursor_pos < 0) or (cursor_pos >= #self:get_text()) then return end + while (cursor_pos - self._private.cursor_pos.index) ~= 0 do + self._private.cursor_pos.index, self._private.cursor_pos.trailing = self._private.layout:move_cursor_visually( + true, self._private.cursor_pos.index, + self._private.cursor_pos.trailing, + cursor_pos - self._private.cursor_pos.index + ) + end + + self.draw_text(self) +end + +function inputbox:get_highlight() + return self._private.highlight +end + +function inputbox:set_highlight(highlight) + self._private.highlight = highlight + self.draw_text(self) +end + +function inputbox:focus() + +end + +function inputbox:unfocus() + +end + +function inputbox.new(args) + local ret = gobject { enable_properties = true } + args.text = args.text .. '\n' + gtable.crush(ret, inputbox) + + ret._private = {} + ret._private.context = PangoCairo.font_map_get_default():create_context() + ret._private.layout = Pango.Layout.new(ret._private.context) + + ret.font_size = 24 + ret.font = 'JetBrainsMono Nerd Font, ' .. 24 + ret._private.layout:set_font_description(Pango.FontDescription.from_string('JetBrainsMono Nerd Font 16')) + + ret._private.text_hint = args.text_hint or '' + ret._private.cursor_pos = { + index = args.cursor_pos or 0, + trailing = 0, + } + ret._private.highlight = args.highlight or { + start_pos = 0, + end_pos = 0, + } + + ret.widget = imagebox(nil, false) + + ret.widget:connect_signal('button::press', function(_, x, y, button) + if button == 1 then + ret:set_cursor_pos_from_mouse(x, y) + --ret:start_mousegrabber(x, y) + ret:start_keygrabber() + end + end) + + ret:set_text(args.text or '') + --ret:set_cursor_pos(ret._private.cursor_pos) + ret:set_highlight(ret._private.highlight) + + return ret +end + +return setmetatable(inputbox, { + __call = function(_, ...) + return inputbox.new(...) + end, +}) diff --git a/awesome/src/modules/network_controller/access_point.lua b/awesome/src/modules/network_controller/access_point.lua index 311c416..8028bba 100644 --- a/awesome/src/modules/network_controller/access_point.lua +++ b/awesome/src/modules/network_controller/access_point.lua @@ -3,44 +3,45 @@ ------------------------------------ -- Awesome Libs -local abutton = require("awful.button") -local awidget = require("awful.widget") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears").table -local gfilesystem = require("gears").filesystem -local gcolor = require("gears").color -local lgi = require("lgi") -local wibox = require("wibox") -local base = require("wibox.widget.base") +local abutton = require('awful.button') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears').table +local gfilesystem = require('gears').filesystem +local gcolor = require('gears').color +local lgi = require('lgi') +local wibox = require('wibox') +local base = require('wibox.widget.base') local NM = lgi.NM -- Third party libs -local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy") +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 ap_form = require('src.modules.network_controller.ap_form') +local cm = require('src.modules.context_menu.init') +local hover = require('src.tools.hover') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/' local access_point = { mt = {} } local function flags_to_security(flags, wpa_flags, rsn_flags) - local str = "" + local str = '' if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then - str = str .. " WEP" + str = str .. ' WEP' end if wpa_flags ~= 0 then - str = str .. " WPA1" + str = str .. ' WPA1' end if not rsn_flags ~= 0 then - str = str .. " WPA2" + str = str .. ' WPA2' end if wpa_flags == 512 or rsn_flags == 512 then - str = str .. " 802.1X" + str = str .. ' 802.1X' end - return (str:gsub("^%s", "")) + return (str:gsub('^%s', '')) end function access_point:get_access_point_connections(ssid) @@ -50,9 +51,9 @@ function access_point:get_access_point_connections(ssid) for _, connection_path in ipairs(connections) do local NetworkManagerSettingsConnection = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.Settings.Connection", - path = connection_path + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Settings.Connection', + path = connection_path, } if NetworkManagerSettingsConnection.Filename:find(ssid) then @@ -66,39 +67,39 @@ end function access_point:create_profile(ap, password, auto_connect) local s_wsec = {} local security = flags_to_security(ap.Flags, ap.WpaFlags, ap.RsnFlags) - if security ~= "" then - if security:match("WPA") then - s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "wpa-psk") - s_wsec["auth-alg"] = lgi.GLib.Variant("s", "open") - s_wsec["psk"] = lgi.GLib.Variant("s", password) + if security ~= '' then + if security:match('WPA') then + s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk') + s_wsec['auth-alg'] = lgi.GLib.Variant('s', 'open') + s_wsec['psk'] = lgi.GLib.Variant('s', password) else - s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "None") - s_wsec["wep-key-type"] = lgi.GLib.Variant("s", NM.WepKeyType.PASSPHRASE) - s_wsec["wep-key0"] = lgi.GLib.Variant("s", password) + s_wsec['key-mgmt'] = lgi.GLib.Variant('s', 'None') + s_wsec['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE) + s_wsec['wep-key0'] = lgi.GLib.Variant('s', password) end end return { - ["connection"] = { + ['connection'] = { -- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface), - ["uuid"] = lgi.GLib.Variant("s", string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c) + ['uuid'] = lgi.GLib.Variant('s', string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c) local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb) return string.format('%x', v) end)), - ["id"] = lgi.GLib.Variant("s", NM.utils_ssid_to_utf8(ap.Ssid)), - ["type"] = lgi.GLib.Variant("s", "802-11-wireless"), - ["autoconnect"] = lgi.GLib.Variant("b", auto_connect), + ['id'] = lgi.GLib.Variant('s', NM.utils_ssid_to_utf8(ap.Ssid)), + ['type'] = lgi.GLib.Variant('s', '802-11-wireless'), + ['autoconnect'] = lgi.GLib.Variant('b', auto_connect), }, - ["ipv4"] = { - ["method"] = lgi.GLib.Variant("s", "auto") + ['ipv4'] = { + ['method'] = lgi.GLib.Variant('s', 'auto'), }, - ["ipv6"] = { - ["method"] = lgi.GLib.Variant("s", "auto"), + ['ipv6'] = { + ['method'] = lgi.GLib.Variant('s', 'auto'), }, - ["802-11-wireless"] = { - ["mode"] = lgi.GLib.Variant("s", "infrastructure"), + ['802-11-wireless'] = { + ['mode'] = lgi.GLib.Variant('s', 'infrastructure'), }, - ["802-11-wireless-security"] = s_wsec + ['802-11-wireless-security'] = s_wsec, } end @@ -113,26 +114,25 @@ function access_point:connect(ap, password, auto_connect) if #connections == 0 then self.NetworkManager:AddAndActivateConnectionAsync(function(proxy, context, success, fail) if fail ~= nil then - print("Error: " .. tostring(fail), tostring(fail.code)) - self:emit_signal("NetworkManager::failed", tostring(fail), tostring(fail.code)) + self:emit_signal('NetworkManager::failed', tostring(fail), tostring(fail.code)) return end - self:emit_signal("NetworkManager::connected", success) - end, { call_id = "my-id" }, profile, self.NetworkManagerDevice.object_path, + self:emit_signal('NetworkManager::connected', success) + end, { call_id = 'my-id' }, profile, self.NetworkManagerDevice.object_path, self.NetworkManagerAccessPoint.object_path) --88ALYLNxo9Kk*RwRxMfN else connections[1]:Update(profile) self.NetworkManager:ActivateConnectionAsync(function(proxy, context, success, failure) if failure then - self:emit_signal("NM::AccessPointFailed", tostring(failure)) + self:emit_signal('NM::AccessPointFailed', tostring(failure)) return end - self:emit_signal("NM::AccessPointConnected", NM.utils_ssid_to_utf8(ap.Ssid)) + self:emit_signal('NM::AccessPointConnected', NM.utils_ssid_to_utf8(ap.Ssid)) end, - { call_id = "my-id" }, connections[1].object_path, self.NetworkManagerDevice.object_path, + { call_id = 'my-id' }, connections[1].object_path, self.NetworkManagerDevice.object_path, self.NetworkManagerAccessPoint.object_path) end end @@ -156,9 +156,9 @@ function access_point.new(args) local ssid_text = awidget.inputbox { text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid) or - args.NetworkManagerAccessPoint.hw_address or "Unknown", - halign = "left", - valign = "center", + args.NetworkManagerAccessPoint.hw_address or 'Unknown', + halign = 'left', + valign = 'center', } local ret = base.make_widget_from_value(wibox.widget { @@ -168,84 +168,86 @@ function access_point.new(args) { { image = gcolor.recolor_image( - icondir .. "wifi-strength-" .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg", + icondir .. 'wifi-strength-' .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg', Theme_config.network_manager.access_point.icon_color), - id = "icon", + id = 'icon', resize = true, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', forced_width = dpi(24), forced_height = dpi(24), - widget = wibox.widget.imagebox + widget = wibox.widget.imagebox, }, - id = "icon_container", - strategy = "max", + id = 'icon_container', + strategy = 'max', width = dpi(24), height = dpi(24), - widget = wibox.container.constraint + widget = wibox.container.constraint, }, { { ssid_text, widget = wibox.container.constraint, - strategy = "exact", + strategy = 'exact', width = dpi(300), - id = "alias" + id = 'alias', }, width = dpi(260), height = dpi(40), - strategy = "max", - widget = wibox.container.constraint + strategy = 'max', + widget = wibox.container.constraint, }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, { -- Spacing forced_width = dpi(10), - widget = wibox.container.background + widget = wibox.container.background, }, { { { { - id = "con", + id = 'con', resize = false, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', forced_width = dpi(24), forced_height = dpi(24), - widget = wibox.widget.imagebox + widget = wibox.widget.imagebox, }, - id = "place", - strategy = "max", + id = 'place', + strategy = 'max', width = dpi(24), height = dpi(24), - widget = wibox.container.constraint + widget = wibox.container.constraint, }, - id = "margin", + id = 'margin', margins = dpi(2), - widget = wibox.container.margin + widget = wibox.container.margin, }, - id = "margin0", + id = 'margin0', margin = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, - id = "device_layout", - layout = wibox.layout.align.horizontal + id = 'device_layout', + layout = wibox.layout.align.horizontal, }, - id = "device_margin", + id = 'device_margin', margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.network_manager.access_point.bg, fg = Theme_config.network_manager.access_point.fg, border_color = Theme_config.network_manager.access_point.border_color, border_width = Theme_config.network_manager.access_point.border_width, - id = "background", + id = 'background', shape = Theme_config.network_manager.access_point.device_shape, - widget = wibox.container.background + widget = wibox.container.background, }) + assert(type(ret) == 'table', 'access_point:ret is not a table') + gtable.crush(ret, access_point, true) ret.NetworkManagerAccessPoint = args.NetworkManagerAccessPoint @@ -256,49 +258,49 @@ function access_point.new(args) ret.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.DBus.Properties", + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.DBus.Properties', path = ret.NetworkManagerAccessPoint.object_path, } -- Update the access point strength ret.NetworkManagerAccessPointProperties:connect_signal(function(_, properties, data) if data.Strength then - awesome.emit_signal("NM::AccessPointStrength", data.Strength) + awesome.emit_signal('NM::AccessPointStrength', data.Strength) if ret.is_ap_active(ret.NetworkManagerAccessPoint.object_path) then - ret:get_children_by_id("icon")[1].image = gcolor.recolor_image( - icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg", + ret:get_children_by_id('icon')[1].image = gcolor.recolor_image( + icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg', Theme_config.network_manager.access_point.icon_color2) else - ret:get_children_by_id("icon")[1].image = gcolor.recolor_image( - icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg", + ret:get_children_by_id('icon')[1].image = gcolor.recolor_image( + icondir .. 'wifi-strength-' .. math.floor(data.Strength / 25) + 1 .. '.svg', Theme_config.network_manager.access_point.icon_color) end end - end, "PropertiesChanged") + end, 'PropertiesChanged') if ret:is_ap_active(ret.NetworkManagerAccessPoint) then ret.bg = Theme_config.network_manager.access_point.fg ret.fg = Theme_config.network_manager.access_point.bg - ret:get_children_by_id("icon")[1].image = gcolor.recolor_image( - icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg", + ret:get_children_by_id('icon')[1].image = gcolor.recolor_image( + icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg', Theme_config.network_manager.access_point.icon_color2) - ret:get_children_by_id("con")[1].image = gcolor.recolor_image( - icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color2) + ret:get_children_by_id('con')[1].image = gcolor.recolor_image( + icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color2) else ret.bg = Theme_config.network_manager.access_point.bg ret.fg = Theme_config.network_manager.access_point.fg - ret:get_children_by_id("icon")[1].image = gcolor.recolor_image( - icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg", + ret:get_children_by_id('icon')[1].image = gcolor.recolor_image( + icondir .. 'wifi-strength-' .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. '.svg', Theme_config.network_manager.access_point.icon_color) - ret:get_children_by_id("con")[1].image = gcolor.recolor_image( - icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color) + ret:get_children_by_id('con')[1].image = gcolor.recolor_image( + icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color) end ret.ap_form = ap_form { screen = args.screen, NetworkManagerAccessPoint = args.NetworkManagerAccessPoint, - ap = ret + ap = ret, } ret.cm = cm { @@ -309,40 +311,40 @@ function access_point.new(args) { widget = wibox.widget.imagebox, resize = true, - valign = "center", - halign = "center", - id = "icon_role", + valign = 'center', + halign = 'center', + id = 'icon_role', }, widget = wibox.container.constraint, - stragety = "exact", + stragety = 'exact', width = dpi(24), height = dpi(24), - id = "const" + id = 'const', }, { widget = wibox.widget.textbox, - valign = "center", - halign = "left", - id = "text_role" + valign = 'center', + halign = 'left', + id = 'text_role', }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.background, }, spacing = dpi(10), entries = { { -- Connect/Disconnect a device - name = "ret.device.Connected" and "Disconnect" or "Connect", - icon = gcolor.recolor_image("ret.device.Connected" and icondir .. "link-off.svg" or - icondir .. "link.svg", + name = 'ret.device.Connected' and 'Disconnect' or 'Connect', + icon = gcolor.recolor_image('ret.device.Connected' and icondir .. 'link-off.svg' or + icondir .. 'link.svg', Theme_config.network_manager.access_point.icon_color), callback = function() ret:toggle_connection(ret.NetworkManagerAccessPoint) end, - id = "connected" - } - } + id = 'connected', + }, + }, } ret:buttons(gtable.join( @@ -362,7 +364,7 @@ function access_point.new(args) ) )) - Hover_signal(ret) + hover.bg_hover { widget = ret } return ret end diff --git a/awesome/src/modules/network_controller/ap_form.lua b/awesome/src/modules/network_controller/ap_form.lua index 40ece1a..3916c90 100644 --- a/awesome/src/modules/network_controller/ap_form.lua +++ b/awesome/src/modules/network_controller/ap_form.lua @@ -1,21 +1,23 @@ -local abutton = require("awful.button") -local aplacement = require("awful.placement") -local apopup = require("awful.popup") -local awidget = require("awful.widget") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local gcolor = require("gears.color") -local gshape = require("gears.shape") -local gfilesystem = require("gears.filesystem") -local NM = require("lgi").NM -local wibox = require("wibox") +local abutton = require('awful.button') +local aplacement = require('awful.placement') +local apopup = require('awful.popup') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local gcolor = require('gears.color') +local gshape = require('gears.shape') +local gfilesystem = require('gears.filesystem') +local NM = require('lgi').NM +local wibox = require('wibox') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/" +local hover = require('src.tools.hover') + +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/' local capi = { awesome = awesome, mouse = mouse, - mousegrabber = mousegrabber + mousegrabber = mousegrabber, } local ap_form = { mt = {} } @@ -28,7 +30,7 @@ function ap_form.new(args) args = args or {} args.screen = args.screen - local password = awidget.inputbox { hint_text = "Password..." } + local password = awidget.inputbox { hint_text = 'Password...' } local ret = apopup { widget = { @@ -40,31 +42,31 @@ function ap_form.new(args) { widget = wibox.widget.textbox, text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid), - font = User_config.font.specify .. ",extra bold 16", - halign = "center", - valign = "center", + font = User_config.font.specify .. ',extra bold 16', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, - margins = dpi(5) + margins = dpi(5), }, { -- Close button { { widget = wibox.widget.imagebox, - image = gcolor.recolor_image(icondir .. "close.svg", Theme_config.network_manager.form.icon_fg), + image = gcolor.recolor_image(icondir .. 'close.svg', Theme_config.network_manager.form.icon_fg), resize = false, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', }, widget = wibox.container.margin, margins = dpi(5), }, widget = wibox.container.background, shape = Theme_config.network_manager.form.close_icon_shape, - id = "close_button", - bg = Theme_config.network_manager.form.close_bg + id = 'close_button', + bg = Theme_config.network_manager.form.close_bg, }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.background, bg = Theme_config.network_manager.form.header_bg, @@ -73,9 +75,9 @@ function ap_form.new(args) { -- Form { -- Password widget = wibox.widget.textbox, - text = "Password", - halign = "center", - valign = "center" + text = 'Password', + halign = 'center', + valign = 'center', }, { widget = wibox.container.margin, @@ -89,25 +91,25 @@ function ap_form.new(args) password, widget = wibox.container.margin, margins = 5, - id = "marg" + id = 'marg', }, widget = wibox.container.constraint, - strategy = "exact", + strategy = 'exact', width = 400, height = 50, - id = "const" + id = 'const', }, widget = wibox.container.background, - bg = "#212121", - fg = "#F0F0F0", - border_color = "#414141", + bg = '#212121', + fg = '#F0F0F0', + border_color = '#414141', border_width = 2, shape = gshape.rounded_rect, forced_width = 300, forced_height = 50, - id = "password_container" + id = 'password_container', }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, { -- Actions { -- Auto connect @@ -121,26 +123,26 @@ function ap_form.new(args) check_color = Theme_config.network_manager.form.checkbox_bg, border_color = Theme_config.network_manager.form.checkbox_bg, border_width = 2, - id = "checkbox", - widget = wibox.widget.checkbox + id = 'checkbox', + widget = wibox.widget.checkbox, }, widget = wibox.container.constraint, - strategy = "exact", + strategy = 'exact', width = dpi(30), - height = dpi(30) + height = dpi(30), }, widget = wibox.container.place, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, { widget = wibox.widget.textbox, - text = "Auto connect", - halign = "center", - valign = "center" + text = 'Auto connect', + halign = 'center', + valign = 'center', }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, nil, { -- Connect @@ -148,9 +150,9 @@ function ap_form.new(args) { { widget = wibox.widget.textbox, - text = "Connect", - halign = "center", - valign = "center" + text = 'Connect', + halign = 'center', + valign = 'center', }, widget = wibox.container.margin, margins = dpi(10), @@ -159,18 +161,18 @@ function ap_form.new(args) bg = Theme_config.network_manager.form.button_bg, fg = Theme_config.network_manager.form.button_fg, shape = Theme_config.network_manager.form.button_shape, - id = "connect_button", + id = 'connect_button', }, widget = wibox.container.margin, margins = dpi(10), }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, spacing = dpi(20), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, widget = wibox.container.margin, - margins = dpi(10) + margins = dpi(10), }, placement = aplacement.centered, ontop = true, @@ -182,55 +184,55 @@ function ap_form.new(args) shape = Theme_config.network_manager.form.shape, border_color = Theme_config.network_manager.form.border_color, border_width = Theme_config.network_manager.form.border_width, - type = "dialog", + type = 'dialog', screen = args.screen, } - local password_container = ret.widget:get_children_by_id("password_container")[1] + local password_container = ret.widget:get_children_by_id('password_container')[1] + + gtable.crush(ret, ap_form, true) -- Focus the searchbar when its left clicked password_container:buttons(gtable.join { abutton({}, 1, function() password:focus() - end) + end), }) --#region Hover signals to change the cursor to a text cursor local old_cursor, old_wibox - password_container:connect_signal("mouse::enter", function() + password_container:connect_signal('mouse::enter', function() local wid = capi.mouse.current_wibox if wid then old_cursor, old_wibox = wid.cursor, wid - wid.cursor = "xterm" + wid.cursor = 'xterm' end end) - password_container:connect_signal("mouse::leave", function() + password_container:connect_signal('mouse::leave', function() old_wibox.cursor = old_cursor old_wibox = nil end) --#endregion - gtable.crush(ret, ap_form, true) - - local checkbox = ret.widget:get_children_by_id("checkbox")[1] - checkbox:connect_signal("button::press", function() + local checkbox = ret.widget:get_children_by_id('checkbox')[1] + checkbox:connect_signal('button::press', function() checkbox.checked = not checkbox.checked end) - local close_button = ret.widget:get_children_by_id("close_button")[1] - close_button:connect_signal("button::press", function() + local close_button = ret.widget:get_children_by_id('close_button')[1] + close_button:connect_signal('button::press', function() ret:popup_toggle() end) - Hover_signal(close_button) + hover.bg_hover { widget = close_button } - local connect_button = ret.widget:get_children_by_id("connect_button")[1] - connect_button:connect_signal("button::press", function() + local connect_button = ret.widget:get_children_by_id('connect_button')[1] + connect_button:connect_signal('button::press', function() password:stop() args.ap:connect(args.NetworkManagerAccessPoint, password:get_text(), - ret.widget:get_children_by_id("checkbox")[1].checked) + ret.widget:get_children_by_id('checkbox')[1].checked) ret:popup_toggle() end) - Hover_signal(connect_button) + hover.bg_hover { widget = connect_button } return ret end diff --git a/awesome/src/modules/network_controller/init.lua b/awesome/src/modules/network_controller/init.lua index bb8a6bf..2ff6dd2 100644 --- a/awesome/src/modules/network_controller/init.lua +++ b/awesome/src/modules/network_controller/init.lua @@ -3,28 +3,29 @@ ------------------------------------ -- Awesome Libs -local abutton = require("awful.button") -local base = require("wibox.widget.base") -local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy") -local 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 abutton = require('awful.button') +local base = require('wibox.widget.base') +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 NM = lgi.NM -local naughty = require("naughty") -local wibox = require("wibox") +local naughty = require('naughty') +local wibox = require('wibox') -- Third party libs -local rubato = require("src.lib.rubato") +local rubato = require('src.lib.rubato') +local hover = require('src.tools.hover') -- Local libs -local access_point = require("src.modules.network_controller.access_point") -local dnd_widget = require("awful.widget.toggle_widget") +local access_point = require('src.modules.network_controller.access_point') +local dnd_widget = require('awful.widget.toggle_widget') -local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/network/' local network = { mt = {} } @@ -41,7 +42,7 @@ network.NMState = { network.DeviceType = { ETHERNET = 1, - WIFI = 2 + WIFI = 2, } network.DeviceState = { @@ -57,7 +58,7 @@ network.DeviceState = { SECONDARIES = 90, ACTIVATED = 100, DEACTIVATING = 110, - FAILED = 120 + FAILED = 120, } ---Get the wifi and or ethernet proxy and connect to their PropertiesChanged signal @@ -73,9 +74,9 @@ function network:get_active_device() --Create a new proxy for every device local NetworkManagerDevice = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.Device", - path = path + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Device', + path = path, } --Check if the device is either a wifi or ethernet device, and if its activated @@ -87,92 +88,87 @@ function network:get_active_device() --New wifi proxy to check the bitrate self._private.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.Device.Wireless", - path = path + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Device.Wireless', + path = path, } -- Watch PropertiesChanged and update the bitrate local NetworkManagerDeviceWirelessProperties = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.DBus.Properties", - path = self._private.NetworkManagerDeviceWireless.object_path + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.DBus.Properties', + path = self._private.NetworkManagerDeviceWireless.object_path, } NetworkManagerDeviceWirelessProperties:connect_signal(function(_, properties, data) if data.Bitrate then - self:emit_signal("NM::Bitrate", data.Bitrate) + self:emit_signal('NM::Bitrate', data.Bitrate) end - end, "PropertiesChanged") + end, 'PropertiesChanged') -- Watch the StateChanged signal, update and notify when a new AP is connected self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state) local NetworkManagerAccessPoint = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.AccessPoint", - path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.AccessPoint', + path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint, } if new_state == network.DeviceState.ACTIVATED then local ssid = NM.utils_ssid_to_utf8(NetworkManagerAccessPoint.Ssid) - self:emit_signal("NM::AccessPointConnected", ssid, NetworkManagerAccessPoint.Strength) + self:emit_signal('NM::AccessPointConnected', ssid, NetworkManagerAccessPoint.Strength) end - end, "StateChanged") + end, 'StateChanged') elseif (NetworkManagerDevice.DeviceType == network.DeviceType.ETHERNET) and (NetworkManagerDevice.State == network.DeviceState.ACTIVATED) then - -- Create a new ethernet device and set it as the active device self._private.NetworkManagerDevice = NetworkManagerDevice self._private.NetworkManagerDeviceWired = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.Device.Wired", - path = path + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Device.Wired', + path = path, } - - local NetworkManagerDeviceWiredProperties = dbus_proxy.Proxy:new { - bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.DBus.Properties", - path = self._private.NetworkManagerDeviceWired.object_path - } - - -- Watch the PropertiesChanged signal and update the speed and carrier - NetworkManagerDeviceWiredProperties:connect_signal(function(_, properties, data) - if data.Speed then - print(data.Speed) - self:emit_signal("NM::Speed", data.Speed) - elseif data.Carrier then - print(data.Carrier) - self:emit_signal("NM::Carrier", data.Carrier) - end - end, "PropertiesChanged") - + if self._private.NetworkManagerDevice.State == network.DeviceState.ACTIVATED then + awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed) + end -- Connect to the StateChanged signal and notify when the wired connection is ready - self._private.NetworkManagerDevice:connect_signal(function(proxy, new_state) + self._private.NetworkManagerDevice:connect_signal(function(_, new_state) if new_state == network.DeviceState.ACTIVATED then - self:emit_signal("NM::EthernetActive") - print("Ethernet active") + awesome.emit_signal('NM::EthernetStatus', true, self._private.NetworkManagerDeviceWired.Speed) + elseif new_state == network.DeviceState.DISCONNECTED then + awesome.emit_signal('NM::EthernetStatus', false) end - end, "StateChanged") + end, 'StateChanged') end end end +function network:get_active_ap_ssid() + local d = dbus_proxy.Proxy:new { + bus = dbus_proxy.Bus.SYSTEM, + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Device.Wireless', + path = self._private.NetworkManagerDeviceWireless.ActiveAccessPoint, + } + + return NM.utils_ssid_to_utf8(d.Ssid) +end + ---Scan for access points and create a widget for each one. function network:scan_access_points() if not self._private.NetworkManagerDeviceWireless then return end - local ap_list = self:get_children_by_id("wifi_ap_list")[1] + local ap_list = self:get_children_by_id('wifi_ap_list')[1] ap_list:reset() local ap_table = {} self._private.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure) if failure then naughty.notification { - app_icon = icondir .. "ethernet.svg", - app_name = "Network Manager", - title = "Error: Scan failed!", - message = "Failed to scan for access points.\n" .. failure, - icon = gcolor.recolor_image(icondir .. "ethernet.svg", Theme_config.network.icon_color), + app_icon = icondir .. 'ethernet.svg', + app_name = 'Network Manager', + title = 'Error: Scan failed!', + message = 'Failed to scan for access points.\n' .. failure, + icon = gcolor.recolor_image(icondir .. 'ethernet.svg', Theme_config.network.icon_color), timeout = 5, } return @@ -183,9 +179,9 @@ function network:scan_access_points() -- Create a new proxy for every ap local NetworkManagerAccessPoint = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.AccessPoint", - path = ap + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.AccessPoint', + path = ap, } -- We are only interested in those with a ssid @@ -216,17 +212,17 @@ function network:scan_access_points() NetworkManagerDevice = self._private.NetworkManagerDevice, NetworkManagerSettings = self._private.NetworkManagerSettings, NetworkManager = self._private.NetworkManager, - NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless + NetworkManagerDeviceWireless = self._private.NetworkManagerDeviceWireless, }) end - end, { call_id = "my-id" }, {}) + end, { call_id = 'my-id' }, {}) end ---Toggles networking on or off function network:toggle_wifi() local enable = not self._private.NetworkManager.WirelessEnabled - self._private.NetworkManager:Set("org.freedesktop.NetworkManager", "WirelessEnabled", lgi.GLib.Variant("b", enable)) - self._private.NetworkManager.WirelessEnabled = { signature = "b", value = enable } + self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', enable)) + self._private.NetworkManager.WirelessEnabled = { signature = 'b', value = enable } end function network.new(args) @@ -242,54 +238,54 @@ function network.new(args) { { resize = false, - image = gcolor.recolor_image(icondir .. "menu-down.svg", + image = gcolor.recolor_image(icondir .. 'menu-down.svg', Theme_config.network_manager.wifi_icon_color), widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "icon" + valign = 'center', + halign = 'center', + id = 'icon', }, - id = "center", - halign = "center", - valign = "center", + id = 'center', + halign = 'center', + valign = 'center', widget = wibox.container.place, }, { { - text = "Wifi Networks", + text = 'Wifi Networks', widget = wibox.widget.textbox, - id = "ap_name" + id = 'ap_name', }, margins = dpi(5), - widget = wibox.container.margin + widget = wibox.container.margin, }, - id = "wifi", - layout = wibox.layout.fixed.horizontal + id = 'wifi', + layout = wibox.layout.fixed.horizontal, }, - id = "wifi_bg", + id = 'wifi_bg', bg = Theme_config.network_manager.wifi_bg, fg = Theme_config.network_manager.wifi_fg, shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - widget = wibox.container.background + widget = wibox.container.background, }, - id = "wifi_margin", - widget = wibox.container.margin + id = 'wifi_margin', + widget = wibox.container.margin, }, { - id = "wifi_list", + id = 'wifi_list', { { step = dpi(50), spacing = dpi(10), - layout = require("src.lib.overflow_widget.overflow").vertical, + layout = require('src.lib.overflow_widget.overflow').vertical, scrollbar_width = 0, - id = "wifi_ap_list" + id = 'wifi_ap_list', }, - id = "margin", + id = 'margin', margins = dpi(10), - widget = wibox.container.margin + widget = wibox.container.margin, }, border_color = Theme_config.network_manager.ap_border_color, border_width = Theme_config.network_manager.ap_border_width, @@ -297,35 +293,35 @@ function network.new(args) gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4)) end, widget = wibox.container.background, - forced_height = 0 + forced_height = 0, }, { { -- action buttons { dnd_widget { color = Theme_config.network_manager.power_icon_color, - size = dpi(40) + size = dpi(40), }, - id = "dnd", + id = 'dnd', widget = wibox.container.place, - valign = "center", - halign = "center" + valign = 'center', + halign = 'center', }, nil, { -- refresh { { - image = gcolor.recolor_image(icondir .. "refresh.svg", + image = gcolor.recolor_image(icondir .. 'refresh.svg', Theme_config.network_manager.refresh_icon_color), resize = false, - valign = "center", - halign = "center", + valign = 'center', + halign = 'center', widget = wibox.widget.imagebox, - id = "icon" + id = 'icon', }, widget = wibox.container.margin, margins = dpi(5), - id = "center", + id = 'center', }, border_width = dpi(2), border_color = Theme_config.network_manager.border_color, @@ -334,20 +330,20 @@ function network.new(args) end, bg = Theme_config.network_manager.refresh_bg, widget = wibox.container.background, - id = "refresh" + id = 'refresh', }, - layout = wibox.layout.align.horizontal + layout = wibox.layout.align.horizontal, }, widget = wibox.container.margin, top = dpi(10), - id = "action_buttons" + id = 'action_buttons', }, - id = "layout1", - layout = wibox.layout.fixed.vertical + id = 'layout1', + layout = wibox.layout.fixed.vertical, }, - id = "margin", + id = 'margin', margins = dpi(15), - widget = wibox.container.margin + widget = wibox.container.margin, }, shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) @@ -355,17 +351,19 @@ function network.new(args) border_color = Theme_config.network_manager.border_color, border_width = Theme_config.network_manager.border_width, bg = Theme_config.network_manager.bg, - id = "background", - widget = wibox.container.background + id = 'background', + widget = wibox.container.background, }, width = dpi(400), - strategy = "exact", - widget = wibox.container.constraint + strategy = 'exact', + widget = wibox.container.constraint, }) - local dnd = ret:get_children_by_id("dnd")[1]:get_widget() + assert(type(ret) == 'table', 'NetworkManager is not running') - dnd:connect_signal("dnd::toggle", function(enable) + local dnd = ret:get_children_by_id('dnd')[1]:get_widget() + + dnd:connect_signal('dnd::toggle', function(enable) ret:toggle_wifi() end) @@ -375,23 +373,23 @@ function network.new(args) ret._private.NetworkManager = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager", - path = "/org/freedesktop/NetworkManager", + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager', + path = '/org/freedesktop/NetworkManager', } ret._private.NetworkManagerSettings = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.NetworkManager.Settings", - path = "/org/freedesktop/NetworkManager/Settings", + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.NetworkManager.Settings', + path = '/org/freedesktop/NetworkManager/Settings', } ret._private.NetworkManagerProperties = dbus_proxy.Proxy:new { bus = dbus_proxy.Bus.SYSTEM, - name = "org.freedesktop.NetworkManager", - interface = "org.freedesktop.DBus.Properties", - path = "/org/freedesktop/NetworkManager", + name = 'org.freedesktop.NetworkManager', + interface = 'org.freedesktop.DBus.Properties', + path = '/org/freedesktop/NetworkManager', } ret._private.NetworkManagerProperties:connect_signal(function(_, properties, data) @@ -404,7 +402,7 @@ function network.new(args) dnd:set_disabled() end - ret:emit_signal("NetworkManager::status", ret._private.WirelessEnabled) + ret:emit_signal('NetworkManager::status', ret._private.WirelessEnabled) if data.WirelessEnabled then gtimer { @@ -414,11 +412,11 @@ function network.new(args) single_shot = true, callback = function() ret:scan_access_points() - end + end, } end end - end, "PropertiesChanged") + end, 'PropertiesChanged') ret:get_active_device() @@ -433,9 +431,9 @@ function network.new(args) --#endregion --#region Dropdown logic - local wifi_margin = ret:get_children_by_id("wifi_margin")[1] - local wifi_list = ret:get_children_by_id("wifi_list")[1] - local wifi = ret:get_children_by_id("wifi")[1].center + local wifi_margin = ret:get_children_by_id('wifi_margin')[1] + local wifi_list = ret:get_children_by_id('wifi_list')[1] + local wifi = ret:get_children_by_id('wifi')[1].center local rubato_timer = rubato.timed { duration = 0.2, @@ -443,14 +441,14 @@ function network.new(args) easing = rubato.linear, subscribed = function(v) wifi_list.forced_height = v - end + end, } wifi_margin:buttons(gtable.join( abutton({}, 1, nil, function() if wifi_list.forced_height == 0 then - if not ret:get_children_by_id("wifi_ap_list")[1].children then + if not ret:get_children_by_id('wifi_ap_list')[1].children then return end local size = (5 * 49) + 1 @@ -461,30 +459,29 @@ function network.new(args) wifi_margin.wifi_bg.shape = function(cr, width, height) gshape.partially_rounded_rect(cr, width, height, true, true, false, false, dpi(4)) end - wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-up.svg", + wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-up.svg', Theme_config.network_manager.wifi_icon_color)) else rubato_timer.target = 0 wifi_margin.wifi_bg.shape = function(cr, width, height) gshape.partially_rounded_rect(cr, width, height, true, true, true, true, dpi(4)) end - wifi.icon:set_image(gcolor.recolor_image(icondir .. "menu-down.svg", + wifi.icon:set_image(gcolor.recolor_image(icondir .. 'menu-down.svg', Theme_config.network_manager.wifi_icon_color)) end end ) )) + hover.bg_hover { widget = wifi_margin.wifi_bg } --#endregion - local refresh_button = ret:get_children_by_id("refresh")[1] + local refresh_button = ret:get_children_by_id('refresh')[1] refresh_button:buttons(gtable.join( - abutton({}, 1, nil, - function() - ret:scan_access_points() - end - ) + abutton({}, 1, nil, function() + ret:scan_access_points() + end) )) - Hover_signal(refresh_button) + hover.bg_hover { widget = refresh_button } return ret end diff --git a/awesome/src/modules/notification-center/init.lua b/awesome/src/modules/notification-center/init.lua index 96cae16..cc2aa1d 100644 --- a/awesome/src/modules/notification-center/init.lua +++ b/awesome/src/modules/notification-center/init.lua @@ -3,286 +3,303 @@ ------------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local dnd_widget = require("awful.widget.toggle_widget") +local dpi = require('beautiful').xresources.apply_dpi +local gfilesystem = require('gears.filesystem') +local base = require('wibox.widget.base') +local wibox = require('wibox') +local apopup = require('awful.popup') +local aplacement = require('awful.placement') +local gshape = require('gears.shape') +local gcolor = require('gears.color') -local capi = { - awesome = awesome, -} +-- Own Libs +local dnd_widget = require('awful.widget.toggle_widget') +local notification_list = require('src.modules.notification-center.widgets.notification_list')() +local weather_widget = require('src.modules.notification-center.widgets.weather')() +local profile_widget = require('src.modules.notification-center.widgets.profile')() +local status_bars = require('src.modules.notification-center.widgets.status_bars')() +local music_widget = require('src.modules.notification-center.widgets.song_info')() +local hover = require('src.tools.hover') -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/' -return function(s) +local capi = { + client = client, +} - local dnd = dnd_widget({ - text = "Do not disturb", - color = Theme_config.notification_center.dnd_color, - fg = Theme_config.notification_center.dnd_fg, - size = dpi(40) - }) +local instance = nil - dnd:get_widget():connect_signal("dnd::toggle", function(enabled) - User_config.dnd = enabled - end) +local info_center = {} - --#region Activation area +function info_center:toggle() + if self.container.visible then + self.container.visible = false + else + self.container.visible = true + end +end - local activation_area = awful.popup { - bg = '#00000000', - widget = wibox.container.background, - ontop = true, - screen = s, - type = 'dock', - placement = function(c) - awful.placement.top(c) - end, - } +function info_center.new(args) + args = args or {} - activation_area:setup({ - widget = wibox.container.background, - forced_height = dpi(1), - forced_width = dpi(300), - bg = '#00000000', - layout = wibox.layout.fixed.horizontal - }) - - capi.awesome.connect_signal( - "notification_center_activation::toggle", - function(screen, hide) - if screen == s then - activation_area.visible = hide - end - end - ) - - --#endregion - - --#region Widgets - local nl = require("src.modules.notification-center.notification_list").notification_list - local music_widget = require("src.modules.notification-center.song_info")() - local time_date = require("src.modules.notification-center.time_date")() - local weather_widget = require("src.modules.notification-center.weather")() - local profile_widget = require("src.modules.notification-center.profile")() - local status_bars_widget = require("src.modules.notification-center.status_bars")() - --#endregion - - --#region Notification buttons - local clear_all_widget = wibox.widget { -- Clear all button + local w = base.make_widget_from_value { { { { - text = "Clear", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "clearall" + { + { + { -- Time + halign = 'center', + valign = 'center', + format = "%H:%M", + widget = wibox.widget.textclock, + }, + { -- Date and Day + { -- Date + halign = 'left', + valign = 'bottom', + format = "%d %b %Y", + widget = wibox.widget.textclock, + }, + { -- Day + halign = 'left', + valign = 'top', + format = "%A", + widget = wibox.widget.textclock, + }, + layout = wibox.layout.flex.vertical, + }, + spacing = dpi(20), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + margins = dpi(20), + widget = wibox.container.margin, + }, + { + { + { + bg = Theme_config.notification_center.spacing_line.color, + widget = wibox.container.background, + }, + widget = wibox.container.constraint, + height = dpi(2), + strategy = 'exact', + }, + left = dpi(60), + right = dpi(60), + widget = wibox.container.margin, }, - id = "background4", - fg = Theme_config.notification_center.clear_all_button.fg, - bg = Theme_config.notification_center.clear_all_button.bg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 12) - end, - forced_width = dpi(80), - forced_height = dpi(40), - widget = wibox.container.background - }, - id = "margin3", - margins = dpi(10), - widget = wibox.container.margin - }, - widget = wibox.container.place, - valign = "bottom", - halign = "right", - } - - local no_notification_widget = wibox.widget { - { - { - valign = "center", - halign = "center", - resize = true, - forced_height = dpi(200), - forced_width = dpi(200), - image = icondir .. "megamind.svg", - widget = wibox.widget.imagebox, - id = "icon" - }, - { - id = "txt", - markup = "No Notifications?", - valign = "center", - halign = "center", - widget = wibox.widget.textbox - }, - id = "lay", - layout = wibox.layout.fixed.vertical - }, - valign = "center", - halign = "center", - widget = wibox.container.place - } - --#endregion - - --#region Notification center - local notification_center = awful.popup { - widget = wibox.container.background, - bg = Theme_config.notification_center.bg, - border_color = Theme_config.notification_center.border_color, - border_width = Theme_config.notification_center.border_width, - placement = function(c) - awful.placement.top(c, { margins = dpi(10) }) - end, - ontop = true, - screen = s, - visible = false, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(12)) - end, - } - - local function notification_center_setup() - notification_center:setup({ - widget = notification_center, - -- Custom widgets - { - time_date, - require("src.modules.notification-center.spacingline_widget")(), { { weather_widget, { profile_widget, - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - status_bars_widget, + status_bars, music_widget, - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, -- Notification list { { { - nl, + notification_list, height = dpi(680), - strategy = "max", - widget = wibox.container.constraint - }, - { - no_notification_widget, - strategy = "max", - height = dpi(400), - widget = wibox.container.constraint + strategy = 'max', + widget = wibox.container.constraint, }, { { - dnd, + { + { + { + valign = 'center', + halign = 'center', + resize = true, + image = icondir .. 'megamind.svg', + widget = wibox.widget.imagebox, + id = 'no_notification_icon', + }, + widget = wibox.container.constraint, + height = dpi(200), + width = dpi(200), + strategy = 'exact', + }, + { + markup = "No Notifications?", + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'no_notification_text', + }, + layout = wibox.layout.fixed.vertical, + }, + widget = wibox.container.place, + }, + strategy = 'max', + height = dpi(400), + widget = wibox.container.constraint, + }, + { + { + dnd_widget { + text = 'Do not disturb', + color = Theme_config.notification_center.dnd_color, + fg = Theme_config.notification_center.dnd_fg, + size = dpi(40), + }, + id = 'dnd', widget = wibox.container.place, - valign = "center", - halign = "center" }, nil, - clear_all_widget, - layout = wibox.layout.align.horizontal + { -- Clear all button + { + { + { + { + text = 'Clear', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'clear', + }, + fg = Theme_config.notification_center.clear_all_button.fg, + bg = Theme_config.notification_center.clear_all_button.bg, + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, 12) + end, + id = 'clear_all_bg', + widget = wibox.container.background, + }, + widget = wibox.container.constraint, + width = dpi(80), + height = dpi(40), + strategy = 'exact', + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + widget = wibox.container.place, + valign = 'bottom', --? Needed? + halign = 'right', --? Needed? + }, + layout = wibox.layout.align.horizontal, }, - id = "layout5", - layout = wibox.layout.align.vertical + layout = wibox.layout.align.vertical, }, - id = "margin6", margins = dpi(20), - widget = wibox.container.margin + widget = wibox.container.margin, }, - id = "yes", spacing_widget = { - { - bg = Theme_config.notification_center.spacing_color, - widget = wibox.container.background - }, - top = dpi(40), - bottom = dpi(40), - widget = wibox.container.margin + thickness = dpi(2), + color = Theme_config.notification_center.spacing_color, + span_ratio = 0.9, + widget = wibox.widget.separator, }, - spacing = dpi(1), - forced_height = dpi(800), - forced_width = dpi(1000), - layout = wibox.layout.flex.horizontal - }) - end + spacing = dpi(2), + layout = wibox.layout.flex.horizontal, + }, + widget = wibox.container.constraint, + height = dpi(800), + width = dpi(1000), + strategy = 'exact', + } - --#endregion + hover.bg_hover { widget = w:get_children_by_id('clear_all_bg')[1] } - --#region Signals - -- Toggle notification_center visibility when mouse is over activation_area - activation_area:connect_signal( - "mouse::enter", - function() - notification_center.visible = true - notification_center_setup() - end - ) + assert(type(w) == 'table', 'Widget creation failed') - -- Update the notification center popup and check if there are no notifications - capi.awesome.connect_signal( - "notification_center:update::needed", - function() - if #nl == 0 then - math.randomseed(os.time()) - local prob = math.random(1, 10) + notification_list:connect_signal('new_children', function() + if #notification_list.children == 0 then + math.randomseed(os.time()) + local prob = math.random(1, 10) - if (prob == 5) or (prob == 6) then - no_notification_widget.lay.icon.image = icondir .. "megamind.svg" - no_notification_widget.lay.txt.markup = "No Notifications?" - else - no_notification_widget.lay.icon.image = icondir .. "bell-outline.svg" - no_notification_widget.lay.txt.markup = "No Notification" - end - no_notification_widget.visible = true + if (prob == 5) or (prob == 6) then + w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'megamind.svg' + w:get_children_by_id('no_notification_text')[1].markup = "No Notifications?" else - no_notification_widget.visible = false + w:get_children_by_id('no_notification_icon')[1].image = icondir .. 'bell-outline.svg' + w:get_children_by_id('no_notification_text')[1].markup = "No Notification" end - notification_center_setup() + w:get_children_by_id('no_notification_icon')[1].visible = true + w:get_children_by_id('no_notification_text')[1].visible = true + else + w:get_children_by_id('no_notification_icon')[1].visible = false + w:get_children_by_id('no_notification_text')[1].visible = false end - ) - - local function mouse_leave() - notification_center.visible = false - end - - capi.awesome.connect_signal("notification_center::block_mouse_events", function() - notification_center:disconnect_signal("mouse::leave", mouse_leave) end) - capi.awesome.connect_signal("notification_center::unblock_mouse_events", function() - notification_center:connect_signal("mouse::leave", mouse_leave) + w:get_children_by_id('clear')[1]:connect_signal('button::press', function() + notification_list.children = {} + notification_list:emit_signal('new_children') end) - -- Hide notification_center when mouse leaves it - notification_center:connect_signal( - "mouse::leave", - mouse_leave - ) + w:get_children_by_id('dnd')[1]:get_widget():connect_signal('dnd::toggle', function(enabled) + User_config.dnd = enabled + end) - -- Clear all notifications on button press - clear_all_widget:connect_signal( - "button::press", - function() - local size = #nl - for i = 0, size do - nl[i] = nil - end - capi.awesome.emit_signal("notification_center:update::needed") + w.container = apopup { + widget = w, + bg = Theme_config.notification_center.bg, + border_color = Theme_config.notification_center.border_color, + border_width = Theme_config.notification_center.border_width, + placement = function(c) + aplacement.top(c, { margins = dpi(10) }) + end, + ontop = true, + screen = args.screen, + visible = false, + } + + local activation_area = apopup { + bg = gcolor.transparent, + widget = { + forced_height = dpi(1), + forced_width = dpi(300), + bg = gcolor.transparent, + layout = wibox.layout.fixed.horizontal, + }, + ontop = true, + screen = args.screen, + type = 'dock', + placement = function(c) + aplacement.top(c) + end, + } + + capi.client.connect_signal('property::fullscreen', function(c) + if c.fullscreen then + activation_area.visible = false + else + activation_area.visible = true end - ) + end) - Hover_signal(clear_all_widget.margin3.background4) - --#endregion + activation_area:connect_signal('mouse::enter', function() + w.container.visible = true + end) + w.container:connect_signal('mouse::leave', function() + w.container.visible = false + end) + + return w end + +if not instance then + instance = setmetatable(info_center, { + __call = function(self, ...) + self.new(...) + end, + }) +end + +return instance diff --git a/awesome/src/modules/notification-center/notification_list.lua b/awesome/src/modules/notification-center/notification_list.lua deleted file mode 100644 index b28e9c4..0000000 --- a/awesome/src/modules/notification-center/notification_list.lua +++ /dev/null @@ -1,268 +0,0 @@ -------------------------------------- --- This is the notification-center -- -------------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local naughty = require("naughty") - -local capi = { - awesome = awesome, -} - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/" - -local nl = {} - -nl.notification_list = { layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0, - step = dpi(100), spacing = dpi(20) } - --- @param {table} notification --- @return {widget} notifications_list -function nl.create_notification(n) - - n.time = os.time() - - local time_ago_text = "- ago" - - local timer_widget = wibox.widget { - { - { - text = time_ago_text, - widget = wibox.widget.textbox, - id = "txt" - }, - id = "background", - fg = Theme_config.notification_center.notification_list.timer_fg, - widget = wibox.container.background - }, - margins = dpi(10), - widget = wibox.container.margin, - } - - gears.timer { - timeout = 1, - autostart = true, - call_now = true, - callback = function() - local time_ago = math.floor(os.time() - n.time) - local timer_text = timer_widget.background.txt - if time_ago < 5 then - timer_text:set_text("now") - elseif time_ago < 60 then - timer_text:set_text(time_ago .. "s ago") - elseif time_ago < 3600 then - timer_text:set_text(math.floor(time_ago / 60) .. "m ago") - elseif time_ago < 86400 then - timer_text:set_text(math.floor(time_ago / 3600) .. "h ago") - else - timer_text:set_text(math.floor(time_ago / 86400) .. "d ago") - end - end - } - - local close_widget = wibox.widget { - { - { - { - { - font = User_config.font.specify .. ", 10", - text = "✕", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - start_angle = 4.71239, - thickness = dpi(2), - min_value = 0, - max_value = 360, - value = 360, - widget = wibox.container.arcchart, - id = "arc_chart" - }, - id = "background", - fg = Theme_config.notification_center.notification_list.close_color, - bg = Theme_config.notification_center.notification_list.close_bg, - widget = wibox.container.background - }, - strategy = "exact", - width = dpi(20), - height = dpi(20), - widget = wibox.container.constraint, - id = "const" - }, - margins = dpi(10), - widget = wibox.container.margin, - } - - local timer_close_widget = timer_widget - - local notification = wibox.widget { - { - { - { - { - { - { - { - { - { - { - image = gears.color.recolor_image(icondir .. "notification-outline.svg", - Theme_config.notification_center.notification_list.icon), - resize = false, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - right = dpi(5), - widget = wibox.container.margin - }, - { - markup = n.app_name or 'System Notification', - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - layout = wibox.layout.fixed.horizontal - }, - fg = Theme_config.notification_center.notification_list.title_fg, - widget = wibox.container.background - }, - margins = dpi(10), - widget = wibox.container.margin - }, - nil, - { - timer_widget, - layout = wibox.layout.fixed.horizontal, - id = "arc_app_layout_2" - }, - id = "arc_app_layout", - layout = wibox.layout.align.horizontal - }, - id = "arc_app_bg", - border_color = Theme_config.notification_center.notification_list.title_border_color, - border_width = Theme_config.notification_center.notification_list.title_border_width, - widget = wibox.container.background - }, - { - { - { - { - { - image = n.icon, - resize = true, - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - clip_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 10) - end - }, - width = naughty.config.defaults.icon_size, - height = naughty.config.defaults.icon_size, - strategy = "exact", - widget = wibox.container.constraint - }, - halign = "center", - valign = "top", - widget = wibox.container.place - }, - id = "margin01", - left = dpi(20), - bottom = dpi(15), - top = dpi(15), - right = dpi(10), - widget = wibox.container.margin - }, - { - { - { - markup = n.title, - widget = wibox.widget.textbox, - align = "left" - }, - { - markup = n.message, - widget = wibox.widget.textbox, - align = "left" - }, - layout = wibox.layout.fixed.vertical - }, - left = dpi(10), - bottom = dpi(10), - top = dpi(10), - right = dpi(20), - widget = wibox.container.margin - }, - layout = wibox.layout.fixed.horizontal - }, - id = "widget_layout", - layout = wibox.layout.fixed.vertical - }, - id = "min_size", - strategy = "min", - width = dpi(100), - widget = wibox.container.constraint - }, - id = "max_size", - strategy = "max", - width = Theme.notification_max_width or dpi(500), - widget = wibox.container.constraint - }, - pk = #nl.notification_list + 1, - bg = Theme_config.notification_center.notification_list.notification_bg, - border_color = Theme_config.notification_center.notification_list.notification_border_color, - border_width = Theme_config.notification_center.notification_list.notification_border_width, - shape = Theme_config.notification_center.notification_list.notification_shape, - widget = wibox.container.background - } - - close_widget:connect_signal( - "button::press", - function(_, _, _, button) - if button == 1 then - for i, b in pairs(nl.notification_list) do - if b.pk == notification.pk then - table.remove(nl.notification_list, math.tointeger(i)) - capi.awesome.emit_signal("notification_center:update::needed") - break - end - end - end - end - ) - - Hover_signal(close_widget.const.background) - - notification:connect_signal( - "mouse::enter", - function() - notification:get_children_by_id("arc_app_layout_2")[1]:set(1, close_widget) - end - ) - - notification:connect_signal( - "mouse::leave", - function() - notification:get_children_by_id("arc_app_layout_2")[1]:set(1, timer_close_widget) - end - ) - - table.insert(nl.notification_list, 1, notification) -end - -naughty.connect_signal( - "request::display", - function(n) - nl.create_notification(n) - capi.awesome.emit_signal("notification_center:update::needed") - end -) - -return nl diff --git a/awesome/src/modules/notification-center/profile.lua b/awesome/src/modules/notification-center/profile.lua deleted file mode 100644 index 22eb32b..0000000 --- a/awesome/src/modules/notification-center/profile.lua +++ /dev/null @@ -1,208 +0,0 @@ --------------------------------- --- This is the profile widget -- --------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/profile/" - -return function() - - local profile_widget = wibox.widget { - { - { - { - { - { - { - image = gears.surface.load_uncached(gears.filesystem.get_configuration_dir() .. - "src/assets/userpfp/crylia.png"), - id = "icon", - valign = "center", - halign = "center", - clip_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(12)) - end, - widget = wibox.widget.imagebox - }, - strategy = "exact", - widget = wibox.container.constraint - }, - id = "icon_margin", - margins = dpi(20), - widget = wibox.container.margin - }, - { - { - { - { - { -- Username - id = "username_prefix", - image = gears.color.recolor_image(icondir .. "user.svg", - Theme_config.notification_center.profile.username_icon_color), - valign = "center", - halign = "left", - resize = false, - widget = wibox.widget.imagebox - }, - { -- Username - id = "username", - valign = "center", - align = "left", - widget = wibox.widget.textbox - }, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal - }, - { - { - id = "os_prefix", - image = gears.color.recolor_image(icondir .. "laptop.svg", - Theme_config.notification_center.profile.os_prefix_icon_color), - valign = "center", - halign = "left", - resize = false, - widget = wibox.widget.imagebox - }, - { -- OS - id = "os", - valign = "center", - align = "left", - widget = wibox.widget.textbox - }, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal - }, - { - { - id = "kernel_prefix", - image = gears.color.recolor_image(icondir .. "penguin.svg", - Theme_config.notification_center.profile.kernel_icon_color), - valign = "center", - halign = "left", - resize = false, - widget = wibox.widget.imagebox - }, - { -- Kernel - id = "kernel", - valign = "center", - align = "left", - widget = wibox.widget.textbox - }, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal - }, - { - { - id = "uptime_prefix", - image = gears.color.recolor_image(icondir .. "clock.svg", - Theme_config.notification_center.profile.uptime_icon_color), - valign = "center", - halign = "left", - resize = false, - widget = wibox.widget.imagebox - }, - { -- Uptime - id = "uptime", - valign = "center", - align = "left", - widget = wibox.widget.textbox - }, - spacing = dpi(10), - id = "uptime_layout", - layout = wibox.layout.fixed.horizontal - }, - spacing = dpi(5), - id = "info_layout", - layout = wibox.layout.flex.vertical - }, - id = "text_margin", - widget = wibox.container.constraint - }, - id = "text_container", - bottom = dpi(20), - left = dpi(20), - widget = wibox.container.margin - }, - id = "text_container_wrapper", - widget = wibox.layout.fixed.vertical - }, - id = "wrapper", - fg = Theme_config.notification_center.profile.fg, - border_color = Theme_config.notification_center.profile.border_color, - border_width = Theme_config.notification_center.profile.border_width, - shape = Theme_config.notification_center.profile.shape, - widget = wibox.container.background - }, - id = "const", - strategy = "exact", - width = dpi(250), - height = dpi(350), - widget = wibox.container.constraint - }, - top = dpi(20), - left = dpi(10), - right = dpi(20), - bottom = dpi(10), - widget = wibox.container.margin - } - - local function get_os_name_pretty() - awful.spawn.easy_async_with_shell( - "cat /etc/os-release | grep -w NAME", - function(stdout) - profile_widget:get_children_by_id("os")[1].text = stdout:match("\"(.+)\"") - end - ) - end - - -- function to get and set the kernel version - local function get_kernel_version() - awful.spawn.easy_async_with_shell( - "uname -r", - function(stdout) - profile_widget:get_children_by_id("kernel")[1].text = stdout:match("(%d+%.%d+%.%d+)") - end - ) - end - - --function to get the username and hostname - local function get_user_hostname() - awful.spawn.easy_async_with_shell( - "echo $USER@$(hostname)", - function(stdout) - profile_widget:get_children_by_id("username")[1].text = stdout:gsub("\n", "") or "" - end - ) - end - - -- function to fetch uptime async - local function get_uptime() - awful.spawn.easy_async_with_shell("uptime -p", function(stdout) - - local hours = stdout:match("(%d+) hours") or 0 - local minutes = stdout:match("(%d+) minutes") or 0 - - profile_widget:get_children_by_id("uptime")[1].text = hours .. "h, " .. minutes .. "m" - end) - end - - get_os_name_pretty() - get_kernel_version() - get_user_hostname() - - gears.timer { - timeout = 60, - autostart = true, - call_now = true, - callback = get_uptime - } - - return profile_widget - -end diff --git a/awesome/src/modules/notification-center/song_info.lua b/awesome/src/modules/notification-center/song_info.lua deleted file mode 100644 index 2e63d98..0000000 --- a/awesome/src/modules/notification-center/song_info.lua +++ /dev/null @@ -1,501 +0,0 @@ ---------------------------- --- This is the song-info -- ---------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") - -local capi = { - awesome = awesome, - mouse = mouse, -} - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/notifications/" - -return function(s) - - --#region Music control button widgets - - local function button_hover_effect(widget, svg, color, color2) - local mouse_enter = function() - widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color2)) - local w = capi.mouse.current_wibox - if w then - w.cursor = "hand1" - end - end - - local mouse_leave = function() - widget.image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. svg, color)) - capi.mouse.cursor = "left_ptr" - local w = capi.mouse.current_wibox - if w then - w.cursor = "left_ptr" - end - end - - widget:disconnect_signal("mouse::enter", mouse_enter) - widget:connect_signal("mouse::enter", mouse_enter) - widget:disconnect_signal("mouse::leave", mouse_leave) - widget:connect_signal("mouse::leave", mouse_leave) - end - - local shuffle_button = wibox.widget { - resize = false, - image = gears.color.recolor_image(icondir .. "shuffle.svg", - Theme_config.notification_center.song_info.shuffle_disabled), - valign = "center", - halign = "center", - widget = wibox.widget.imagebox, - } - - local function suffle_handler() - awful.spawn.easy_async_with_shell( - "playerctl shuffle", - function(stdout) - if stdout:match("On") then - awful.spawn.with_shell("playerctl shuffle off") - shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg", - Theme_config.notification_center.song_info.shuffle_disabled) - else - awful.spawn.with_shell("playerctl shuffle on") - shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg", - Theme_config.notification_center.song_info.shuffle_enabled) - end - end - ) - end - - local function update_shuffle() - awful.spawn.easy_async_with_shell( - "playerctl shuffle", - function(stdout) - if stdout:match("On") then - shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg", - Theme_config.notification_center.song_info.shuffle_enabled) - else - shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg", - Theme_config.notification_center.song_info.shuffle_disabled) - end - end - ) - end - - update_shuffle() - - local repeat_button = wibox.widget { - resize = false, - image = gears.color.recolor_image(icondir .. "repeat.svg", Theme_config.notification_center.song_info.repeat_disabled), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - id = "imagebox" - } - - -- On first time load set the correct loop - local function update_loop() - awful.spawn.easy_async_with_shell( - "playerctl loop", - function(stdout) - local loop_mode = stdout:gsub("\n", "") - if loop_mode == "Track" then - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"), - Theme_config.notification_center.song_info.repeat_single) - elseif loop_mode == "None" then - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"), - Theme_config.notification_center.song_info.repeat_disabled) - elseif loop_mode == "Playlist" then - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"), - Theme_config.notification_center.song_info.repeat_all) - end - end - ) - end - - update_loop() - -- Activate shuffle when button is clicked - shuffle_button:buttons(gears.table.join( - awful.button({}, 1, suffle_handler))) - - local prev_button = wibox.widget { - resize = false, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled), - widget = wibox.widget.imagebox - } - - -- Activate previous song when button is clicked - prev_button:buttons(gears.table.join( - awful.button({}, 1, function() - awful.spawn.easy_async_with_shell( - "playerctl previous && sleep 1", - function() - update_loop() - end - ) - end) - )) - - local pause_play_button = wibox.widget { - resize = false, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "play-pause.svg", - Theme_config.notification_center.song_info.play_enabled), - widget = wibox.widget.imagebox - } - - -- Activate play/pause when button is clicked - pause_play_button:buttons(gears.table.join( - awful.button({}, 1, function() - awful.spawn.with_shell("playerctl play-pause") - end) - )) - - local next_button = wibox.widget { - resize = false, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "skip-next.svg", Theme_config.notification_center.song_info.next_enabled), - widget = wibox.widget.imagebox - } - - -- Activate next song when button is clicked - next_button:buttons(gears.table.join( - awful.button({}, 1, function() - awful.spawn.easy_async_with_shell( - "playerctl next && sleep 1", - function() - update_loop() - end - ) - end) - )) - - --- This function updates the repeat button svg and changes the mode on click - local function loop_handler() - awful.spawn.easy_async_with_shell( - "playerctl loop", - function(stdout) - local loop_mode = stdout:gsub("\n", "") - if loop_mode == "None" then - awful.spawn.with_shell("playerctl loop playlist") - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"), - Theme_config.notification_center.song_info.repeat_all) - elseif loop_mode == "Playlist" then - awful.spawn.with_shell("playerctl loop track") - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat-once.svg"), - Theme_config.notification_center.song_info.repeat_single) - elseif loop_mode == "Track" then - awful.spawn.with_shell("playerctl loop none") - repeat_button.image = gears.color.recolor_image(gears.surface.load_uncached(icondir .. "repeat.svg"), - Theme_config.notification_center.song_info.repeat_disabled) - end - end - ) - end - - repeat_button:buttons(gears.table.join(awful.button({}, 1, loop_handler))) - - button_hover_effect(prev_button, "skip-prev.svg", Theme_config.notification_center.song_info.prev_enabled, - Theme_config.notification_center.song_info.prev_hover) - button_hover_effect(pause_play_button, "play-pause.svg", Theme_config.notification_center.song_info.play_enabled, - Theme_config.notification_center.song_info.play_hover) - button_hover_effect(next_button, "skip-next.svg", Theme_config.notification_center.song_info.next_enabled, - Theme_config.notification_center.song_info.next_hover) - - --#endregion - - -- Main music widget - local music_widget = wibox.widget { - { - { - { - { - { - { -- Album art - { - image = icondir .. "default_image.svg", - resize = true, - clip_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(8)) - end, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox, - id = "imagebox" - }, - width = dpi(80), - height = dpi(80), - strategy = "exact", - widget = wibox.container.constraint, - id = "const" - }, - { - { - { - { - { --Title - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "textbox4" - }, - fg = Theme_config.notification_center.song_info.title_fg, - id = "textbox5", - widget = wibox.container.background - }, - id = "textbox_const", - strategy = "max", - width = dpi(400), - widget = wibox.container.constraint - }, - halign = "center", - valign = "center", - id = "textbox_container4", - widget = wibox.container.place - }, - { - { - { - { --Artist - halign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "textbox3" - }, - fg = Theme_config.notification_center.song_info.artist_fg, - id = "background", - widget = wibox.container.background - }, - strategy = "max", - width = dpi(400), - widget = wibox.container.constraint - }, - halign = "center", - valign = "center", - id = "artist_container", - widget = wibox.container.place - }, - { --Buttons - { - { - shuffle_button, - prev_button, - pause_play_button, - next_button, - repeat_button, - spacing = dpi(15), - layout = wibox.layout.fixed.horizontal, - id = "layout5" - }, - halign = "center", - widget = wibox.container.place, - id = "place2" - }, - widget = wibox.container.margin, - id = "margin6" - }, - layout = wibox.layout.flex.vertical, - id = "layout4" - }, - fill_space = true, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal, - id = "layout3" - }, - widget = wibox.container.margin, - id = "margin5" - }, - { --Song Duration - { - { - { - markup = "0:00", - widget = wibox.widget.textbox, - id = "textbox2" - }, - fg = Theme_config.notification_center.song_info.duration_fg, - widget = wibox.container.background, - id = "background3" - }, - right = dpi(10), - widget = wibox.container.margin, - id = "margin4" - }, - { -- Progressbar - { - color = Theme_config.notification_center.song_info.progress_color, - background_color = Theme_config.notification_center.song_info.progress_background_color, - max_value = 100, - value = 50, - forced_height = dpi(5), - shape = function(cr, width) - gears.shape.rounded_bar(cr, width, dpi(5)) - end, - widget = wibox.widget.progressbar, - id = "progressbar1" - }, - valign = "center", - halign = "center", - widget = wibox.container.place, - id = "place1" - }, - { - { - { - text = "00:00", - widget = wibox.widget.textbox, - id = "text1" - }, - id = "background2", - fg = Theme_config.notification_center.song_info.duration_fg, - widget = wibox.container.background - }, - id = "margin3", - left = dpi(10), - widget = wibox.container.margin - }, - id = "layout2", - layout = wibox.layout.align.horizontal - }, - id = "layout1", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - }, - id = "margin2", - widget = wibox.container.margin, - margins = dpi(10) - }, - id = "background1", - border_color = Theme_config.notification_center.song_info.border_color, - border_width = Theme_config.notification_center.song_info.border_width, - shape = Theme_config.notification_center.song_info.shape, - widget = wibox.container.background - }, - id = "margin1", - widget = wibox.container.margin, - top = dpi(10), - bottom = dpi(20), - left = dpi(20), - right = dpi(20) - } - - -- Used to check if the music changed and if everthing should be updated - local trackid = "" - local artist = "" - local title = "" - - -- Function to get spotify title, artist, album, album_art, length and track_id - local function get_spotify_metadata(skip_check) - skip_check = skip_check or false - awful.spawn.easy_async_with_shell( - "playerctl metadata", - function(stdout) - -- Only fetch info if the track changed or if the title/artist is empty - if skip_check or (not stdout:match(trackid)) or (not stdout:match(artist)) or (not stdout:match(title)) then - -- Get the song title - awful.spawn.easy_async_with_shell( - "playerctl metadata xesam:title", - function(stdout2) - local tit = stdout2:gsub("\n", "") - title = tit - music_widget:get_children_by_id("textbox4")[1].text = tit - end - ) - - -- Get the song artist - awful.spawn.easy_async_with_shell( - "playerctl metadata xesam:artist", - function(stdout2) - local art = stdout2:gsub("\n", "") - artist = art - music_widget:get_children_by_id("textbox3")[1].text = art - end - ) - - -- Get the song album image - awful.spawn.easy_async_with_shell( - "playerctl metadata mpris:artUrl", - function(album_art) - local url = album_art:gsub("\n", "") - awful.spawn.easy_async_with_shell( - -- TODO: curl does not stdout and is returns before it finished. This causes the image to sometimes not show correctly. - -- !Find a better solution than sleep 0.1 - -- Maybe cache the image? Not sure if that would be a waste of space or not. - "curl -s " .. url .. " -o /tmp/album_art.jpg && echo /tmp/album_art.jpg && sleep 0.5", - function() - music_widget:get_children_by_id("imagebox")[1].image = gears.surface.load_uncached("/tmp/album_art.jpg") - or icondir .. "default_image.svg" - end - ) - end - ) - - -- Get the length of the song - awful.spawn.easy_async_with_shell( - "playerctl metadata mpris:length", - function(stdout2) - local length = stdout2:gsub("\n", "") - if length ~= "" then - local length_formated = string.format("%02d:%02d", math.floor((tonumber(length) or 1) / 60000000) or 0, - (math.floor((tonumber(length) or 1) / 1000000) % 60) or 0) - music_widget:get_children_by_id("progressbar1")[1].max_value = tonumber(math.floor(tonumber(length) / - 1000000)) - music_widget:get_children_by_id("text1")[1].markup = string.format("%s" - , Theme_config.notification_center.song_info.duration_fg, length_formated) - end - end - ) - end - - awful.spawn.easy_async_with_shell( - "playerctl metadata mpris:trackid", - function(stdout2) - trackid = stdout2:gsub("\n", "") - end - ) - -- Update track id - trackid, artist, title = stdout, music_widget:get_children_by_id("textbox3")[1].text, - music_widget:get_children_by_id("textbox4")[1].text - end - ) - -- Always update the current song progression - awful.spawn.easy_async_with_shell( - "playerctl position", - function(stdout) - local time = stdout:gsub("\n", "") - if time ~= "" then - local time_formated = string.format("%02d:%02d", math.floor((tonumber(time) or 1) / 60), - math.floor(tonumber(time) or 1) % 60) - music_widget:get_children_by_id("textbox2")[1].markup = string.format("%s" - , Theme_config.notification_center.song_info.duration_fg, time_formated) - music_widget:get_children_by_id("progressbar1")[1].value = tonumber(time) - end - end - ) - end - - -- Call every second, if performance is bad, set the timer to a higher value - gears.timer { - timeout = 1, - autostart = true, - call_now = true, - callback = function() - --!Rewrite entire playerctl module for better performance - --get_spotify_metadata() - end - } - - -- get_spotify_metadata() on awesome reload - capi.awesome.connect_signal("startup", function() - get_spotify_metadata(true) - end) - - return music_widget -end diff --git a/awesome/src/modules/notification-center/spacingline_widget.lua b/awesome/src/modules/notification-center/spacingline_widget.lua deleted file mode 100644 index bd4ca9f..0000000 --- a/awesome/src/modules/notification-center/spacingline_widget.lua +++ /dev/null @@ -1,22 +0,0 @@ ------------------------------------------------- --- This is the spacing widget under the clock -- ------------------------------------------------- - --- Awesome Libs -local dpi = require("beautiful").xresources.apply_dpi -local wibox = require("wibox") - -return function() - - return wibox.widget { - { - forced_height = dpi(2), - bg = Theme_config.notification_center.spacing_line.color, - widget = wibox.container.background - }, - left = dpi(80), - right = dpi(80), - widget = wibox.container.margin - } - -end diff --git a/awesome/src/modules/notification-center/status_bars.lua b/awesome/src/modules/notification-center/status_bars.lua deleted file mode 100644 index 08846bd..0000000 --- a/awesome/src/modules/notification-center/status_bars.lua +++ /dev/null @@ -1,840 +0,0 @@ ------------------------------------- --- This is the status_bars widget -- ------------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") - -local rubato = require("src.lib.rubato") - -local capi = { - awesome = awesome, -} - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/" - ---- Signal bars widget for the notification-center ----@diagnostic disable-next-line: undefined-doc-name ----@return wibox.widget -return 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 - if widget == "cpu_usage" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.cpu_usage_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - image = gears.color.recolor_image(icondir .. "cpu/cpu.svg", - Theme_config.notification_center.status_bar.cpu_usage_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox, - id = "icon1", - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "cpu_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - - capi.awesome.connect_signal( - "update::cpu_usage", - function(cpu_usage) - tooltip.text = "CPU Usage: " .. cpu_usage .. "%" - rubato_timer.target = cpu_usage - end - ) - elseif widget == "cpu_temp" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.cpu_temp_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg", - Theme_config.notification_center.status_bar.cpu_temp_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "cpu_temp_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "update::cpu_temp", - function(cpu_temp) - local temp_icon - if cpu_temp < 50 then - temp_icon = icondir .. "cpu/thermometer-low.svg" - elseif cpu_temp >= 50 and cpu_temp < 80 then - temp_icon = icondir .. "cpu/thermometer.svg" - elseif cpu_temp >= 80 then - temp_icon = icondir .. "cpu/thermometer-high.svg" - end - w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon, - Theme_config.notification_center.status_bar.cpu_temp_color) - tooltip.text = "CPU Temp: " .. cpu_temp .. "°C" - rubato_timer.target = cpu_temp - end - ) - elseif widget == "ram_usage" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.ram_usage_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - image = gears.color.recolor_image(icondir .. "cpu/ram.svg", - Theme_config.notification_center.status_bar.ram_usage_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "ram_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "update::ram_widget", - function(MemTotal, _, MemAvailable) - 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 - end - ) - elseif widget == "gpu_usage" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.gpu_usage_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - image = gears.color.recolor_image(icondir .. "cpu/gpu.svg", - Theme_config.notification_center.status_bar.gpu_usage_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "gpu_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "update::gpu_usage", - function(gpu_usage) - if not gpu_usage then return end - tooltip.text = "GPU Usage: " .. gpu_usage .. "%" - rubato_timer.target = tonumber(gpu_usage) - end - ) - elseif widget == "gpu_temp" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.gpu_temp_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "cpu/thermometer.svg", - Theme_config.notification_center.status_bar.gpu_temp_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "gpu_temp_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "update::gpu_temp", - function(gpu_temp) - local temp_icon - local temp_num = tonumber(gpu_temp) or "NaN" - - if temp_num then - - 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 - w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(temp_icon, - Theme_config.notification_center.status_bar.gpu_temp_color) - tooltip.text = "GPU Temp: " .. temp_num .. "°C" - rubato_timer.target = temp_num - end - ) - elseif widget == "volume" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.volume_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "audio/volume-high.svg", - Theme_config.notification_center.status_bar.volume_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "volume_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - local rubato_timer = rubato.timed { - duration = 1, - pos = bar.value, - subscribed = function(v) - bar.value = v - end - } - - local tooltip = awful.tooltip { - objects = { w }, - mode = "inside", - preferred_alignments = "middle", - margins = dpi(10) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "audio::get", - function(muted, volume) - 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("icon1")[1].image = gears.color.recolor_image(icon .. ".svg", - Theme_config.notification_center.status_bar.volume_color) - tooltip.text = "Volume: " .. volume .. "%" - rubato_timer.target = volume - end - ) - elseif widget == "microphone" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.microphone_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "audio/microphone.svg", - Theme_config.notification_center.status_bar.microphone_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "microphone_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - local rubato_timer = rubato.timed { - duration = 1, - pos = bar.value, - subscribed = function(v) - bar.value = v - end - } - - local tooltip = awful.tooltip { - objects = { w }, - mode = "inside", - preferred_alignments = "middle", - margins = dpi(10) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "microphone::get", - function(muted, volume) - 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("icon1")[1].image = gears.color.recolor_image(icon .. ".svg", - Theme_config.notification_center.status_bar.microphone_color) - tooltip.text = "Microphone: " .. volume .. "%" - rubato_timer.target = volume - end - ) - elseif widget == "backlight" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.backlight_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "brightness/brightness-high.svg", - Theme_config.notification_center.status_bar.backlight_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "brightness_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "brightness::get", - function(brightness) - local icon = icondir .. "brightness" - if brightness >= 0 and brightness < 34 then - icon = icon .. "-low" - elseif brightness >= 34 and brightness < 67 then - icon = icon .. "-medium" - elseif brightness >= 67 then - icon = icon .. "-high" - end - w:get_children_by_id("icon1")[1]:set_image(gears.color.recolor_image(icon .. ".svg", - Theme_config.notification_center.status_bar.backlight_color)) - tooltip.text = "Backlight: " .. brightness .. "%" - rubato_timer.target = brightness - end - ) - elseif widget == "battery" then - w = wibox.widget { - { - { - { --Bar - color = Theme_config.notification_center.status_bar.battery_color, - background_color = Theme_config.notification_center.status_bar.bar_bg_color, - max_value = 100, - value = 0, - forced_height = dpi(8), - shape = function(cr) - gears.shape.rounded_bar(cr, dpi(58), dpi(8)) - end, - id = "progressbar1", - widget = wibox.widget.progressbar - }, - id = "background1", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background2", - forced_height = dpi(58), --120 Base size - (10+10) margin - (4+4) Border - 24 Icon - 10 spacing = 58 - forced_width = dpi(24), - direction = "east", - widget = wibox.container.rotate - }, - { - { --Icon - id = "icon1", - image = gears.color.recolor_image(icondir .. "battery/battery.svg", - Theme_config.notification_center.status_bar.battery_color), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - id = "background3", - height = dpi(24), - width = dpi(24), - widget = wibox.container.constraint - }, - id = "battery_layout", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - } - - local bar = w:get_children_by_id("progressbar1")[1] - - 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) - } - w:connect_signal("mouse::enter", function() - capi.awesome.emit_signal("notification_center::block_mouse_events") - end) - - w:connect_signal("mouse::leave", function() - capi.awesome.emit_signal("notification_center::unblock_mouse_events") - end) - capi.awesome.connect_signal( - "update::battery_widget", - function(battery, battery_icon) - w:get_children_by_id("icon1")[1].image = gears.color.recolor_image(battery_icon, - Theme_config.notification_center.status_bar.battery_color) - tooltip.text = "Battery: " .. battery .. "%" - rubato_timer.target = battery - end - ) - end - table.insert(bar_layout, w) - end - - return bar_layout - end - - local signal_bars = wibox.widget { - { - { - { - { - create_bar_layout(User_config.status_bar_widgets), - width = dpi(480), - strategy = "exact", - widget = wibox.container.constraint - }, - halign = "center", - valign = "center", - widget = wibox.container.place - }, - magins = dpi(10), - layout = wibox.container.margin - }, - forced_height = dpi(120), - forced_width = dpi(500), - border_color = Theme_config.notification_center.status_bar.border_color, - border_width = Theme_config.notification_center.status_bar.border_width, - shape = Theme_config.notification_center.status_bar.shape, - widget = wibox.container.background - }, - top = dpi(10), - left = dpi(20), - right = dpi(20), - bottom = dpi(10), - widget = wibox.container.margin - } - - return signal_bars - -end diff --git a/awesome/src/modules/notification-center/time_date.lua b/awesome/src/modules/notification-center/time_date.lua deleted file mode 100644 index d23b0a2..0000000 --- a/awesome/src/modules/notification-center/time_date.lua +++ /dev/null @@ -1,65 +0,0 @@ ----------------------------------- --- This is the time_date widget -- ----------------------------------- - --- Awesome Libs -local dpi = require("beautiful").xresources.apply_dpi -local wibox = require("wibox") - -return function() - - local time_date = wibox.widget { - { - { - { - { -- Time - { - id = "label", - align = "center", - valign = "center", - format = "%H:%M", - widget = wibox.widget.textclock - }, - widget = wibox.container.margin - }, - { -- Date and Day - { -- Date - { - id = "label", - align = "left", - valign = "bottom", - format = "%d %b %Y", - widget = wibox.widget.textclock - }, - widget = wibox.container.margin - }, - { -- Day - { - id = "label", - align = "left", - valign = "top", - format = "%A", - widget = wibox.widget.textclock - }, - widget = wibox.container.margin - }, - layout = wibox.layout.flex.vertical - }, - spacing = dpi(20), - layout = wibox.layout.fixed.horizontal - }, - valign = "center", - halign = "center", - widget = wibox.container.place - }, - id = "background", - widget = wibox.container.background - }, - id = "margin", - margins = dpi(20), - widget = wibox.container.margin - } - - return time_date - -end diff --git a/awesome/src/modules/notification-center/weather.lua b/awesome/src/modules/notification-center/weather.lua deleted file mode 100644 index e9c997f..0000000 --- a/awesome/src/modules/notification-center/weather.lua +++ /dev/null @@ -1,224 +0,0 @@ --------------------------------- --- This is the weather widget -- --------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") -local naughty = require("naughty") - -local json_lua = require("src.lib.json-lua.json-lua") - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/weather/" - -return function() - - local api_secrets = { - key = User_config.weather_secrets.key, - city_id = User_config.weather_secrets.city_id, - unit = User_config.weather_secrets.unit - } - - local weather_widget = wibox.widget { - { - { - { - { - { - { -- Icon - valign = "center", - align = "center", - resize = true, - forced_width = dpi(64), - forced_height = dpi(64), - widget = wibox.widget.imagebox, - id = "icon" - }, - id = "place2", - valing = "center", - halign = "center", - widget = wibox.container.place - }, - { -- Temperature - text = "0°C", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - font = "JetBrains Mono Bold 24", - id = "temp" - }, - { -- City, Country - text = "City, Country", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "city_country", - }, - { - { -- Description - text = "Description", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "description" - }, - fg = Theme_config.notification_center.weather.description_fg, - widget = wibox.container.background - }, - { -- line - forced_height = dpi(4), - forced_width = dpi(10), - bg = Theme_config.notification_center.weather.line_bg, - widget = wibox.container.background, - id = "line" - }, - { - { -- Speed - { - image = gears.color.recolor_image(icondir .. "weather-windy.svg", - Theme_config.notification_center.weather.speed_icon_color), - resize = true, - forced_width = dpi(24), - forced_height = dpi(24), - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - { - text = "", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "speed" - }, - spacing = dpi(10), - id = "layout3", - layout = wibox.layout.fixed.horizontal - }, - id = "place4", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - { - { -- Humidity - { - forced_width = dpi(24), - forced_height = dpi(24), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "humidity.svg", - Theme_config.notification_center.weather.humidity_icon_color), - id = "humidity_icon" - }, - { - text = "", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - id = "humidity" - }, - spacing = dpi(10), - id = "layoutHum", - layout = wibox.layout.fixed.horizontal - }, - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "lyt", - spacing = dpi(10), - layout = wibox.layout.fixed.vertical - }, - margins = dpi(20), - widget = wibox.container.margin, - }, - id = "center", - halign = "center", - valign = "center", - widget = wibox.container.place - }, - id = "background", - border_color = Theme_config.notification_center.weather.border_color, - border_width = Theme_config.notification_center.weather.border_width, - shape = Theme_config.notification_center.weather.shape, - widget = wibox.container.background - }, - id = "margin", - top = dpi(20), - left = dpi(20), - right = dpi(10), - bottom = dpi(10), - forced_width = dpi(250), - widget = wibox.container.margin - } - - local function fetch_weather_data() - awful.spawn.easy_async_with_shell( - "curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" .. - api_secrets.city_id .. "&units=" .. api_secrets.unit .. "&appid=" .. api_secrets.key .. "'", - function(stdout) - if not stdout:match('error') then - local weather_metadata = json_lua:decode(stdout) - if weather_metadata then - local temp = weather_metadata.main.temp - local humidity = weather_metadata.main.humidity - local city = weather_metadata.name - local country = weather_metadata.sys.country - local weather_icon = weather_metadata.weather[1].icon - local description = weather_metadata.weather[1].description - local speed = weather_metadata.wind.speed - - local icon_table = { - ["01d"] = "weather-sunny", - ["01n"] = "weather-clear-night", - ["02d"] = "weather-partly-cloudy", - ["02n"] = "weather-night-partly-cloudy", - ["03d"] = "weather-cloudy", - ["03n"] = "weather-clouds-night", - ["04d"] = "weather-cloudy", - ["04n"] = "weather-cloudy", - ["09d"] = "weather-rainy", - ["09n"] = "weather-rainy", - ["10d"] = "weather-partly-rainy", - ["10n"] = "weather-partly-rainy", - ["11d"] = "weather-pouring", - ["11n"] = "weather-pouring", - ["13d"] = "weather-snowy", - ["13n"] = "weather-snowy", - ["50d"] = "weather-fog", - ["50n"] = "weather-fog" - } - - weather_widget:get_children_by_id("icon")[1].image = icondir .. icon_table[weather_icon] .. ".svg" - weather_widget:get_children_by_id("temp")[1].text = math.floor(temp + 0.5) .. "°C" - weather_widget:get_children_by_id("city_country")[1].text = city .. ", " .. country - weather_widget:get_children_by_id("description")[1].text = description:sub(1, 1):upper() .. - description:sub(2) - weather_widget:get_children_by_id("line")[1].bg = Theme_config.notification_center.weather.line_color - weather_widget:get_children_by_id("speed")[1].text = speed .. " m/s" - weather_widget:get_children_by_id("humidity")[1].text = humidity .. "%" - - end - end - end - ) - end - - fetch_weather_data() - - gears.timer { - timeout = 900, - autostart = true, - callback = function() - fetch_weather_data() - end - } - - return weather_widget - -end diff --git a/awesome/src/modules/notification-center/widgets/notification_list.lua b/awesome/src/modules/notification-center/widgets/notification_list.lua new file mode 100644 index 0000000..578e319 --- /dev/null +++ b/awesome/src/modules/notification-center/widgets/notification_list.lua @@ -0,0 +1,71 @@ +------------------------------------- +-- This is the notification-center -- +------------------------------------- + +-- Awesome Libs +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local naughty = require('naughty') +local gtimer = require('gears.timer') + +local hover = require('src.tools.hover') + +return setmetatable({}, { + __call = function() + local ret = wibox.widget { + layout = require('src.lib.overflow_widget.overflow').vertical, + scrollbar_width = 0, + step = dpi(100), + spacing = dpi(20), + } + + --!No, :get_children_by_id() does not work here for some reason, yes I hate it too + --[[ naughty.connect_signal('notification_surface', function(b) + local start_time = os.time() + local w = wibox.template.make_from_value(b) + w = w:get_widget() + assert(type(w) == 'table', 'w is not a wibox.widget.base') + + -- Change the clock to a timer how long ago the notification was created + w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1] = wibox.widget { + text = 'now', + font = 'JetBrainsMono Nerd Font, Bold 12', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + } + + hover.bg_hover { widget = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2].children[1].children[1] } + w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[2]:connect_signal('button::press', function() + ret:remove_widgets(w) + ret:emit_signal('new_children') + end) + + gtimer { + timeout = 1, + autostart = true, + call_now = true, + callback = function() + local time_ago = math.floor(os.time() - start_time) + local timer_text = w.children[1].children[1].children[1].children[1].children[1].children[2].children[1].children[1] + if time_ago < 5 then + timer_text:set_text('now') + elseif time_ago < 60 then + timer_text:set_text(time_ago .. 's ago') + elseif time_ago < 3600 then + timer_text:set_text(math.floor(time_ago / 60) .. 'm ago') + elseif time_ago < 86400 then + timer_text:set_text(math.floor(time_ago / 3600) .. 'h ago') + else + timer_text:set_text(math.floor(time_ago / 86400) .. 'd ago') + end + end, + } + + ret:add(w) + ret:emit_signal('new_children') + end) ]] + + return ret + end, +}) diff --git a/awesome/src/modules/notification-center/widgets/profile.lua b/awesome/src/modules/notification-center/widgets/profile.lua new file mode 100644 index 0000000..36886dc --- /dev/null +++ b/awesome/src/modules/notification-center/widgets/profile.lua @@ -0,0 +1,174 @@ +-------------------------------- +-- This is the profile widget -- +-------------------------------- + +-- Awesome Libs +local aspawn = require('awful.spawn') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local gshape = require('gears.shape') +local gsurface = require('gears.surface') +local gtimer = require('gears.timer') +local wibox = require('wibox') + +-- Icon directory path +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/profile/' + +local instance = nil + +if not instance then + instance = setmetatable({}, { __call = function() + local w = wibox.widget { + { + { + { + { + { + { + ---@diagnostic disable-next-line: param-type-mismatch + image = gsurface.load_uncached(gfilesystem.get_configuration_dir() .. 'src/assets/userpfp/userpfp.png'), + valign = 'center', + halign = 'center', + clip_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(12)) + end, + widget = wibox.widget.imagebox, + }, + strategy = 'exact', + widget = wibox.container.constraint, + }, + margins = dpi(20), + widget = wibox.container.margin, + }, + { + { + { + { -- Username + image = gcolor.recolor_image(icondir .. 'user.svg', + Theme_config.notification_center.profile.username_icon_color), + valign = 'center', + halign = 'left', + resize = false, + widget = wibox.widget.imagebox, + }, + { -- Username + id = 'username', + valign = 'center', + halign = 'left', + widget = wibox.widget.textbox, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + { + image = gcolor.recolor_image(icondir .. 'laptop.svg', + Theme_config.notification_center.profile.os_prefix_icon_color), + valign = 'center', + halign = 'left', + resize = false, + widget = wibox.widget.imagebox, + }, + { -- OS + id = 'os', + valign = 'center', + halign = 'left', + widget = wibox.widget.textbox, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + { + image = gcolor.recolor_image(icondir .. 'penguin.svg', + Theme_config.notification_center.profile.kernel_icon_color), + valign = 'center', + halign = 'left', + resize = false, + widget = wibox.widget.imagebox, + }, + { -- Kernel + id = 'kernel', + valign = 'center', + halign = 'left', + widget = wibox.widget.textbox, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + { + image = gcolor.recolor_image(icondir .. 'clock.svg', + Theme_config.notification_center.profile.uptime_icon_color), + valign = 'center', + halign = 'left', + resize = false, + widget = wibox.widget.imagebox, + }, + { -- Uptime + id = 'uptime', + valign = 'center', + halign = 'left', + widget = wibox.widget.textbox, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + spacing = dpi(5), + layout = wibox.layout.flex.vertical, + }, + bottom = dpi(20), + left = dpi(20), + widget = wibox.container.margin, + }, + widget = wibox.layout.fixed.vertical, + }, + fg = Theme_config.notification_center.profile.fg, + border_color = Theme_config.notification_center.profile.border_color, + border_width = Theme_config.notification_center.profile.border_width, + shape = Theme_config.notification_center.profile.shape, + widget = wibox.container.background, + }, + strategy = 'exact', + width = dpi(250), + height = dpi(350), + widget = wibox.container.constraint, + }, + top = dpi(20), + left = dpi(10), + right = dpi(20), + bottom = dpi(10), + widget = wibox.container.margin, + } + + aspawn.easy_async_with_shell('cat /etc/os-release | grep -w NAME', function(stdout) + w:get_children_by_id('os')[1].text = stdout:match('\"(.+)\"') + end) + + aspawn.easy_async_with_shell('uname -r', function(stdout) + w:get_children_by_id('kernel')[1].text = stdout:match('(%d+%.%d+%.%d+)') + end) + + aspawn.easy_async_with_shell('echo $USER@$(hostname)', function(stdout) + w:get_children_by_id('username')[1].text = stdout:gsub('\n', '') or '' + end) + + gtimer { + timeout = 60, + autostart = true, + call_now = true, + callback = function() + aspawn.easy_async_with_shell('uptime -p', function(stdout) + local hours = stdout:match('(%d+) hours') or 0 + local minutes = stdout:match('(%d+) minutes') or 0 + w:get_children_by_id('uptime')[1].text = hours .. 'h, ' .. minutes .. 'm' + end) + end, + } + + return w + end, }) +end + +return instance diff --git a/awesome/src/modules/notification-center/widgets/song_info.lua b/awesome/src/modules/notification-center/widgets/song_info.lua new file mode 100644 index 0000000..8356d26 --- /dev/null +++ b/awesome/src/modules/notification-center/widgets/song_info.lua @@ -0,0 +1,241 @@ +--------------------------- +-- This is the song-info -- +--------------------------- + +-- Awesome Libs +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local gfilesystem = require('gears.filesystem') +local gtable = require('gears.table') +local gcolor = require('gears.color') +local gshape = require('gears.shape') +local base = require('wibox.widget.base') +local abutton = require('awful.button') + +local mh = require('src.tools.helpers.playerctl') + +-- Icon directory path +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/' + +local music_player = {} + +return setmetatable({}, { __call = function() + local w = base.make_widget_from_value { + { + { + { + { + { -- Album art + { + image = icondir .. 'default_image.svg', + resize = true, + clip_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + id = 'album_art', + }, + width = dpi(80), + height = dpi(80), + strategy = 'exact', + widget = wibox.container.constraint, + }, + { + { + { + { + { --Title + valign = 'center', + halign = 'center', + text = 'Unknown Title', + id = 'title', + widget = wibox.widget.textbox, + }, + fg = Theme_config.notification_center.song_info.title_fg, + widget = wibox.container.background, + }, + strategy = 'max', + width = dpi(400), + widget = wibox.container.constraint, + }, + widget = wibox.container.place, + }, + { + { + { + { --Artist + halign = 'center', + valign = 'center', + id = 'artist', + text = 'Unknown Artist', + widget = wibox.widget.textbox, + }, + fg = Theme_config.notification_center.song_info.artist_fg, + widget = wibox.container.background, + }, + strategy = 'max', + width = dpi(400), + widget = wibox.container.constraint, + }, + widget = wibox.container.place, + }, + { --Buttons + { + { + resize = false, + image = gcolor.recolor_image(icondir .. 'shuffle.svg', + Theme_config.notification_center.song_info.shuffle_disabled), + valign = 'center', + halign = 'center', + id = 'shuffle', + widget = wibox.widget.imagebox, + }, + { + resize = false, + valign = 'center', + halign = 'center', + id = 'prev', + image = gcolor.recolor_image(icondir .. 'skip-prev.svg', Theme_config.notification_center.song_info.prev_enabled), + widget = wibox.widget.imagebox, + }, + { + resize = false, + valign = 'center', + halign = 'center', + id = 'play_pause', + image = gcolor.recolor_image(icondir .. 'play-pause.svg', + Theme_config.notification_center.song_info.play_enabled), + widget = wibox.widget.imagebox, + }, + { + resize = false, + valign = 'center', + halign = 'center', + id = 'next', + image = gcolor.recolor_image(icondir .. 'skip-next.svg', Theme_config.notification_center.song_info.next_enabled), + widget = wibox.widget.imagebox, + }, + { + resize = false, + image = gcolor.recolor_image(icondir .. 'repeat.svg', Theme_config.notification_center.song_info.repeat_disabled), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + id = 'repeat', + }, + spacing = dpi(15), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + layout = wibox.layout.flex.vertical, + }, + fill_space = true, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { --Song Duration + { + { + { + widget = wibox.widget.textbox, + id = 'position', + text = '00:00', + valign = 'center', + halign = 'center', + }, + fg = Theme_config.notification_center.song_info.duration_fg, + widget = wibox.container.background, + }, + right = dpi(10), + widget = wibox.container.margin, + }, + { -- Progressbar + { + color = Theme_config.notification_center.song_info.progress_color, + background_color = Theme_config.notification_center.song_info.progress_background_color, + max_value = 100, + value = 0, + id = 'progress', + forced_height = dpi(5), + shape = function(cr, width) + gshape.rounded_bar(cr, width, dpi(5)) + end, + widget = wibox.widget.progressbar, + }, + widget = wibox.container.place, + }, + { + { + { + widget = wibox.widget.textbox, + id = 'length', + text = '00:00', + valign = 'center', + halign = 'center', + }, + fg = Theme_config.notification_center.song_info.duration_fg, + widget = wibox.container.background, + }, + left = dpi(10), + widget = wibox.container.margin, + }, + layout = wibox.layout.align.horizontal, + }, + widget = wibox.layout.fixed.vertical, + }, + widget = wibox.container.margin, + margins = dpi(10), + }, + border_color = Theme_config.notification_center.song_info.border_color, + border_width = Theme_config.notification_center.song_info.border_width, + shape = Theme_config.notification_center.song_info.shape, + widget = wibox.container.background, + }, + widget = wibox.container.margin, + top = dpi(10), + bottom = dpi(20), + left = dpi(20), + right = dpi(20), + } + assert(type(w) == 'table', 'Widget must be a table') + + gtable.crush(w, music_player, true) + + local music_handler = mh(w) + + --#region Buttons + w:get_children_by_id('play_pause')[1]:buttons(gtable.join( + abutton({}, 1, function() + music_handler:play_pause() + end) + )) + + w:get_children_by_id('next')[1]:buttons(gtable.join( + abutton({}, 1, function() + music_handler:next() + end) + )) + + w:get_children_by_id('prev')[1]:buttons(gtable.join( + abutton({}, 1, function() + music_handler:prev() + end) + )) + + w:get_children_by_id('repeat')[1]:buttons(gtable.join( + abutton({}, 1, function() + music_handler:set_loop_status() + end) + )) + + w:get_children_by_id('shuffle')[1]:buttons(gtable.join( + abutton({}, 1, function() + music_handler:set_shuffle() + end) + )) + --#endregion + return w +end, }) diff --git a/awesome/src/modules/notification-center/widgets/status_bars.lua b/awesome/src/modules/notification-center/widgets/status_bars.lua new file mode 100644 index 0000000..79135b2 --- /dev/null +++ b/awesome/src/modules/notification-center/widgets/status_bars.lua @@ -0,0 +1,266 @@ +------------------------------------ +-- This is the status_bars widget -- +------------------------------------ + +-- Awesome Libs +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gears = require('gears') +local wibox = require('wibox') +local base = require('wibox.widget.base') +local gfilesystem = require('gears.filesystem') + +local rubato = require('src.lib.rubato') + +-- Own Libs +local audio = require('src.tools.helpers.audio') +local backlight = 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') +local ram = require('src.tools.helpers.ram') +local gpu_usage = require('src.tools.helpers.gpu_usage') +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() + + ---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 { + { + { + { + { --Bar + color = Theme_config.notification_center.status_bar.cpu_usage_color, + background_color = Theme_config.notification_center.status_bar.bar_bg_color, + 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.widget.imagebox, + }, + height = dpi(24), + width = dpi(24), + widget = wibox.container.constraint, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + } + + assert(type(w) == 'table', 'Widget creation failed') + + 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 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) + 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', + Theme_config.notification_center.status_bar.cpu_usage_color) + end) + elseif widget == 'cpu_temp' then + cpu_temp:connect_signal('update::cpu_temp', function(_, v) + 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, + Theme_config.notification_center.status_bar.cpu_temp_color) + 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 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', + Theme_config.notification_center.status_bar.ram_usage_color) + end) + elseif widget == 'gpu_usage' then + gpu_usage:connect_signal('update::gpu_usage', function(_, v) + if not v then return 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', + Theme_config.notification_center.status_bar.gpu_usage_color) + end) + elseif widget == 'gpu_temp' then + gpu_temp:connect_signal('update::gpu_temp', function(_, v) + 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 + w:get_children_by_id('image_role')[1].image = gears.color.recolor_image(temp_icon, + Theme_config.notification_center.status_bar.gpu_temp_color) + 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) + 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', + Theme_config.notification_center.status_bar.volume_color) + tooltip.text = 'Volume: ' .. volume .. '%' + rubato_timer.target = volume + end) + elseif widget == 'microphone' then + audio:connect_signal('source::get', function(_, muted, volume) + 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', + Theme_config.notification_center.status_bar.microphone_color) + tooltip.text = 'Microphone: ' .. volume .. '%' + rubato_timer.target = volume + end) + elseif widget == 'backlight' then + backlight:connect_signal('brightness::get', function(_, v) + 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', + Theme_config.notification_center.status_bar.backlight_color)) + 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, + Theme_config.notification_center.status_bar.battery_color) + tooltip.text = 'Battery: ' .. battery .. '%' + rubato_timer.target = battery + end) ]] + end + table.insert(bar_layout, w) + end + + return bar_layout + end + + return wibox.widget { + { + { + { + { + { + create_bar_layout(User_config.status_bar_widgets), + width = dpi(480), + strategy = 'exact', + widget = wibox.container.constraint, + }, + widget = wibox.container.place, + }, + magins = dpi(10), + layout = wibox.container.margin, + }, + border_color = Theme_config.notification_center.status_bar.border_color, + border_width = Theme_config.notification_center.status_bar.border_width, + shape = Theme_config.notification_center.status_bar.shape, + widget = wibox.container.background, + }, + 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, }) diff --git a/awesome/src/modules/notification-center/widgets/weather.lua b/awesome/src/modules/notification-center/widgets/weather.lua new file mode 100644 index 0000000..7efe804 --- /dev/null +++ b/awesome/src/modules/notification-center/widgets/weather.lua @@ -0,0 +1,203 @@ +-------------------------------- +-- This is the weather widget -- +-------------------------------- + +-- Awesome Libs +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local gfilesystem = require('gears.filesystem') +local gtimer = require('gears.timer') +local aspawn = require('awful.spawn') +local gcolor = require('gears.color') + +local json_lua = require('src.lib.json-lua.json-lua') + +-- Icon directory path +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/weather/' + +local instance = nil + +local icon_table = { + ['01d'] = 'weather-sunny', + ['01n'] = 'weather-clear-night', + ['02d'] = 'weather-partly-cloudy', + ['02n'] = 'weather-night-partly-cloudy', + ['03d'] = 'weather-cloudy', + ['03n'] = 'weather-clouds-night', + ['04d'] = 'weather-cloudy', + ['04n'] = 'weather-cloudy', + ['09d'] = 'weather-rainy', + ['09n'] = 'weather-rainy', + ['10d'] = 'weather-partly-rainy', + ['10n'] = 'weather-partly-rainy', + ['11d'] = 'weather-pouring', + ['11n'] = 'weather-pouring', + ['13d'] = 'weather-snowy', + ['13n'] = 'weather-snowy', + ['50d'] = 'weather-fog', + ['50n'] = 'weather-fog', +} + +if not instance then + instance = setmetatable({}, { __call = function() + + local w = wibox.widget { + { + { + { + { + { + { + { -- Icon + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + id = 'icon', + }, + widget = wibox.container.constraint, + width = dpi(64), + height = dpi(64), + strategy = 'exact', + }, + { -- Temperature + text = 'NaN°C', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + font = 'JetBrains Mono Bold 24', + id = 'temp', + }, + { -- City, Country + text = 'City, Country', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'city_country', + }, + { + { -- Description + text = 'NaN', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'description', + }, + fg = Theme_config.notification_center.weather.description_fg, + widget = wibox.container.background, + }, + { -- line + { + bg = Theme_config.notification_center.weather.line_color, + widget = wibox.container.background, + }, + widget = wibox.container.constraint, + height = dpi(2), + width = dpi(10), + strategy = 'exact', + }, + { + { -- Speed + { + image = gcolor.recolor_image(icondir .. 'weather-windy.svg', + Theme_config.notification_center.weather.speed_icon_color), + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + widget = wibox.container.constraint, + width = dpi(24), + height = dpi(24), + strategy = 'exact', + }, + { + text = 'NaN m/s', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'speed', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + { -- Humidity + { + { + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icondir .. 'humidity.svg', + Theme_config.notification_center.weather.humidity_icon_color), + }, + widget = wibox.container.constraint, + width = dpi(24), + height = dpi(24), + strategy = 'exact', + }, + { + text = 'NaN%', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + id = 'humidity', + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + margins = dpi(20), + widget = wibox.container.margin, + }, + widget = wibox.container.place, + }, + border_color = Theme_config.notification_center.weather.border_color, + border_width = Theme_config.notification_center.weather.border_width, + shape = Theme_config.notification_center.weather.shape, + widget = wibox.container.background, + }, + top = dpi(20), + left = dpi(20), + right = dpi(10), + bottom = dpi(10), + widget = wibox.container.margin, + }, + widget = wibox.container.constraint, + width = dpi(250), + strategy = 'exact', + } + + gtimer { + timeout = 900, + autostart = true, + call_now = true, + callback = function() + aspawn.easy_async_with_shell("curl -sf 'http://api.openweathermap.org/data/2.5/weather?id=" .. + User_config.weather_secrets.city_id .. '&units=' .. User_config.weather_secrets.unit .. '&appid=' .. User_config.weather_secrets.key .. "'", + function(stdout) + if not stdout:match('error') then + local weather_metadata = json_lua:decode(stdout) + if weather_metadata then + w:get_children_by_id('icon')[1].image = icondir .. icon_table[weather_metadata.weather[1].icon] .. '.svg' + w:get_children_by_id('temp')[1].text = math.floor(weather_metadata.main.temp + 0.5) .. '°C' + w:get_children_by_id('city_country')[1].text = weather_metadata.name .. ', ' .. weather_metadata.sys.country + w:get_children_by_id('description')[1].text = weather_metadata.weather[1].description:sub(1, 1):upper() .. + weather_metadata.weather[1].description:sub(2) + w:get_children_by_id('speed')[1].text = weather_metadata.wind.speed .. ' m/s' + w:get_children_by_id('humidity')[1].text = weather_metadata.main.humidity .. '%' + end + end + end + ) + end, + } + + return w + + end, }) +end + +return instance diff --git a/awesome/src/modules/powermenu/init.lua b/awesome/src/modules/powermenu/init.lua new file mode 100644 index 0000000..ee1c14d --- /dev/null +++ b/awesome/src/modules/powermenu/init.lua @@ -0,0 +1,214 @@ +-------------------------------- +-- This is the network widget -- +-------------------------------- + +-- Awesome Libs +local abutton = require('awful.button') +local akey = require('awful.key') +local akeygrabber = require('awful.keygrabber') +local aspawn = require('awful.spawn') +local dpi = require('beautiful').xresources.apply_dpi +local gfilesystem = require('gears.filesystem') +local gtable = require('gears.table') +local wibox = require('wibox') + +local hover = require('src.tools.hover') + +local capi = { + awesome = awesome, + screen = screen, +} + +-- Icon directory path +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/powermenu/' + +local instance = nil +local powermenu = {} + +local function get_button(type) + local icon, name, bg_color, command + + if type == 'shutdown' then + icon = icondir .. 'shutdown.svg' + name = 'Shutdown' + bg_color = Theme_config.powermenu.shutdown_button_bg + command = 'shutdown now' + elseif type == 'reboot' then + icon = icondir .. 'reboot.svg' + name = 'Reboot' + bg_color = Theme_config.powermenu.reboot_button_bg + command = 'reboot' + elseif type == 'logout' then + icon = icondir .. 'logout.svg' + name = 'Logout' + bg_color = Theme_config.powermenu.logout_button_bg + command = 'awesome-client "awesome.quit()"' + elseif type == 'lock' then + icon = icondir .. 'lock.svg' + name = 'Lock' + bg_color = Theme_config.powermenu.lock_button_bg + command = 'dm-tool lock' + elseif type == 'suspend' then + icon = icondir .. 'suspend.svg' + name = 'Suspend' + bg_color = Theme_config.powermenu.suspend_button_bg + command = 'systemctl suspend' + end + + local widget = wibox.widget { + { + { + { + { + { + image = icon, + resize = true, + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + { + text = name, + font = 'JetBrains Mono Bold 30', + valign = 'center', + halign = 'center', + widget = wibox.widget.textbox, + }, + widget = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + fg = Theme_config.powermenu.button_fg, + bg = bg_color, + shape = Theme_config.powermenu.button_shape, + widget = wibox.container.background, + id = 'background', + }, + height = dpi(70), + strategy = 'exact', + widget = wibox.container.constraint, + } + + hover.bg_hover { widget = widget.background, overlay = 12, press_overlay = 24 } + + widget:buttons(gtable.join( + abutton({}, 1, function() + aspawn(command) + end) + )) + + return widget +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 = Theme_config.powermenu.profile_picture_shape, + 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 = Theme_config.powermenu.container_bg, + 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' '" .. User_config.namestyle .. "'", function(stdout) + w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '') + end) + + return w +end + +if instance == nil then + instance = powermenu.new() +end +return instance diff --git a/awesome/src/modules/powermenu/powermenu.lua b/awesome/src/modules/powermenu/powermenu.lua deleted file mode 100644 index c39e862..0000000 --- a/awesome/src/modules/powermenu/powermenu.lua +++ /dev/null @@ -1,249 +0,0 @@ --------------------------------- --- This is the network widget -- --------------------------------- - --- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") - -local capi = { - awesome = awesome, - mouse = mouse, -} - --- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/powermenu/" - -return function(s) - - -- Profile picture imagebox - local profile_picture = wibox.widget { - image = icondir .. "defaultpfp.svg", - resize = true, - forced_height = dpi(200), - clip_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(30)) - end, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - } - - -- Username textbox - local profile_name = wibox.widget { - align = 'center', - valign = 'center', - text = " ", - font = "JetBrains Mono Bold 30", - widget = wibox.widget.textbox - } - - -- Get the profile script from /var/lib/AccountsService/icons/${USER} - -- and copy it to the assets folder - -- TODO: If the user doesnt have AccountsService look into $HOME/.faces - local update_profile_picture = function() - awful.spawn.easy_async_with_shell( - "./.config/awesome/src/scripts/pfp.sh 'userPfp'", - function(stdout) - if stdout then - profile_picture:set_image(stdout:gsub("\n", "")) - else - profile_picture:set_image(icondir .. "defaultpfp.svg") - end - end - ) - end - update_profile_picture() - - -- Get the full username(if set) and the username + hostname - local update_user_name = function() - awful.spawn.easy_async_with_shell( - "./.config/awesome/src/scripts/pfp.sh 'userName' '" .. User_config.namestyle .. "'", - function(stdout) - if stdout:gsub("\n", "") == "Rick Astley" then - profile_picture:set_image(gears.filesystem.get_configuration_dir() .. "src/assets/userpfp/" .. "rickastley.jpg") - end - profile_name:set_text(stdout) - end - ) - end - update_user_name() - - -- Universal Button widget - local button = function(name, icon, bg_color, callback) - local item = wibox.widget { - { - { - { - { - -- TODO: using gears.color to recolor a SVG will make it look super low res - -- currently I recolor it in the .svg file directly, but later implement - -- a better way to recolor a SVG - image = icon, - resize = true, - forced_height = dpi(30), - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - { - text = name, - font = "JetBrains Mono Bold 30", - widget = wibox.widget.textbox - }, - widget = wibox.layout.fixed.horizontal - }, - margins = dpi(10), - widget = wibox.container.margin - }, - fg = Theme_config.powermenu.button_fg, - bg = bg_color, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(10)) - end, - widget = wibox.container.background, - id = 'background' - }, - layout = wibox.layout.align.vertical - } - - item:connect_signal( - "button::release", - function() - callback() - end - ) - - return item - end - - -- Create the power menu actions - local suspend_command = function() - awful.spawn("systemctl suspend") - capi.awesome.emit_signal("module::powermenu:hide") - end - - local logout_command = function() - capi.awesome.quit() - end - - local lock_command = function() - awful.spawn("dm-tool lock") - capi.awesome.emit_signal("module::powermenu:hide") - end - - local shutdown_command = function() - awful.spawn("shutdown now") - capi.awesome.emit_signal("module::powermenu:hide") - end - - local reboot_command = function() - awful.spawn("reboot") - capi.awesome.emit_signal("module::powermenu:hide") - end - - -- Create the buttons with their command and name etc - local shutdown_button = button("Shutdown", icondir .. "shutdown.svg", Theme_config.powermenu.shutdown_button_bg, - shutdown_command) - local reboot_button = button("Reboot", icondir .. "reboot.svg", Theme_config.powermenu.reboot_button_bg, reboot_command) - local suspend_button = button("Suspend", icondir .. "suspend.svg", Theme_config.powermenu.suspend_button_bg, - suspend_command) - local logout_button = button("Logout", icondir .. "logout.svg", Theme_config.powermenu.logout_button_bg, logout_command) - local lock_button = button("Lock", icondir .. "lock.svg", Theme_config.powermenu.lock_button_bg, lock_command) - - -- Signals to change color on hover - Hover_signal(shutdown_button.background) - Hover_signal(reboot_button.background) - Hover_signal(suspend_button.background) - Hover_signal(logout_button.background) - Hover_signal(lock_button.background) - - -- The powermenu widget - local powermenu = wibox.widget { - { - { - profile_picture, - profile_name, - spacing = dpi(50), - layout = wibox.layout.fixed.vertical - }, - { - { - shutdown_button, - reboot_button, - logout_button, - lock_button, - suspend_button, - spacing = dpi(30), - layout = wibox.layout.fixed.horizontal - }, - halign = "center", - valign = "center", - widget = wibox.container.place - }, - layout = wibox.layout.fixed.vertical - }, - halign = "center", - valign = "center", - widget = wibox.container.place - } - - -- Container for the widget, covers the entire screen - local powermenu_container = wibox { - widget = powermenu, - screen = s, - type = "splash", - visible = false, - ontop = true, - bg = Theme_config.powermenu.container_bg, - height = s.geometry.height, - width = s.geometry.width, - x = s.geometry.x, - y = s.geometry.y - } - - -- Close on rightclick - powermenu_container:buttons( - gears.table.join( - awful.button( - {}, - 3, - function() - capi.awesome.emit_signal("module::powermenu:hide") - end - ) - ) - ) - - -- Close on Escape - local powermenu_keygrabber = awful.keygrabber { - autostart = false, - stop_event = 'release', - keypressed_callback = function(self, mod, key, command) - if key == 'Escape' then - capi.awesome.emit_signal("module::powermenu:hide") - end - end - } - - -- Signals - capi.awesome.connect_signal( - "module::powermenu:show", - function() - if s == capi.mouse.screen then - powermenu_container.visible = true - powermenu_keygrabber:start() - end - end - ) - - capi.awesome.connect_signal( - "module::powermenu:hide", - function() - powermenu_keygrabber:stop() - powermenu_container.visible = false - end - ) -end diff --git a/awesome/src/modules/window_switcher/window_elements.lua b/awesome/src/modules/window_switcher/window_elements.lua index c7611a4..4b463fe 100644 --- a/awesome/src/modules/window_switcher/window_elements.lua +++ b/awesome/src/modules/window_switcher/window_elements.lua @@ -3,13 +3,13 @@ --------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local awful = require('awful') +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 color = require('src.lib.color') +local rubato = require('src.lib.rubato') local capi = { awesome = awesome, @@ -21,13 +21,13 @@ return function() local elements = wibox.widget { layout = wibox.layout.fixed.horizontal, spacing = dpi(20), - id = "switcher" + id = 'switcher', } local selected = 0 local function create_elements(fn) - fn = fn or "" + fn = fn or '' elements:reset() @@ -53,44 +53,43 @@ return function() { { -- Icon { - id = "icon", + id = 'icon', --!ADD FALLBACK ICON!-- - image = Get_icon(client.class, client.name) or client.icon, - --image = gears.surface(client.content), - valign = "center", - halign = "center", - widget = wibox.widget.imagebox + 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 + id = 'icon_const', + strategy = 'exact', + widget = wibox.container.constraint, }, { { text = client.name, - id = "label", - widget = wibox.widget.textbox + id = 'label', + widget = wibox.widget.textbox, }, - id = "place", - valign = "center", - halign = "center", - widget = wibox.container.place + id = 'place', + valign = 'center', + halign = 'center', + widget = wibox.container.place, }, - id = "layout1", + id = 'layout1', spacing = dpi(10), - layout = wibox.layout.fixed.vertical + layout = wibox.layout.fixed.vertical, }, - id = "box", + id = 'box', width = dpi(150), height = dpi(150), - strategy = "exact", - widget = wibox.container.constraint + strategy = 'exact', + widget = wibox.container.constraint, }, - id = "margin", + id = 'margin', margins = dpi(20), - widget = wibox.container.margin + widget = wibox.container.margin, }, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, dpi(12)) @@ -99,13 +98,13 @@ return function() border_width = Theme_config.window_switcher.border_width, bg = Theme_config.window_switcher.bg, fg = Theme_config.window_switcher.element_fg, - widget = wibox.container.background + widget = wibox.container.background, } elements:add(window_element) end - if fn == "next" then + if fn == 'next' then if selected >= #clients_sorted then selected = 1 else @@ -153,15 +152,15 @@ return function() 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 }) + 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 }) + 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 = "#" .. + element.border_color = '#' .. color.utils.rgba_to_hex { r_timed_border.pos, g_timed_border.pos, b_timed_border.pos } end @@ -202,7 +201,7 @@ return function() set_bg(Theme_config.window_switcher.bg) end end - elseif fn == "raise" then + elseif fn == 'raise' then local c = clients_sorted[selected] if not c:isvisible() and c.first_tag then c.first_tag:view_only() @@ -219,35 +218,35 @@ return function() elements = create_elements() capi.awesome.connect_signal( - "window_switcher::select_next", + 'window_switcher::select_next', function() - elements = create_elements("next") + elements = create_elements('next') end ) capi.awesome.connect_signal( - "window_switcher::raise", + 'window_switcher::raise', function() - elements = create_elements("raise") + elements = create_elements('raise') end ) capi.client.connect_signal( - "manage", + 'manage', function() elements = create_elements() end ) capi.client.connect_signal( - "unmanage", + 'unmanage', function() elements = create_elements() end ) capi.awesome.connect_signal( - "window_switcher::update", + 'window_switcher::update', function() elements = create_elements() end diff --git a/awesome/src/scripts/mic.sh b/awesome/src/scripts/mic.sh deleted file mode 100755 index 6f57c7f..0000000 --- a/awesome/src/scripts/mic.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -SINK=$(LC_ALL=C pactl get-default-source) - -case $1 in - - "volume") - echo $(LC_ALL=C pactl get-source-volume $SINK | awk '{print $5}') - ;; - - "mute") - echo $(LC_ALL=C pactl get-source-mute $SINK) - ;; - - "toggle_mute") - $(LC_ALL=C pactl set-source-mute $SINK toggle) - ;; - - "set_volume") - $(LC_ALL=C pactl set-source-volume $SINK $2) - ;; - - "set_source") - $(LC_ALL=C pactl set-default-source $2) - ;; - -esac diff --git a/awesome/src/scripts/pfp.sh b/awesome/src/scripts/pfp.sh index ac1a183..29c9066 100755 --- a/awesome/src/scripts/pfp.sh +++ b/awesome/src/scripts/pfp.sh @@ -23,8 +23,8 @@ case $1 in else if [[ -f "$iconPath" ]]; then - cp "$iconPath" "$userIconPath$USER.png" - printf "$userIconPath$USER.png" + cp "$iconPath" $userIconPath"userpfp.png" + printf $userIconPath"userpfp.png" exit; fi fi diff --git a/awesome/src/scripts/vol.sh b/awesome/src/scripts/vol.sh deleted file mode 100755 index 0c9dab0..0000000 --- a/awesome/src/scripts/vol.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -case $1 in - - "volume") - echo $(LC_ALL=C pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}') - ;; - - "mute") - echo $(LC_ALL=C pactl get-sink-mute @DEFAULT_SINK@) - ;; - - "set_sink") - $(LC_ALL=C pactl set-default-sink $2) - ;; -esac diff --git a/awesome/src/theme/colors.lua b/awesome/src/theme/colors.lua index 09e833e..1d795fe 100644 --- a/awesome/src/theme/colors.lua +++ b/awesome/src/theme/colors.lua @@ -3,125 +3,116 @@ ----------------------------------------------------- return { - ['White'] = '#ffffff', - ['Black'] = '#000000', - - ['Grey50'] = '#fafafa', - ['Grey100'] = '#f5f5f5', - ['Grey200'] = '#eeeeee', - ['Grey300'] = '#e0e0e0', - ['Grey400'] = '#bdbdbd', - ['Grey500'] = '#9e9e9e', - ['Grey600'] = '#757575', - ['Grey700'] = '#616161', - ['Grey800'] = '#424242', - ['Grey900'] = '#212121', - - ['Red50'] = '#ffebee', - ['Red100'] = '#ffcdd2', - ['Red200'] = '#ef9a9a', - ['Red300'] = '#e57373', - ['Red400'] = '#ef5350', - ['Red500'] = '#f44336', - ['Red600'] = '#e53935', - ['Red700'] = '#d32f2f', - ['Red800'] = '#c62828', - ['Red900'] = '#b71c1c', - ['RedA100'] = '#ff8a80', - ['RedA200'] = '#ff5252', - ['RedA400'] = '#ff1744', - ['RedA700'] = '#d50000', - - ['Pink50'] = '#fce4ec', - ['Pink100'] = '#f8bbd0', - ['Pink200'] = '#f48fb1', - ['Pink300'] = '#f06292', - ['Pink400'] = '#ec407a', - ['Pink500'] = '#e91e63', - ['Pink600'] = '#d81b60', - ['Pink700'] = '#c2185b', - ['Pink800'] = '#ad1457', - ['Pink900'] = '#880e4f', - ['PinkA100'] = '#ff80ab', - ['PinkA200'] = '#ff4081', - ['PinkA400'] = '#f50057', - ['PinkA700'] = '#c51162', - - ['Blue50'] = '#e3f2fd', - ['Blue100'] = '#bbdefb', - ['Blue200'] = '#90caf9', - ['Blue300'] = '#64b5f6', - ['Blue400'] = '#42a5f5', - ['Blue500'] = '#2196f3', - ['Blue600'] = '#1e88e5', - ['Blue700'] = '#1976d2', - ['Blue800'] = '#1565c0', - ['Blue900'] = '#0d47a1', - ['BlueA100'] = '#82b1ff', - ['BlueA200'] = '#448aff', - ['BlueA400'] = '#2979ff', - ['BlueA700'] = '#2962ff', - - ['Yellow50'] = '#fffde7', - ['Yellow100'] = '#fff9c4', - ['Yellow200'] = '#fff59d', - ['Yellow300'] = '#fff176', - ['Yellow400'] = '#ffee58', - ['Yellow500'] = '#ffeb3b', - ['Yellow600'] = '#fdd835', - ['Yellow700'] = '#fbc02d', - ['Yellow800'] = '#f9a825', - ['Yellow900'] = '#f57f17', - ['YellowA100'] = '#ffff8d', - ['YellowA200'] = '#ffff00', - ['YellowA400'] = '#ffea00', - ['YellowA700'] = '#ffd600', - - ['Teal50'] = '#e0f2f1', - ['Teal100'] = '#b2dfdb', - ['Teal200'] = '#80cbc4', - ['Teal300'] = '#4db6ac', - ['Teal400'] = '#26a69a', - ['Teal500'] = '#009688', - ['Teal600'] = '#00897b', - ['Teal700'] = '#00796b', - ['Teal800'] = '#00695c', - ['Teal900'] = '#004d40', - ['TealA100'] = '#a7ffeb', - ['TealA200'] = '#64ffda', - ['TealA400'] = '#1de9b6', - ['TealA700'] = '#00bfa5', - - ['Green50'] = '#e8f5e9', - ['Green100'] = '#c8e6c9', - ['Green200'] = '#a5d6a7', - ['Green300'] = '#81c784', - ['Green400'] = '#66bb6a', - ['Green500'] = '#4caf50', - ['Green600'] = '#43a047', - ['Green700'] = '#388e3c', - ['Green800'] = '#2e7d32', - ['Green900'] = '#1b5e20', - ['GreenA100'] = '#b9f6ca', - ['GreenA200'] = '#69f0ae', - ['GreenA400'] = '#00e676', - ['GreenA700'] = '#00c853', - - ['Orange50'] = '#fff3e0', - ['Orange100'] = '#ffe0b2', - ['Orange200'] = '#ffcc80', - ['Orange300'] = '#ffb74d', - ['Orange400'] = '#ffa726', - ['Orange500'] = '#ff9800', - ['Orange600'] = '#fb8c00', - ['Orange700'] = '#f57c00', - ['Orange800'] = '#ef6c00', - ['Orange900'] = '#e65100', - ['OrangeA100'] = '#ffd180', - ['OrangeA200'] = '#ffab40', - ['OrangeA400'] = '#ff9100', - ['OrangeA700'] = '#ff6d00', - + ['White'] = '#ffffff', + ['Black'] = '#000000', + ['Grey50'] = '#fafafa', + ['Grey100'] = '#f5f5f5', + ['Grey200'] = '#eeeeee', + ['Grey300'] = '#e0e0e0', + ['Grey400'] = '#bdbdbd', + ['Grey500'] = '#9e9e9e', + ['Grey600'] = '#757575', + ['Grey700'] = '#616161', + ['Grey800'] = '#424242', + ['Grey900'] = '#212121', + ['Red50'] = '#ffebee', + ['Red100'] = '#ffcdd2', + ['Red200'] = '#ef9a9a', + ['Red300'] = '#e57373', + ['Red400'] = '#ef5350', + ['Red500'] = '#f44336', + ['Red600'] = '#e53935', + ['Red700'] = '#d32f2f', + ['Red800'] = '#c62828', + ['Red900'] = '#b71c1c', + ['RedA100'] = '#ff8a80', + ['RedA200'] = '#ff5252', + ['RedA400'] = '#ff1744', + ['RedA700'] = '#d50000', + ['Pink50'] = '#fce4ec', + ['Pink100'] = '#f8bbd0', + ['Pink200'] = '#f48fb1', + ['Pink300'] = '#f06292', + ['Pink400'] = '#ec407a', + ['Pink500'] = '#e91e63', + ['Pink600'] = '#d81b60', + ['Pink700'] = '#c2185b', + ['Pink800'] = '#ad1457', + ['Pink900'] = '#880e4f', + ['PinkA100'] = '#ff80ab', + ['PinkA200'] = '#ff4081', + ['PinkA400'] = '#f50057', + ['PinkA700'] = '#c51162', + ['Blue50'] = '#e3f2fd', + ['Blue100'] = '#bbdefb', + ['Blue200'] = '#90caf9', + ['Blue300'] = '#64b5f6', + ['Blue400'] = '#42a5f5', + ['Blue500'] = '#2196f3', + ['Blue600'] = '#1e88e5', + ['Blue700'] = '#1976d2', + ['Blue800'] = '#1565c0', + ['Blue900'] = '#0d47a1', + ['BlueA100'] = '#82b1ff', + ['BlueA200'] = '#448aff', + ['BlueA400'] = '#2979ff', + ['BlueA700'] = '#2962ff', + ['Yellow50'] = '#fffde7', + ['Yellow100'] = '#fff9c4', + ['Yellow200'] = '#fff59d', + ['Yellow300'] = '#fff176', + ['Yellow400'] = '#ffee58', + ['Yellow500'] = '#ffeb3b', + ['Yellow600'] = '#fdd835', + ['Yellow700'] = '#fbc02d', + ['Yellow800'] = '#f9a825', + ['Yellow900'] = '#f57f17', + ['YellowA100'] = '#ffff8d', + ['YellowA200'] = '#ffff00', + ['YellowA400'] = '#ffea00', + ['YellowA700'] = '#ffd600', + ['Teal50'] = '#e0f2f1', + ['Teal100'] = '#b2dfdb', + ['Teal200'] = '#80cbc4', + ['Teal300'] = '#4db6ac', + ['Teal400'] = '#26a69a', + ['Teal500'] = '#009688', + ['Teal600'] = '#00897b', + ['Teal700'] = '#00796b', + ['Teal800'] = '#00695c', + ['Teal900'] = '#004d40', + ['TealA100'] = '#a7ffeb', + ['TealA200'] = '#64ffda', + ['TealA400'] = '#1de9b6', + ['TealA700'] = '#00bfa5', + ['Green50'] = '#e8f5e9', + ['Green100'] = '#c8e6c9', + ['Green200'] = '#a5d6a7', + ['Green300'] = '#81c784', + ['Green400'] = '#66bb6a', + ['Green500'] = '#4caf50', + ['Green600'] = '#43a047', + ['Green700'] = '#388e3c', + ['Green800'] = '#2e7d32', + ['Green900'] = '#1b5e20', + ['GreenA100'] = '#b9f6ca', + ['GreenA200'] = '#69f0ae', + ['GreenA400'] = '#00e676', + ['GreenA700'] = '#00c853', + ['Orange50'] = '#fff3e0', + ['Orange100'] = '#ffe0b2', + ['Orange200'] = '#ffcc80', + ['Orange300'] = '#ffb74d', + ['Orange400'] = '#ffa726', + ['Orange500'] = '#ff9800', + ['Orange600'] = '#fb8c00', + ['Orange700'] = '#f57c00', + ['Orange800'] = '#ef6c00', + ['Orange900'] = '#e65100', + ['OrangeA100'] = '#ffd180', + ['OrangeA200'] = '#ffab40', + ['OrangeA400'] = '#ff9100', + ['OrangeA700'] = '#ff6d00', ['DeepOrange50'] = '#fbe9e7', ['DeepOrange100'] = '#ffccbc', ['DeepOrange200'] = '#ffab91', @@ -136,76 +127,70 @@ return { ['DeepOrangeA200'] = '#ff6e40', ['DeepOrangeA400'] = '#ff3d00', ['DeepOrangeA700'] = '#dd2c00', - - ['Purple50'] = '#F3E5F5', - ['Purple100'] = '#E1BEE7', - ['Purple200'] = '#CE93D8', - ['Purple300'] = '#BA68C8', - ['Purple400'] = '#AB47BC', - ['Purple500'] = '#9C27B0', - ['Purple600'] = '#8E24AA', - ['Purple700'] = '#7B1FA2', - ['Purple800'] = '#6A1B9A', - ['Purple900'] = '#4A148C', - ['PurpleA100'] = '#EA80FC', - ['PurpleA200'] = '#E040FB', - ['PurpleA500'] = '#D500F9', - ['PurpleA700'] = '#AA00FF', - - ['DeepPurple50'] = '#EDE7F6', - ['DeepPurple100'] = '#D1C4E9', - ['DeepPurple200'] = '#B39DDB', - ['DeepPurple300'] = '#9575CD', - ['DeepPurple400'] = '#7E57C2', - ['DeepPurple500'] = '#673AB7', - ['DeepPurple600'] = '#5E35B1', - ['DeepPurple700'] = '#512DA8', - ['DeepPurple800'] = '#4527A0', - ['DeepPurple900'] = '#311B92', + ['Purple50'] = '#F3E5F5', + ['Purple100'] = '#E1BEE7', + ['Purple200'] = '#CE93D8', + ['Purple300'] = '#BA68C8', + ['Purple400'] = '#AB47BC', + ['Purple500'] = '#9C27B0', + ['Purple600'] = '#8E24AA', + ['Purple700'] = '#7B1FA2', + ['Purple800'] = '#6A1B9A', + ['Purple900'] = '#4A148C', + ['PurpleA100'] = '#EA80FC', + ['PurpleA200'] = '#E040FB', + ['PurpleA500'] = '#D500F9', + ['PurpleA700'] = '#AA00FF', + ['DeepPurple50'] = '#EDE7F6', + ['DeepPurple100'] = '#D1C4E9', + ['DeepPurple200'] = '#B39DDB', + ['DeepPurple300'] = '#9575CD', + ['DeepPurple400'] = '#7E57C2', + ['DeepPurple500'] = '#673AB7', + ['DeepPurple600'] = '#5E35B1', + ['DeepPurple700'] = '#512DA8', + ['DeepPurple800'] = '#4527A0', + ['DeepPurple900'] = '#311B92', ['DeepPurpleA100'] = '#B388FF', ['DeepPurpleA200'] = '#7C4DFF', ['DeepPurpleA400'] = '#651FFF', ['DeepPurpleA700'] = '#6200EA', - - ['LightBlue50'] = '#E1F5FE', - ['LightBlue100'] = '#B3E5FC', - ['LightBlue200'] = '#81D4FA', - ['LightBlue300'] = '#4FC3F7', - ['LightBlue400'] = '#29B6F6', - ['LightBlue500'] = '#03A9F4', - ['LightBlue600'] = '#039BE5', - ['LightBlue700'] = '#0288D1', - ['LightBlue800'] = '#0277BD', - ['LightBlue900'] = '#01579B', - ['LightBlueA100'] = '#80D8FF', - ['LightBlueA200'] = '#40C4FF', - ['LightBlueA400'] = '#00B0FF', - ['LightBlueA700'] = '#0091EA', - - ['Cyan50'] = '#E0F7FA', - ['Cyan100'] = '#B2EBF2', - ['Cyan200'] = '#80DEEA', - ['Cyan300'] = '#4DD0E1', - ['Cyan400'] = '#26C6DA', - ['Cyan500'] = '#00BCD4', - ['Cyan600'] = '#00ACC1', - ['Cyan700'] = '#0097A7', - ['Cyan800'] = '#00838F', - ['Cyan900'] = '#006064', - ['CyanA100'] = '#84FFFF', - ['CyanA200'] = '#18FFFF', - ['CyanA400'] = '#00E5FF', - ['CyanA700'] = '#00B8D4', - - - ['BlueGrey50'] = '#ECEFF1', - ['BlueGrey100'] = '#CFD8DC', - ['BlueGrey200'] = '#B0BEC5', - ['BlueGrey300'] = '#90A4AE', - ['BlueGrey400'] = '#78909C', - ['BlueGrey500'] = '#607D8B', - ['BlueGrey600'] = '#546E7A', - ['BlueGrey700'] = '#455A64', - ['BlueGrey800'] = '#37474F', - ['BlueGrey900'] = '#263238' + ['LightBlue50'] = '#E1F5FE', + ['LightBlue100'] = '#B3E5FC', + ['LightBlue200'] = '#81D4FA', + ['LightBlue300'] = '#4FC3F7', + ['LightBlue400'] = '#29B6F6', + ['LightBlue500'] = '#03A9F4', + ['LightBlue600'] = '#039BE5', + ['LightBlue700'] = '#0288D1', + ['LightBlue800'] = '#0277BD', + ['LightBlue900'] = '#01579B', + ['LightBlueA100'] = '#80D8FF', + ['LightBlueA200'] = '#40C4FF', + ['LightBlueA400'] = '#00B0FF', + ['LightBlueA700'] = '#0091EA', + ['Cyan50'] = '#E0F7FA', + ['Cyan100'] = '#B2EBF2', + ['Cyan200'] = '#80DEEA', + ['Cyan300'] = '#4DD0E1', + ['Cyan400'] = '#26C6DA', + ['Cyan500'] = '#00BCD4', + ['Cyan600'] = '#00ACC1', + ['Cyan700'] = '#0097A7', + ['Cyan800'] = '#00838F', + ['Cyan900'] = '#006064', + ['CyanA100'] = '#84FFFF', + ['CyanA200'] = '#18FFFF', + ['CyanA400'] = '#00E5FF', + ['CyanA700'] = '#00B8D4', + ['BlueGrey50'] = '#ECEFF1', + ['BlueGrey100'] = '#CFD8DC', + ['BlueGrey200'] = '#B0BEC5', + ['BlueGrey300'] = '#90A4AE', + ['BlueGrey400'] = '#78909C', + ['BlueGrey500'] = '#607D8B', + ['BlueGrey600'] = '#546E7A', + ['BlueGrey700'] = '#455A64', + ['BlueGrey800'] = '#37474F', + ['BlueGrey900'] = '#263238', } diff --git a/awesome/src/theme/init.lua b/awesome/src/theme/init.lua index 53e7a1e..56fd438 100644 --- a/awesome/src/theme/init.lua +++ b/awesome/src/theme/init.lua @@ -6,16 +6,20 @@ -- ╚██████╗██║ ██║ ██║ ███████╗██║██║ ██║ -- -- ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝ -- -------------------------------------------------- -local beautiful = require("beautiful") -local gears = require("gears") +local beautiful = require('beautiful') +local gwallpaper = require('gears.wallpaper') +local gfilesystem = require('gears.filesystem') local capi = { + awesome = awesome, screen = screen, } -Theme_path = gears.filesystem.get_configuration_dir() .. "/src/theme/" +Theme_path = gfilesystem.get_configuration_dir() .. '/src/theme/' Theme = {} +awesome.set_preferred_icon_size(128) + -- Default font, change it in user_config, not here. Theme.font = User_config.font.bold @@ -51,17 +55,17 @@ Theme.hotkeys_label_fg = Theme_config.hotkeys.label_fg -- Wallpaper beautiful.wallpaper = User_config.wallpaper -capi.screen.connect_signal( - 'request::wallpaper', - function(s) - if beautiful.wallpaper then - if type(beautiful.wallpaper) == 'string' then - gears.wallpaper.maximized(beautiful.wallpaper, s) - else - beautiful.wallpaper(s) - end +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')() diff --git a/awesome/src/theme/theme_config.lua b/awesome/src/theme/theme_config.lua index 991ab5f..28dda45 100644 --- a/awesome/src/theme/theme_config.lua +++ b/awesome/src/theme/theme_config.lua @@ -1,7 +1,7 @@ -- Awesome Libs -local color = require("src.theme.colors") -local dpi = require("beautiful.xresources").apply_dpi -local gshape = require("gears.shape") +local color = require('src.theme.colors') +local dpi = require('beautiful.xresources').apply_dpi +local gshape = require('gears.shape') Theme_config = {} @@ -18,127 +18,175 @@ Theme_config = {} -- #region Widget Settings Theme_config.audio = { - bg = color["Yellow200"], - fg = color["Grey900"] + bg = color['Yellow200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.battery = { - bg = color["Purple200"], - fg = color["Grey900"] + bg = color['Purple200'], + fg = color['Grey900'], } Theme_config.bluetooth = { - bg = color["Blue200"], - fg = color["Grey900"] + bg = color['Blue200'], + fg = color['Grey900'], } Theme_config.clock = { - bg = color["Orange200"], - fg = color["Grey900"] + bg = color['Orange200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.cpu_freq = { - bg = color["Blue200"], - fg = color["Grey900"] + bg = color['Blue200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.cpu_temp = { - fg = color["Grey900"], - bg_low = color["Green200"], - bg_mid = color["Orange200"], - bg_high = color["Red200"] + fg = color['Grey900'], + bg_low = color['Green200'], + bg_mid = color['Orange200'], + bg_high = color['Red200'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.cpu_usage = { - bg = color["Blue200"], - fg = color["Grey900"] + bg = color['Blue200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.date = { - bg = color["Teal200"], - fg = color["Grey900"] + bg = color['Teal200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.dnd = { - bg = color["Grey900"], - disabled = color["Grey800"], - border_disabled = color["Grey800"], + bg = color['Grey900'], + disabled = color['Grey800'], + border_disabled = color['Grey800'], } Theme_config.gpu_usage = { - bg = color["Green200"], - fg = color["Grey900"] + bg = color['Green200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.gpu_temp = { - fg = color["Grey900"], - bg_low = color["Green200"], - bg_mid = color["Orange200"], - bg_high = color["Red200"] + fg = color['Grey900'], + bg_low = color['Green200'], + bg_mid = color['Orange200'], + bg_high = color['Red200'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.kblayout = { - bg = color["Green200"], - fg = color["Grey900"], - bg_container = color["Grey900"], - border_color_container = color["Grey800"], + bg = color['Green200'], + fg = color['Grey900'], + bg_container = color['Grey900'], + border_color = color['Grey800'], + border_width = dpi(2), + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, item = { - bg = color["Grey800"], - fg_long = color["Red200"], - fg_short = color["Purple200"], - bg_selected = color["DeepPurple200"], - fg_selected = color["Grey900"] - } + bg = color['Grey900'], + border_color = color['Grey800'], + border_width = dpi(2), + fg_long = color['Red200'], + fg_short = color['Purple200'], + bg_selected = color['DeepPurple200'], + fg_selected = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + }, } Theme_config.layout_list = { - bg = color["LightBlue200"], - fg = color["Grey900"], + bg = color['LightBlue200'], + fg = color['Grey900'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(6)) - end + end, } Theme_config.network = { - bg = color["Red200"], - fg = color["Grey900"], - notify_icon_color = color["Grey100"] + bg = color['Red200'], + fg = color['Grey900'], + notify_icon_color = color['Grey100'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.power_button = { - bg = color["Red200"], - fg = color["Grey900"] + bg = color['Red200'], + fg = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.ram_info = { - bg = color["Red200"], - fg = color["Grey900"] + bg = color['Red200'], + fg = color['Grey900'], } Theme_config.systray = { - bg = "#3A475C" + bg = '#3A475C', + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.taglist = { - bg = "#3A475C", - fg = color["Grey100"], - bg_urgent = color["RedA200"], - fg_urgent = color["Grey900"], - bg_focus = color["Grey100"], - bg_focus_pressed = "#dddddd", - bg_focus_hover = color["Grey100"], - fg_focus = color["Grey900"] + bg = '#3A475C', + fg = color['Grey100'], + bg_urgent = color['RedA200'], + fg_urgent = color['Grey900'], + bg_focus = color['Grey100'], + bg_focus_pressed = '#dddddd', + bg_focus_hover = color['Grey100'], + fg_focus = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } Theme_config.tasklist = { - bg = "#3A475C", - fg = color["Grey100"], - bg_urgent = color["RedA200"], - fg_urgent = color["Grey900"], - bg_focus = color["Grey100"], - bg_focus_pressed = "#dddddd", - bg_focus_hover = color["Grey100"], - fg_focus = color["Grey900"] + bg = '#3A475C', + fg = color['Grey100'], + bg_urgent = color['RedA200'], + fg_urgent = color['Grey900'], + bg_focus = color['Grey100'], + bg_focus_pressed = '#dddddd', + bg_focus_hover = color['Grey100'], + fg_focus = color['Grey900'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(6)) + end, } -- #endregion @@ -154,115 +202,115 @@ Theme_config.tasklist = { -- #region Module Settings Theme_config.calendar = { - bg = color["Grey900"], - fg = color["Grey100"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Grey100'], + border_color = color['Grey800'], border_width = dpi(2), shape = function(cr, w, h) gshape.rounded_rect(cr, w, h, dpi(8)) end, day = { - today_border_color = color["Blue200"], - bg = color["Grey900"], - bg_focus = color["Teal200"], - bg_unfocus = color["Grey900"], - fg = color["Grey100"], - fg_focus = color["Grey900"], - fg_unfocus = color["Grey600"], - border_color = color["Grey800"], + today_border_color = color['Blue200'], + bg = color['Grey900'], + bg_focus = color['Teal200'], + bg_unfocus = color['Grey900'], + fg = color['Grey100'], + fg_focus = color['Grey900'], + fg_unfocus = color['Grey600'], + border_color = color['Grey800'], border_width = dpi(2), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) - end + end, }, task = { - bg = color["Purple200"], - bg_past = color["Grey600"], - fg = color["Grey900"], + bg = color['Purple200'], + bg_past = color['Grey600'], + fg = color['Grey900'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end + end, }, weekdays = { - bg = color["Grey900"], - fg = color["Blue200"] + bg = color['Grey900'], + fg = color['Blue200'], }, add_ical = { - bg = color["Red200"], - fg = color["Grey900"], + bg = color['Red200'], + fg = color['Grey900'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end + end, }, add_task = { - bg = color["LightBlue200"], - fg = color["Grey900"], + bg = color['LightBlue200'], + fg = color['Grey900'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end + end, }, task_info = { - icon_color = color["Blue200"], - bg = color["Grey900"], - fg = color["White"], + icon_color = color['Blue200'], + bg = color['Grey900'], + fg = color['White'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) - end - } + end, + }, } Theme_config.desktop = { context_menu = { - icon_color = color["Purple200"], - entry_bg = color["Grey900"], - entry_fg = color["Pink200"], - bg = color["Grey900"], - fg = color["Pink200"], - border_color = color["Grey800"], + icon_color = color['Purple200'], + entry_bg = color['Grey900'], + entry_fg = color['Pink200'], + bg = color['Grey900'], + fg = color['Pink200'], + border_color = color['Grey800'], border_width = dpi(2), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) - end - } + end, + }, } Theme_config.network_manager = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(2), - wifi_icon_color = color["DeepOrange200"], - wifi_bg = color["Grey800"], - wifi_fg = color["Orange200"], - ap_border_color = color["Grey800"], + wifi_icon_color = color['DeepOrange200'], + wifi_bg = color['Grey800'], + wifi_fg = color['Orange200'], + ap_border_color = color['Grey800'], ap_border_width = dpi(2), - airplane_icon_color = color["Orange200"], - refresh_icon_color = color["Orange200"], - power_icon_color = color["Orange200"], - refresh_bg = color["Grey900"], - power_bg = color["Grey900"], + airplane_icon_color = color['Orange200'], + refresh_icon_color = color['Orange200'], + power_icon_color = color['Orange200'], + refresh_bg = color['Grey900'], + power_bg = color['Grey900'], access_point = { - icon_color = color["Red200"], - button_color = color["Grey900"], - icon_color2 = color["Grey900"], - bg = color["Grey900"], - fg = color["Red200"], - border_color = color["Grey800"], + icon_color = color['Red200'], + button_color = color['Grey900'], + icon_color2 = color['Grey900'], + bg = color['Grey900'], + fg = color['Red200'], + border_color = color['Grey800'], border_width = dpi(2), device_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end + end, }, form = { - bg = color["Grey900"], - fg = color["Grey100"], - close_bg = color["Red200"], - icon_fg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Grey100'], + close_bg = color['Red200'], + icon_fg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(2), - button_bg = color["Blue200"], - button_fg = color["Grey900"], - checkbox_fg = color["Grey900"], - checkbox_bg = color["DeepOrange200"], + button_bg = color['Blue200'], + button_fg = color['Grey900'], + checkbox_fg = color['Grey900'], + checkbox_bg = color['DeepOrange200'], checkbox_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(6)) end, @@ -274,14 +322,14 @@ Theme_config.network_manager = { end, shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) - end - } + end, + }, } Theme_config.notification = { - border_color = color["Grey800"], + border_color = color['Grey800'], border_width = dpi(4), - bg = color["Grey900"], + bg = color['Grey900'], spacing = dpi(10), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(10)) @@ -289,119 +337,119 @@ Theme_config.notification = { shape_inside = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - position = "bottom_right", + position = 'bottom_right', timeout = 3, corner_spacing = dpi(20), - bg_urgent = color["Grey900"], - fg_urgent_title = color["RedA200"], - fg_urgent_message = color["Red200"], - fg_urgent_app_name = color["RedA400"], - fg_normal_title = color["Pink200"], - fg_normal_message = "#ffffffaa", - bg_normal = color["Grey900"], - spotify_button_icon_color = color["Cyan200"], - action_bg = color["Grey800"], - action_fg = color["Green200"], - icon_color = color["Teal200"], - fg_appname = color["Teal200"], - fg_time = color["Teal200"], - fg_close = color["Teal200"], - bg_close = color["Grey900"], - title_border_color = color["Grey800"], - title_border_width = dpi(2) + bg_urgent = color['Grey900'], + fg_urgent_title = color['RedA200'], + fg_urgent_message = color['Red200'], + fg_urgent_app_name = color['RedA400'], + fg_normal_title = color['Pink200'], + fg_normal_message = '#ffffffaa', + bg_normal = color['Blue200'], + spotify_button_icon_color = color['Blue200'], + action_bg = color['Grey800'], + action_fg = color['Green200'], + icon_color = color['Blue200'], + fg_appname = color['Blue200'], + fg_time = color['Blue200'], + fg_close = color['Blue200'], + bg_close = color['Grey900'], + title_border_color = color['Grey800'], + title_border_width = dpi(2), } Theme_config.notification_center = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(4), - spacing_color = color["Grey800"], - dnd_color = color["Purple200"], - dnd_fg = color["Pink200"], + spacing_color = color['Grey800'], + dnd_color = color['Purple200'], + dnd_fg = color['Pink200'], -- Clear all button clear_all_button = { - bg = color["Blue200"], - fg = color["Grey900"] + bg = color['Blue200'], + fg = color['Grey900'], }, -- Notification_list notification_list = { - timer_fg = color["Teal200"], - close_color = color["Teal200"], - close_bg = color["Grey900"], - icon = color["Teal200"], - title_fg = color["Teal200"], - title_border_color = color["Grey800"], + timer_fg = color['Teal200'], + close_color = color['Teal200'], + close_bg = color['Grey900'], + icon = color['Teal200'], + title_fg = color['Teal200'], + title_border_color = color['Grey800'], title_border_width = dpi(2), - notification_border_color = color["Grey800"], - notification_bg = color["Grey900"], + notification_border_color = color['Grey800'], + notification_bg = color['Grey900'], notification_border_width = dpi(4), notification_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, 8) - end + end, }, -- Profile widget profile = { - username_icon_color = color["Blue200"], - os_prefix_icon_color = color["Blue200"], - kernel_icon_color = color["Blue200"], - uptime_icon_color = color["Blue200"], - fg = color["Green200"], - border_color = color["Grey800"], + username_icon_color = color['Blue200'], + os_prefix_icon_color = color['Blue200'], + kernel_icon_color = color['Blue200'], + uptime_icon_color = color['Blue200'], + fg = color['Green200'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) - end + end, }, -- Song info widget song_info = { - shuffle_disabled = color["Grey800"], - shuffle_enabled = color["Green200"], - repeat_disabled = color["Grey800"], - repeat_single = color["Green200"], - repeat_all = color["Green200"], - prev_enabled = color["Teal200"], - next_enabled = color["Teal200"], - play_enabled = color["Teal200"], - prev_hover = color["Teal300"], - next_hover = color["Teal300"], - play_hover = color["Teal300"], - title_fg = color["Pink200"], - artist_fg = color["Teal200"], - duration_fg = color["Teal200"], - progress_color = color["Purple200"], - progress_background_color = color["Grey800"], - border_color = color["Grey800"], + shuffle_disabled = color['Grey800'], + shuffle_enabled = color['Green200'], + repeat_disabled = color['Grey800'], + repeat_single = color['Green200'], + repeat_all = color['Green200'], + prev_enabled = color['Teal200'], + next_enabled = color['Teal200'], + play_enabled = color['Teal200'], + prev_hover = color['Teal300'], + next_hover = color['Teal300'], + play_hover = color['Teal300'], + title_fg = color['Pink200'], + artist_fg = color['Teal200'], + duration_fg = color['Teal200'], + progress_color = color['Purple200'], + progress_background_color = color['Grey800'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) - end + end, }, -- Spacing line widget spacing_line = { - color = color["Grey800"] + color = color['Grey800'], }, -- Status bar widgets status_bar = { - border_color = color["Grey800"], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(10)) end, - bar_bg_color = color["Grey800"], - cpu_usage_color = color["Cyan200"], - cpu_temp_color = color["Blue200"], - ram_usage_color = color["Red200"], - gpu_usage_color = color["Green200"], - gpu_temp_color = color["Green200"], - volume_color = color["Yellow200"], - microphone_color = color["Blue200"], - backlight_color = color["Pink200"], - battery_color = color["Purple200"] + bar_bg_color = color['Grey800'], + cpu_usage_color = color['Cyan200'], + cpu_temp_color = color['Blue200'], + ram_usage_color = color['Red200'], + gpu_usage_color = color['Green200'], + gpu_temp_color = color['Green200'], + volume_color = color['Yellow200'], + microphone_color = color['Blue200'], + backlight_color = color['Pink200'], + battery_color = color['Purple200'], }, -- Time Date widget @@ -409,292 +457,279 @@ Theme_config.notification_center = { -- Weather widget weather = { - description_fg = color["LightBlue200"], - line_color = color["Grey800"], - speed_icon_color = color["OrangeA200"], - humidity_icon_color = color["OrangeA200"], - border_color = color["Grey800"], + description_fg = color['LightBlue200'], + line_color = color['Grey800'], + speed_icon_color = color['OrangeA200'], + humidity_icon_color = color['OrangeA200'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) - end - } + end, + }, } Theme_config.bluetooth_controller = { shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) end, - icon_color = color["Purple200"], - icon_color_dark = color["Grey900"], + icon_color = color['Purple200'], + icon_color_dark = color['Grey900'], icon_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - con_button_color = color["Blue200"], - device_bg = color["Grey900"], - device_bg_hover = "#313131", - device_fg_hover = color["LightBlue100"], - device_fg = color["LightBlue200"], - device_border_color = color["Grey800"], + con_button_color = color['Blue200'], + device_bg = color['Grey900'], + device_bg_hover = '#313131', + device_fg_hover = color['LightBlue100'], + device_fg = color['LightBlue200'], + device_border_color = color['Grey800'], device_border_width = dpi(2), device_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - con_device_border_color = color["Grey800"], + con_device_border_color = color['Grey800'], con_device_border_width = dpi(2), con_device_shape = function(cr, width, height) gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4)) end, - connected_bg = color["Grey800"], - connected_fg = color["Purple200"], - connected_icon_color = color["Purple200"], + connected_bg = color['Grey800'], + connected_fg = color['Purple200'], + connected_icon_color = color['Purple200'], connected_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - discovered_icon_color = color["LightBlue200"], - discovered_bg = color["Grey800"], - discovered_fg = color["LightBlue200"], + discovered_icon_color = color['LightBlue200'], + discovered_bg = color['Grey800'], + discovered_fg = color['LightBlue200'], discovered_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - container_border_color = color["Grey800"], + container_border_color = color['Grey800'], container_border_width = dpi(4), - container_bg = color["Grey900"], - refresh_icon_color = color["Grey900"], - refresh_bg = color["LightBlue200"], + container_bg = color['Grey900'], + refresh_icon_color = color['Grey900'], + refresh_bg = color['LightBlue200'], refresh_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - power_icon_color = color["Grey900"], - power_bg = color["Blue200"], + power_icon_color = color['Grey900'], + power_bg = color['Blue200'], } Theme_config.brightness_osd = { - bg = color["Grey900"], - fg = color["Blue200"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Blue200'], + border_color = color['Grey800'], border_width = dpi(4), - bar_bg_active = color["Blue200"], - bar_bg = color["Grey800"], - icon_color = color["Blue200"] + bar_bg_active = color['Blue200'], + bar_bg = color['Grey800'], + icon_color = color['Blue200'], } Theme_config.center_bar = { - bg = color["Grey900"] + bg = color['Grey900'], } Theme_config.dock = { - element_bg = color["Grey900"], - element_focused_bg = color["Grey800"], - element_focused_hover_bg = color["Grey800"], - element_focused_hover_fg = color["Grey100"], - bg = color["Grey900"], - cm_icon = color["LightBlue200"], - indicator_bg = color["Grey600"], - indicator_focused_bg = color["YellowA200"], - indicator_urgent_bg = color["RedA200"], - indicator_maximized_bg = color["GreenA200"], - indicator_bg_mindicator_minimized_bginimized = color["BlueA200"], - indicator_fullscreen_bg = color["PurpleA200"] + bg = color['Grey900'], + element = { + bg = color['BlueGrey800'], + border = color['BlueGrey800'], + border_focus = color['Yellow200'], + border_fullscreen = color['Green200'], + border_maximized = color['Purple200'], + border_minimized = color['Blue200'], + border_urgent = color['Red200'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(8)) + end, + hover_bg = color['BlueGrey400'], + indicator = { + bg = color['Grey100'], + }, + }, + cm_icon = color['Yellow200'], } Theme_config.left_bar = { - bg = color["Grey900"] + bg = color['Grey900'], } Theme_config.powermenu = { - container_bg = "#21212188", - button_fg = color["Grey900"], - shutdown_button_bg = color["Blue200"], - reboot_button_bg = color["Red200"], - suspend_button_bg = color["Yellow200"], - lock_button_bg = color["Green200"], - logout_button_bg = color["Orange200"] + container_bg = '#21212188', + button_fg = color['Grey900'], + shutdown_button_bg = color['Blue200'], + reboot_button_bg = color['Red200'], + suspend_button_bg = color['Yellow200'], + lock_button_bg = color['Green200'], + logout_button_bg = color['Orange200'], + profile_picture_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(30)) + end, + button_shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(10)) + end, } Theme_config.right_bar = { - bg = color["Grey900"] + bg = color['Grey900'], } Theme_config.titlebar = { - bg = "#121212AA", + color = '#121212AA', + button_size = dpi(18), size = dpi(38), - close_button = { - border_color = "#00000000", - border_width = dpi(2), - shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, dpi(6)) - end, - bg = "#00000000", - fg = color["Grey100"], - hover_border = color["Red800"], - hover_bg = color["Red800"] .. "bb", - hover_fg = color["Red800"] - }, - minimize_button = { - border_color = "#00000000", - border_width = dpi(2), - shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, dpi(6)) - end, - fg = color["Grey100"], - bg = "#00000000", - hover_border = color["Orange800"], - hover_fg = color["Orange800"], - hover_bg = color["Orange800"] .. "bb" - }, - maximize_button = { - border_color = "#00000000", - border_width = dpi(2), - shape = function(cr, width, height) - gshape.rounded_rect(cr, width, height, dpi(6)) - end, - fg = color["Grey100"], - bg = "#00000000", - hover_border = color["Green800"], - hover_fg = color["Green800"], - hover_bg = color["Green800"] .. "bb" - } + title_margin = dpi(5), + close = color['RedA200'], + minimize = color['YellowA200'], + maximize = color['GreenA200'], + ontop = color['PinkA200'], + floating = color['PinkA200'], + sticky = color['PinkA200'], } Theme_config.volume_controller = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) end, - device_bg = color["Grey900"], - device_border_color = color["Grey800"], + device_bg = color['Grey900'], + device_border_color = color['Grey800'], device_border_width = dpi(2), device_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - device_headphones_fg = color["Purple200"], - device_microphone_fg = color["Blue200"], - device_headphones_selected_bg = color["Purple200"], - device_headphones_selected_fg = color["Grey900"], - device_microphone_selected_bg = color["Blue200"], - device_microphone_selected_fg = color["Grey900"], - device_headphones_selected_border_color = color["Purple200"], - device_microphone_selected_border_color = color["Blue200"], - device_headphones_selected_icon_color = color["Purple200"], - device_microphone_selected_icon_color = color["Blue200"], - device_icon_color = color["Grey900"], - list_border_color = color["Grey800"], + device_headphones_fg = color['Purple200'], + device_microphone_fg = color['Blue200'], + device_headphones_selected_bg = color['Purple200'], + device_headphones_selected_fg = color['Grey900'], + device_microphone_selected_bg = color['Blue200'], + device_microphone_selected_fg = color['Grey900'], + device_headphones_selected_border_color = color['Purple200'], + device_microphone_selected_border_color = color['Blue200'], + device_headphones_selected_icon_color = color['Purple200'], + device_microphone_selected_icon_color = color['Blue200'], + device_icon_color = color['Grey900'], + list_border_color = color['Grey800'], list_border_width = dpi(2), list_shape = function(cr, width, height) gshape.partially_rounded_rect(cr, width, height, false, false, true, true, dpi(4)) end, - list_bg = color["Grey800"], - list_headphones_fg = color["Purple200"], - list_microphone_fg = color["Blue200"], + list_bg = color['Grey800'], + list_headphones_fg = color['Purple200'], + list_microphone_fg = color['Blue200'], selector_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - volume_fg = color["Purple200"], - microphone_fg = color["Blue200"] + volume_fg = color['Purple200'], + microphone_fg = color['Blue200'], } Theme_config.volume_osd = { - bg = color["Grey900"], - fg = color["Purple200"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Purple200'], + border_color = color['Grey800'], border_width = dpi(4), - bar_bg_active = color["Purple200"], - bar_bg = color["Grey800"], - icon_color = color["Purple200"] + bar_bg_active = color['Purple200'], + bar_bg = color['Grey800'], + icon_color = color['Purple200'], + shape = function(cr, width, height) + gshape.rounded_rect(cr, width, height, dpi(10)) + end, } Theme_config.window_switcher = { - element_bg = color["Grey800"], - element_fg = color["Green200"], - border_color = color["Grey800"], + element_bg = color['Grey800'], + element_fg = color['Green200'], + border_color = color['Grey800'], border_width = dpi(4), - bg = color["Grey900"], - selected_fg = color["CyanA200"], - selected_border_color = color["Purple200"], - selected_bg = "#313131" + bg = color['Grey900'], + selected_fg = color['CyanA200'], + selected_border_color = color['Purple200'], + selected_bg = '#313131', } Theme_config.application_launcher = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(4), application = { - border_color = color["Grey800"], - border_color_active = color["Purple200"], + border_color = color['Grey800'], + border_color_active = color['Purple200'], border_width = dpi(2), - bg = "#313131", - fg = color["Grey100"], - hover_bg = color["Grey700"], - cm_icon_color = color["Pink200"], + bg = '#313131', + fg = color['Grey100'], + hover_bg = color['Grey700'], + cm_icon_color = color['Pink200'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end + end, }, searchbar = { - bg = color["Grey900"], - fg = color["Grey100"], - fg_hint = color["Grey700"], - fg_cursor = color["Grey900"], - bg_cursor = color["Grey100"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Grey100'], + fg_hint = color['Grey700'], + fg_cursor = color['Grey900'], + bg_cursor = color['Grey100'], + border_color = color['Grey800'], border_width = dpi(2), - icon_color = color["Grey900"], - icon_background = color["LightBlue200"], - hover_bg = color["Grey800"], - hover_fg = color["Purple200"], - hover_border = color["Grey700"], - border_active = color["LightBlue200"], + icon_color = color['Grey900'], + icon_background = color['LightBlue200'], + hover_bg = color['Grey800'], + hover_fg = color['Purple200'], + hover_border = color['Grey700'], + border_active = color['LightBlue200'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) - end - } + end, + }, } Theme_config.context_menu = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) end, - fg = color["Grey100"], + fg = color['Grey100'], entry = { - bg = color["Grey900"], - fg = color["Grey100"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Grey100'], + border_color = color['Grey800'], border_width = dpi(2), - hover_fg = color["Teal200"], - hover_border = color["Teal200"], + hover_fg = color['Teal200'], + hover_border = color['Teal200'], shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, - icon_color = color["Grey100"], - icon_color_hover = color["Teal200"] - } + icon_color = color['Grey100'], + icon_color_hover = color['Teal200'], + }, } Theme_config.setup = { - bg = color["Grey900"], - border_color = color["Grey800"], + bg = color['Grey900'], + border_color = color['Grey800'], border_width = dpi(4), wallpaper = { - bg = color["Grey900"], - fg = color["Grey100"], + bg = color['Grey900'], + fg = color['Grey100'], clip_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) end, - button_bg = color["Yellow200"], - button_fg = color["Grey900"], + button_bg = color['Yellow200'], + button_fg = color['Grey900'], button_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) end, - close_fg = color["Red200"], - path_bg = color["Grey800"], - path_fg = color["Grey100"], - path_border_color = color["Grey700"], + close_fg = color['Red200'], + path_bg = color['Grey800'], + path_fg = color['Grey100'], + path_border_color = color['Grey700'], path_border_width = dpi(2), path_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(12)) @@ -702,18 +737,18 @@ Theme_config.setup = { }, bar = { shape = gshape.circle, - color = color["Green200"], + color = color['Green200'], padding = dpi(4), border_width = dpi(2), - border_color = color["Grey800"], - widget_bg = color["Grey800"], - widget_fg = color["Grey100"], - widget_border_color = color["Grey700"], + border_color = color['Grey800'], + widget_bg = color['Grey800'], + widget_fg = color['Grey100'], + widget_border_color = color['Grey700'], widget_border_width = dpi(2), widget_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) end, - widget_toggle_color = color["Blue200"], + widget_toggle_color = color['Blue200'], bar_shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) end, @@ -722,25 +757,31 @@ Theme_config.setup = { end, }, notification = { - separator_color = color["Grey800"], - checkbox_color = color["Purple200"], + separator_color = color['Grey800'], + checkbox_color = color['Purple200'], checkbox_paddings = dpi(4), checkbox_shape = gshape.circle, - border_color = color["Grey800"], + border_color = color['Grey800'], border_width = dpi(2), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(4)) end, }, layout = { - bg = color["Orange200"], - border_color = color["Grey800"], + bg = color['Orange200'], + border_color = color['Grey800'], border_width = dpi(2), shape = function(cr, width, height) gshape.rounded_rect(cr, width, height, dpi(8)) end, - border_color_selected = color["DeepOrange200"] - } + border_color_selected = color['DeepOrange200'], + }, + titlebar = { + checkbox_shape = gshape.circle, + checkbox_color = color['Cyan200'], + checkbox_padding = dpi(4), + seperator_color = color['Grey800'], + }, } -- #endregion @@ -757,36 +798,36 @@ Theme_config.setup = { Theme_config.window = { border_width = dpi(2), - border_normal = color["Grey800"], - border_marked = color["Red200"], - useless_gap = dpi(5) + border_normal = color['Grey800'], + border_marked = color['Red200'], + useless_gap = dpi(5), } Theme_config.tooltip = { - bg = color["Grey900"], - fg = color["CyanA200"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['CyanA200'], + border_color = color['Grey800'], border_width = dpi(4), gaps = dpi(15), shape = function(cr, width, heigth) gshape.rounded_rect(cr, width, heigth, dpi(4)) - end + end, } Theme_config.hotkeys = { - bg = color["Grey900"], - fg = color["Grey100"], - border_color = color["Grey800"], + bg = color['Grey900'], + fg = color['Grey100'], + border_color = color['Grey800'], border_width = dpi(4), shape = function(cr, width, heigth) gshape.rounded_rect(cr, width, heigth, dpi(12)) end, - modifiers_fg = color["Cyan200"], + modifiers_fg = color['Cyan200'], description_font = User_config.font.bold, font = User_config.font.bold, group_margin = dpi(20), - label_bg = color["Cyan200"], - label_fg = color["Grey900"] + label_bg = color['Cyan200'], + label_fg = color['Grey900'], } -- #endregion diff --git a/awesome/src/theme/user_config.lua b/awesome/src/theme/user_config.lua index ad6a107..2712e48 100644 --- a/awesome/src/theme/user_config.lua +++ b/awesome/src/theme/user_config.lua @@ -1,9 +1,9 @@ ------------------------------------------- -- Uservariables are stored in this file -- ------------------------------------------- -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local home = os.getenv("HOME") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local home = os.getenv('HOME') -- If you want different default programs, wallpaper path or modkey; edit this file. User_config = { @@ -17,10 +17,13 @@ User_config = { Flatpak application: flatpak run com.example.App ]] -- autostart = { - "picom", - "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1", - "setxkbmap -option caps:swapescape", - "/home/crylia/.screenlayout/double.sh" + 'nm-applet', + 'protonvpn-cli ks --off', + 'picom', + '/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1', + 'setxkbmap -option caps:swapescape', + '/home/crylia/.screenlayout/double.sh', + 'gnome-keyring-daemon --start --components=secrets', }, --[[ @@ -43,7 +46,7 @@ User_config = { "MEDIA_PLAYER" More information at: https://lazka.github.io/pgi-docs/UPowerGlib-1.0/enums.html#UPowerGlib.DeviceKind.KEYBOARD ]] -- - battery_kind = "LINE_POWER", + battery_kind = 'LINE_POWER', --[[ If your battery is not found you can specify its path here. @@ -61,6 +64,8 @@ User_config = { ]] brightness_step = 2, + clock_mode = 'average', + --[[ DnD or 'Do not Disturb' will prevent notifications from poping up. This is just a default value, you can toggle it in the notification-center, but it won't be saved. @@ -78,12 +83,12 @@ User_config = { This is the program that will be started when clicking on the battery widget If you don't want any just leave it as nil ]] -- - energy_manager = "xfce4-power-manager-settings", + energy_manager = 'xfce4-power-manager-settings', --[[ Your filemanager. Will be opened with + ]] -- - file_manager = "nautilus", + file_manager = 'nemo', --[[ The font that will be used on all widgets/modules etc. @@ -98,19 +103,19 @@ User_config = { } ]] font = { - regular = "JetBrainsMono Nerd Font, " .. dpi(16), - bold = "JetBrainsMono Nerd Font, bold " .. dpi(16), - extrabold = "JetBrainsMono Nerd Font, ExtraBold " .. dpi(16), - specify = "JetBrainsMono Nerd Font" + regular = 'JetBrainsMono Nerd Font, ' .. dpi(16), + bold = 'JetBrainsMono Nerd Font, bold ' .. dpi(16), + extrabold = 'JetBrainsMono Nerd Font, ExtraBold ' .. dpi(16), + specify = 'JetBrainsMono Nerd Font', }, - gtk_settings = "lxappearance", + gtk_settings = 'lxappearance', --[[ The icon theme name must be exactly as the folder is called The folder can be in any $XDG_DATA_DIRS/icons/[icon_theme_name] ]] -- - icon_theme = "Papirus-Dark", + icon_theme = 'Papirus-Dark', -- List every Keyboard layout you use here comma seperated. (run localectl list-keymaps to list all averiable keymaps) --[[ @@ -119,28 +124,15 @@ User_config = { Example: kblayout = { "de", "ru", "us" } ]] -- - kblayout = { "de", "ru" }, + kblayout = { 'de', 'ru' }, --[[ This is a list of every layout you can use. Remove every that you don't want to use. ]] -- layouts = { - awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.tile.top, - awful.layout.suit.floating, awful.layout.suit.fair, - awful.layout.suit.fair.horizontal, - awful.layout.suit.corner.nw, - awful.layout.suit.corner.ne, - awful.layout.suit.corner.sw, - awful.layout.suit.corner.se, - awful.layout.suit.magnifier, - awful.layout.suit.max, - awful.layout.suit.max.fullscreen, - awful.layout.suit.spiral.dwindle, + awful.layout.suit.floating, }, --[[ @@ -153,9 +145,9 @@ User_config = { "mod4" <-- for the super/windows key "mod5" <-- for the shift key ]] -- - modkey = "Mod4", + modkey = 'Mod4', - music_player = "flatpak run com.spotify.Client", + music_player = 'spotify', --[[ This is the naming sheme used for the powermenu and maybe some other places in the future. @@ -164,7 +156,7 @@ User_config = { "fullname" <-- Will display "Firstname Surname" "?" <-- Will display "?" ]] -- - namestyle = "userhost", + namestyle = 'userhost', --[[ This is used to identify your network adapters. @@ -174,16 +166,16 @@ User_config = { ethernet = "eno1" ]] -- network = { - wlan = "wlo1", - ethernet = "eno1" + wlan = 'wlo1', + ethernet = 'eno1', }, - screen_settings = "arandr", + screen_settings = 'arandr', --[[ This is the program that will be executed when hitting the print key. ]] -- - screenshot_program = "flameshot gui", + screenshot_program = 'flameshot gui', --[[ These are the status bar widgets which are to be found in the notification-center. @@ -199,13 +191,13 @@ User_config = { "backlight" ]] -- status_bar_widgets = { - "cpu_usage", - "cpu_temp", - "ram_usage", - "microphone", - "volume", - "gpu_temp", - "gpu_usage", + 'cpu_usage', + 'cpu_temp', + 'ram_usage', + 'microphone', + 'volume', + 'gpu_temp', + 'gpu_usage', }, --[[ @@ -217,9 +209,9 @@ User_config = { --[[ This is the default terminal, Alacritty is the default. ]] -- - terminal = "kitty", + terminal = 'kitty', - text_editor = "code", + text_editor = 'code', --[[ Add every client that should get no titlebar. @@ -233,7 +225,7 @@ User_config = { } ]] -- titlebar_exception = { - "protonvpn" + 'protonvpn', }, --[[ @@ -241,13 +233,19 @@ User_config = { Example: titlebar_position = "top" ]] -- - titlebar_position = "top", + titlebar_position = 'left', + + titlebar_items = { + left_and_bottom = { 'icon' }, + --middle = "title", + right_and_top = { 'close', 'maximize', 'minimize' }, + }, --[[ This is the path to your wallpaper. home is $HOME, you can also use an absolute path. ]] -- - wallpaper = home .. "/Bilder/Hintergründe/784194.jpg", + wallpaper = home .. '/Bilder/Hintergründe/784194.jpg', --[[ This is the weather widget. @@ -258,12 +256,12 @@ User_config = { unit = "metric" or "imperial" ]] weather_secrets = { - key = "e71b00168ca7219563dde4514a425b14", - city_id = "2864118", - unit = "metric" + key = 'e71b00168ca7219563dde4514a425b14', + city_id = '2864118', + unit = 'metric', }, - web_browser = "firefox", + web_browser = 'firefox', --[[ You can configure your bar's here, if you leave it empty the bar will not be shown. @@ -293,65 +291,64 @@ User_config = { crylia_bar = { [1] = { left_bar = { - "Tiling Layout", - "Systray", - "Taglist" + 'Tiling Layout', + 'Systray', + 'Taglist', }, center_bar = { - "Tasklist" + 'Tasklist', }, right_bar = { - "Cpu Frequency", - "Cpu Temperature", - "Cpu Usage", - "Audio", - "Keyboard Layout", - "Date", - "Clock", - "Power Button" - } + 'Bluetooth', + 'Network', + 'Cpu Frequency', + 'Cpu Usage', + 'Cpu Temperature', + 'Audio', + 'Keyboard Layout', + 'Date', + 'Clock', + 'Power Button', + }, }, - --[[ [2] = { + [2] = { left_bar = { - "Tiling Layout", - "Systray", - "Taglist" + 'Tiling Layout', + 'Taglist', }, center_bar = { - "Tasklist" + 'Tasklist', }, right_bar = { - "Gpu Temperature", - "Gpu Usage", - "Ram", - "Audio", - "Keyboard Layout", - "Date", - "Clock", - "Power Button" - } - }]] + 'Gpu Temperature', + 'Gpu Usage', + 'Ram Usage', + 'Audio', + 'Date', + 'Clock', + }, + }, }, crylia_wibox = { [1] = { left_bar = { - "Tiling Layout", - "Taglist" + 'Tiling Layout', + 'Taglist', }, center_bar = { - "Tasklist" + 'Tasklist', }, right_bar = { - "Systray", - "Battery", - "Bluetooth", - "Audio", - "Network", - "Keyboard Layout", - "Date", - "Clock", - } - } - } + 'Systray', + 'Battery', + 'Bluetooth', + 'Audio', + 'Network', + 'Keyboard Layout', + 'Date', + 'Clock', + }, + }, + }, } diff --git a/awesome/src/tools/auto_starter.lua b/awesome/src/tools/auto_starter.lua index 4807b7f..c0b8d50 100644 --- a/awesome/src/tools/auto_starter.lua +++ b/awesome/src/tools/auto_starter.lua @@ -1,20 +1,19 @@ -local awful = require("awful") -local Gio = require("lgi").Gio -local gears = require("gears") +local Gio = require('lgi').Gio +local aspawn = require('awful.spawn') +local gfilesystem = require('gears.filesystem') return function(table) for _, t in ipairs(table) do - awful.spawn(t); + aspawn(t); end - local path = gears.filesystem.get_xdg_config_home() .. "autostart/" - local handler = io.popen("ls " .. path) + local path = gfilesystem.get_xdg_config_home() .. 'autostart/' + local handler = io.popen('ls ' .. path) if not handler then return end for file in handler:lines() do local app = Gio.DesktopAppInfo.new_from_filename(path .. file) if app then - Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(Gio.DesktopAppInfo.get_string(app, - "Exec"), nil, 0)) + Gio.AppInfo.launch_uris_async(Gio.AppInfo.create_from_commandline(Gio.DesktopAppInfo.get_string(app, 'Exec'), nil, 0)) end end end diff --git a/awesome/src/tools/config.lua b/awesome/src/tools/config.lua new file mode 100644 index 0000000..e5674d3 --- /dev/null +++ b/awesome/src/tools/config.lua @@ -0,0 +1,87 @@ +local lgi = require('lgi') +local GLib = lgi.GLib +local Gio = lgi.Gio +local gobject = require('gears.object') +local gtable = require('gears.table') +local gfilesystem = require('gears.filesystem') +local aspawn = require('awful.spawn') + +local json = require('src.lib.json-lua.json-lua') + +local config = {} + +local instance + +---Takes a file path and puts the content into the callback +---@param path string file path, caller has to make sure it exists +---@return string|nil file_content +config.read = function(path) + local handler = io.open(path, 'r') + if not handler then error('Invalid path') return end + + local content = handler:read('*all') + handler:close() + return content +end + +---Writes a string to a file +---@param path string file path, caller has to make sure it exists +---@param content string content to write +config.write = function(path, content) + local handler = io.open(path, 'w') + if not handler then error('Invalid path') return end + + handler:write(content) + handler:close() +end + +config.read_json = function(path) + local handler = io.open(path, 'r') + if not handler then error('Invalid path') return end + + local content = handler:read('*all') + handler:close() + + local json_content = json:decode(content) or {} + assert(type(json_content) == 'table', 'json is not a table') + return json_content +end + +config.write_json = function(path, content) + local json_content = json:encode(content) + assert(type(json_content) == 'string', 'json is not a string') + + local handler = io.open(path, 'w') + if not handler then error('Invalid path') return end + + handler:write(json_content) + handler:close() +end + +local function new() + local ret = gobject {} + + gtable.crush(ret, config, true) + + -- Create config files if they don't exist + for _, file in pairs { 'floating.json', 'dock.json', 'desktop.json', 'applications.json' } do + if not gfilesystem.file_readable(gfilesystem.get_configuration_dir() .. 'src/config/' .. file) then + aspawn('touch ' .. gfilesystem.get_configuration_dir() .. 'src/config/' .. file) + end + end + + -- Create config directories if they don't exist + for _, dir in pairs { 'files/desktop/icons' } do + if not gfilesystem.dir_readable(gfilesystem.get_configuration_dir() .. 'src/config/' .. dir) then + gfilesystem.make_directories(gfilesystem.get_configuration_dir() .. 'src/config/' .. dir) + end + end + + return ret +end + +if not instance then + instance = new() +end + +return instance diff --git a/awesome/src/tools/gio_icon_lookup.lua b/awesome/src/tools/gio_icon_lookup.lua index 63be311..cbf046b 100644 --- a/awesome/src/tools/gio_icon_lookup.lua +++ b/awesome/src/tools/gio_icon_lookup.lua @@ -1,84 +1,23 @@ -- Libraries -local lgi = require("lgi") -local Gtk = lgi.require("Gtk", "3.0") -local Gio = lgi.Gio -local gears = require("gears") -local GLib = require("lgi").GLib - --- Get all .desktop files as gobjects -local app_info = Gio.AppInfo -local app_list = app_info.get_all() +local lgi = require('lgi') +local Gtk = lgi.require('Gtk', '3.0') -- Init a new Gtk theme from the users string -local gtk_theme = Gtk.IconTheme.new() -Gtk.IconTheme.set_custom_theme(gtk_theme, User_config.icon_theme) +local gtk_theme = Gtk.IconTheme.get_default() ---Gets the icon path from an AppInfo gicon. ----@param app Gio.AppInfo +---@param app Gio.AppInfo|nil +---@param icon_string string|nil ---@return string|nil path -function Get_gicon_path(app) - if not app then return end +function Get_gicon_path(app, icon_string) + if (not app) and (not icon_string) then return end + if icon_string then + return gtk_theme:lookup_icon(icon_string, 64, 0):get_filename() or '' + end + local icon_info = gtk_theme:lookup_by_gicon(app, 64, 0) if icon_info then - local path = icon_info:get_filename() - if path then - return path - end - end - return "" -end - ----Takes a class and name string and tries to match it to an icon. ----@param class string ----@param name string ----@return string | nil icon_path -function Get_icon(class, name) - class = string.lower(class or "") - name = string.lower(name or "") - for _, app in ipairs(app_list) do - local desktop_app_info = Gio.DesktopAppInfo.new(app_info.get_id(app)) - local icon_string = Gio.DesktopAppInfo.get_string(desktop_app_info, "Icon") - if icon_string then - icon_string = string.lower(icon_string) - if icon_string == class or icon_string == name then - return Get_gicon_path(app_info.get_icon(app)) - elseif icon_string:match(class) then - return Get_gicon_path(app_info.get_icon(app)) - end - end + return icon_info:get_filename() end return nil end - ----Will return every $XDG_DATA_DIRS ----@return table -local function get_paths() - local dirs = {} - - local dir - for _, value in ipairs(GLib.get_system_data_dirs()) do - dir = GLib.build_filenamev({ value, "applications" }) - if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end - end - - dir = GLib.build_filenamev({ GLib.get_user_data_dir(), "applications" }) - if gears.filesystem.dir_readable(dir) then table.insert(dirs, dir) end - - return dirs -end - ----Returns every .desktop file into a table ----@param file string .desktop files ----@return string | nil path -function Get_desktop_values(file) - - if not file or file == "" then - return - end - - for _, dir in ipairs(get_paths()) do - if gears.filesystem.file_readable(dir .. "/" .. file, "r") then - return dir .. "/" .. file - end - end -end diff --git a/awesome/src/tools/helpers/audio.lua b/awesome/src/tools/helpers/audio.lua index a71668e..b02bae1 100644 --- a/awesome/src/tools/helpers/audio.lua +++ b/awesome/src/tools/helpers/audio.lua @@ -1,61 +1,108 @@ -local aspawn = require("awful.spawn") +local aspawn = require('awful.spawn') +local gobject = require('gears.object') +local gtable = require('gears.table') -local capi = { - awesome = awesome, -} +local audio = {} -aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], { - stdout = function(line) - -- Volume changed - if line:match("on sink") or line:match("on source") then - capi.awesome.emit_signal("audio::volume_changed") - capi.awesome.emit_signal("microphone::volume_changed") - end - -- Device added/removed - if line:match("on server") then - capi.awesome.emit_signal("audio::device_changed") - capi.awesome.emit_signal("microphone::device_changed") - end - end, - output_done = function() - aspawn.with_shell("pkill pactl && pkill grep") - end -}) +local instance = nil -capi.awesome.connect_signal("audio::volume_changed", function() - aspawn.easy_async_with_shell("./.config/awesome/src/scripts/vol.sh mute", function(stdout) - if stdout == "" or stdout == nil then - return - end - local muted = false - if stdout:match("yes") then - muted = true - end - aspawn.easy_async_with_shell("./.config/awesome/src/scripts/vol.sh volume", function(stdout2) - if stdout == "" or stdout == nil then +function audio.set_sink_volume(volume) + aspawn('pactl set-sink-volume @DEFAULT_SINK@ ' .. volume .. '%') +end + +function audio.set_source_volume(volume) + aspawn('pactl set-source-volume @DEFAULT_SOURCE@ ' .. volume .. '%') +end + +function audio.sink_volume_up() + aspawn('pactl set-sink-volume @DEFAULT_SINK@ +2%') +end + +function audio.source_volume_up() + aspawn('pactl set-source-volume @DEFAULT_SOURCE@ +2%') +end + +function audio.sink_volume_down() + aspawn('pactl set-sink-volume @DEFAULT_SINK@ -2%') +end + +function audio.source_volume_down() + aspawn('pactl set-source-volume @DEFAULT_SOURCE@ -2%') +end + +function audio.sink_toggle_mute() + aspawn('pactl set-sink-mute @DEFAULT_SINK@ toggle') +end + +function audio.source_toggle_mute() + aspawn('pactl set-source-mute @DEFAULT_SOURCE@ toggle') +end + +local function new() + + local self = gobject {} + gtable.crush(self, audio, true) + + aspawn.with_line_callback([[bash -c "LC_ALL=C pactl subscribe"]], { + stdout = function(line) + -- Volume changed + if line:match('on sink') or line:match('on source') then + self:emit_signal('sink::volume_changed') + self:emit_signal('source::volume_changed') + end + -- Device added/removed + if line:match('on server') then + self:emit_signal('sink::device_changed') + self:emit_signal('source::device_changed') + end + end, + output_done = function() + aspawn.with_shell('pkill pactl && pkill grep') + end, + }) + + self:connect_signal('sink::volume_changed', function() + aspawn.easy_async_with_shell([[LC_ALL=C pactl get-sink-mute @DEFAULT_SINK@]], function(stdout) + if stdout == '' or stdout == nil then return end - capi.awesome.emit_signal("audio::get", muted, stdout2:gsub("%%", ""):gsub("\n", "") or 0) - end) - end) -end) - -capi.awesome.connect_signal("microphone::volume_changed", function() - aspawn.easy_async_with_shell("./.config/awesome/src/scripts/mic.sh mute", function(stdout) - local muted = false - if stdout:match("yes") then - muted = true - end - aspawn.easy_async_with_shell("./.config/awesome/src/scripts/mic.sh volume", function(stdout2) - if stdout2 == nil or stdout2 == "awful" then - return + local muted = false + if stdout:match('yes') then + muted = true end - capi.awesome.emit_signal("microphone::get", muted, stdout2:gsub("%%", ""):gsub("\n", "") or 0) + aspawn.easy_async_with_shell([[LC_ALL=C pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}']], function(stdout2) + if stdout == '' or stdout == nil then + return + end + self:emit_signal('sink::get', muted, stdout2:gsub('%%', ''):gsub('\n', '') or 0) + end) end) end) -end) -capi.awesome.emit_signal("audio::volume_changed") -capi.awesome.emit_signal("microphone::volume_changed") -capi.awesome.emit_signal("audio::device_changed") -capi.awesome.emit_signal("microphone::device_changed") + self:connect_signal('source::volume_changed', function() + aspawn.easy_async_with_shell([[LC_ALL=C pactl get-source-mute @DEFAULT_SOURCE@]], function(stdout) + local muted = false + if stdout:match('yes') then + muted = true + end + aspawn.easy_async_with_shell([[LC_ALL=C pactl get-source-volume @DEFAULT_SOURCE@ | awk '{print $5}']], function(stdout2) + if stdout2 == nil or stdout2 == 'awful' then + return + end + self:emit_signal('source::get', muted, stdout2:gsub('%%', ''):gsub('\n', '') or 0) + end) + end) + end) + + self:emit_signal('sink::volume_changed') + self:emit_signal('source::volume_changed') + self:emit_signal('sink::device_changed') + self:emit_signal('source::device_changed') + + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/backlight.lua b/awesome/src/tools/helpers/backlight.lua index ac26467..cb2d28c 100644 --- a/awesome/src/tools/helpers/backlight.lua +++ b/awesome/src/tools/helpers/backlight.lua @@ -1,57 +1,41 @@ -local aspawn = require("awful.spawn") -local capi = { - awesome = awesome, -} +local aspawn = require('awful.spawn') +local gobject = require('gears.object') +local gtable = require('gears.table') local backlight = {} -backlight.device = "" +local instance = nil -backlight.max_brightness = 1 - --- Init the backlight device and get the max brightness -aspawn.easy_async_with_shell("ls /sys/class/backlight/", function(stdout) - backlight.device = stdout:gsub("%s+", "") - aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/max_brightness", function(stdout) - backlight.max_brightness = tonumber(stdout:gsub("\n", "") or 0) - end) -end) - - -function backlight.brightness_get() - aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout) - capi.awesome.emit_signal("brightness::get", tonumber(stdout)) +function backlight.brightness_get_async(callback) + aspawn.easy_async_with_shell('brightnessctl get', function(stdout) + callback(tonumber(stdout:gsub('\n', ''))) end) end -function backlight.brightness_get_percent() - aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout) - capi.awesome.emit_signal("brightness::get_percent", - math.floor((tonumber(stdout) / backlight.max_brightness * 100) + 0.5)) +function backlight:brightness_increase() + aspawn('brightnessctl set +2%') + self:emit_signal('brightness_changed') +end + +function backlight:brightness_decrease() + aspawn('brightnessctl set -2%') + self:emit_signal('brightness_changed') +end + +local function new() + local self = gobject {} + + gtable.crush(self, backlight, true) + + -- Init the backlight device and get the max brightness + aspawn.easy_async_with_shell('brightnessctl max', function(stdout) + self.max_brightness = tonumber(stdout:gsub('\n', '') or 1) end) + + return self end -function backlight.brightness_set(value) - if value < 0 or value > (backlight.max_brightness or 24000) then return end - aspawn.with_shell("echo " .. math.floor(value) .. " > /sys/class/backlight/" .. backlight.device .. "/brightness") +if not instance then + instance = new() end - -function backlight.brightness_increase() - aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout) - local new_value = tonumber(stdout:gsub("\n", "") or 0) + - (backlight.max_brightness / 100 * User_config.brightness_step) - backlight.brightness_set(new_value) - capi.awesome.emit_signal("brightness::changed", new_value) - end) -end - -function backlight.brightness_decrease() - aspawn.easy_async_with_shell("cat /sys/class/backlight/" .. backlight.device .. "/brightness", function(stdout) - local new_value = tonumber(stdout:gsub("\n", "") or 0) - - (backlight.max_brightness / 100 * User_config.brightness_step) - backlight.brightness_set(new_value) - capi.awesome.emit_signal("brightness::changed", new_value) - end) -end - -return backlight +return instance diff --git a/awesome/src/tools/helpers/cpu_freq.lua b/awesome/src/tools/helpers/cpu_freq.lua index e96baaa..eba8e0b 100644 --- a/awesome/src/tools/helpers/cpu_freq.lua +++ b/awesome/src/tools/helpers/cpu_freq.lua @@ -1,30 +1,34 @@ -local awful = require("awful") -local watch = awful.widget.watch +local gobject = require('gears.object') +local watch = require('awful.widget.watch') -local capi = { - awesome = awesome, -} +local instance = nil -watch( - [[ bash -c "cat /proc/cpuinfo | grep "MHz" | awk '{print int($4)}'" ]], - 3, - function(_, stdout) +local function new() + local self = gobject {} + + watch("bash -c \"cat /proc/cpuinfo | grep 'MHz' | awk '{print int($4)}'\"", 2, function(_, stdout) local cpu_freq = {} - for value in stdout:gmatch("%d+") do + for value in stdout:gmatch('%d+') do table.insert(cpu_freq, value) end local average = 0 - - if User_config.clock_mode == "average" then + if User_config.clock_mode == 'average' then for i = 1, #cpu_freq do average = average + cpu_freq[i] end - average = math.floor(average / #cpu_freq) - capi.awesome.emit_signal("update::cpu_freq_average", average) + average = math.floor((average / #cpu_freq) + 0.5) + self:emit_signal('update::cpu_freq_average', average) elseif User_config.clock_mode then - capi.awesome.emit_signal("update::cpu_freq_core", cpu_freq[User_config.clock_mode]) + self:emit_signal('update::cpu_freq_core', cpu_freq[User_config.clock_mode]) end - end -) + end) + + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/cpu_temp.lua b/awesome/src/tools/helpers/cpu_temp.lua index 1ef97c5..f212767 100644 --- a/awesome/src/tools/helpers/cpu_temp.lua +++ b/awesome/src/tools/helpers/cpu_temp.lua @@ -1,32 +1,29 @@ -local awful = require("awful") -local watch = awful.widget.watch +local aspawn = require('awful.spawn') +local awatch = require('awful.widget.watch') +local gobject = require('gears.object') -local capi = { - awesome = awesome, -} +local instance = nil -watch( - [[ bash -c "sensors | grep 'Package id 0:' | awk '{print $4}'" ]], - 3, - function(_, stdout) - local temp = tonumber(stdout:match("%d+")) - if not temp or temp == "" then - awful.spawn.easy_async_with_shell( - "paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp)", - function(stdout2) - if (not stdout2) or stdout:match("\n") then return end - temp = math.floor((tonumber(stdout2:match("x86_pkg_temp(.%d+)")) / 1000) + 0.5) - capi.awesome.emit_signal( - "update::cpu_temp", - temp - ) - end - ) +local function new() + local self = gobject {} + + awatch([[ bash -c "sensors | grep 'Package id 0:' | awk '{print $4}'" ]], 2, function(_, stdout) + local temp = tonumber(stdout:match('%d+')) + if not temp or temp == '' then + aspawn.easy_async_with_shell('paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp)', function(stdout2) + if (not stdout2) or stdout:match('\n') then return end + temp = math.floor((tonumber(stdout2:match('x86_pkg_temp(.%d+)')) / 1000) + 0.5) + self:emit_signal('update::cpu_temp', temp) + end) else - capi.awesome.emit_signal( - "update::cpu_temp", - temp - ) + self:emit_signal('update::cpu_temp', temp) end - end -) + end) + + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/cpu_usage.lua b/awesome/src/tools/helpers/cpu_usage.lua index b13dee5..ab7e89a 100644 --- a/awesome/src/tools/helpers/cpu_usage.lua +++ b/awesome/src/tools/helpers/cpu_usage.lua @@ -1,32 +1,43 @@ -local awful = require("awful") -local watch = awful.widget.watch +local aspawn = require('awful.spawn') +local gobject = require('gears.object') +local gtimer = require('gears.timer') -local capi = { - awesome = awesome, -} - -local total_prev = 0 -local idle_prev = 0 +local instance = nil --!Find a better way that doesn't need manual GC since it has a huge performance impact -watch( - [[ cat "/proc/stat" | grep '^cpu ' ]], - 3, - function(_, stdout) - local user, nice, system, idle, iowait, irq, softirq, steal = - stdout:match("(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s") +local function new() - local total = user + nice + system + idle + iowait + irq + softirq + steal + local self = gobject {} - local diff_idle = idle - idle_prev - local diff_total = total - total_prev - local diff_usage = math.floor(((1000 * (diff_total - diff_idle) / diff_total + 5) / 10) + 0.5) + local total_prev = 0 + local idle_prev = 0 - capi.awesome.emit_signal("update::cpu_usage", diff_usage) + gtimer { + timeout = 2, + autostart = true, + call_now = true, + callback = function() + aspawn.easy_async_with_shell([[ cat "/proc/stat" | grep '^cpu ' ]], function(stdout) + local user, nice, system, idle, iowait, irq, softirq, steal = + stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s') - total_prev = total - idle_prev = idle + local total = user + nice + system + idle + iowait + irq + softirq + steal - collectgarbage("collect") - end -) + local diff_total = total - total_prev + local diff_usage = math.floor(((1000 * (diff_total - (idle - idle_prev)) / diff_total + 5) / 10) + 0.5) + + self:emit_signal('update::cpu_usage', diff_usage) + + total_prev = total + idle_prev = idle + end) + end + } + + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/gpu_temp.lua b/awesome/src/tools/helpers/gpu_temp.lua index 0fe45be..e3e9339 100644 --- a/awesome/src/tools/helpers/gpu_temp.lua +++ b/awesome/src/tools/helpers/gpu_temp.lua @@ -1,15 +1,19 @@ -local awful = require("awful") -local watch = awful.widget.watch +local awatch = require('awful.widget.watch') +local gobject = require('gears.object') -local capi = { - awesome = awesome, -} +local instance = nil -watch( - [[ bash -c "nvidia-smi -q -d TEMPERATURE | grep 'GPU Current Temp' | awk '{print $5}'"]], - 3, - function(_, stdout) - if not stdout:gsub("\n", "") then return end - capi.awesome.emit_signal("update::gpu_temp", stdout:match("%d+"):gsub("\n", "")) - end -) +local function new() + local self = gobject {} + awatch([[ bash -c "nvidia-smi -q -d TEMPERATURE | grep 'GPU Current Temp' | awk '{print $5}' | head -n 1"]], 3, function(_, stdout) + stdout = stdout:match('%d+') + if not stdout then return end + self:emit_signal('update::gpu_temp', stdout) + end) + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/gpu_usage.lua b/awesome/src/tools/helpers/gpu_usage.lua index c019bad..b9718cc 100644 --- a/awesome/src/tools/helpers/gpu_usage.lua +++ b/awesome/src/tools/helpers/gpu_usage.lua @@ -1,16 +1,19 @@ -local awful = require("awful") -local watch = awful.widget.watch +local awatch = require('awful.widget.watch') +local gobject = require('gears.object') -local capi = { - awesome = awesome, -} +local instance -watch( - [[ bash -c "nvidia-smi -q -d UTILIZATION | grep Gpu | awk '{print $3}'"]], - 3, - function(_, stdout) - stdout = stdout:match("%d+") +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 - capi.awesome.emit_signal("update::gpu_usage", stdout) - end -) + self:emit_signal('update::gpu_usage', stdout) + end) + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/kb_helper.lua b/awesome/src/tools/helpers/kb_helper.lua new file mode 100644 index 0000000..81481ae --- /dev/null +++ b/awesome/src/tools/helpers/kb_helper.lua @@ -0,0 +1,48 @@ +-- Awesome libs +local gobject = require('gears.object') +local gtable = require('gears.table') +local aspawn = require('awful.spawn') + +local instance = nil +local kb_helper = {} + +function kb_helper:cycle_layout() + self:get_layout_async(function(layout) + local index = gtable.hasitem(self.layout_list, layout) + if index then + if index == #self.layout_list then + self:set_layout(self.layout_list[1]) + else + self:set_layout(self.layout_list[index + 1]) + end + else + self:set_layout(self.layout_list[1]) + end + end) +end + +function kb_helper:set_layout(keymap) + aspawn('setxkbmap ' .. keymap) + self:emit_signal('KB::layout_changed', keymap) +end + +function kb_helper:get_layout_async(callback) + aspawn.easy_async_with_shell([[ setxkbmap -query | grep layout | awk '{print $2}' ]], function(stdout) + callback(stdout:gsub('\n', '')) + end) +end + +local function new() + local self = gobject {} + + gtable.crush(self, kb_helper, true) + + self.layout_list = User_config.kblayout + + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/helpers/playerctl.lua b/awesome/src/tools/helpers/playerctl.lua index adc4291..466a28d 100644 --- a/awesome/src/tools/helpers/playerctl.lua +++ b/awesome/src/tools/helpers/playerctl.lua @@ -1,349 +1,213 @@ --- 99.9% Stolen from bling +local Playerctl = require('lgi').Playerctl +local http_request = require('http.request') +local Cairo = require('lgi').cairo +local Gdk = require('lgi').Gdk +local GdkPixbuf = require('lgi').GdkPixbuf +local gfilesystem = require('gears.filesystem') +local gtimer = require('gears.timer') +local gcolor = require('gears.color') +local gtable = require('gears.table') -local gobject = require("gears.object") -local gtable = require("gears.table") -local gtimer = require("gears.timer") -local gstring = require("gears.string") +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/notifications/' -local capi = { - awesome = awesome +Gdk.init {} + +local instance = nil + +local music_player = {} + +--#region Audio control mappings + +function music_player:next() self.player:next() end + +function music_player:prev() self.player:previous() end + +function music_player:play_pause() self.player:play_pause() end + +function music_player:play() self.player:play() end + +function music_player:pause() self.player:pause() end + +--TODO: Needs validation +function music_player:get_length() + local length = self.player:print_metadata_prop('mpris:length') or 0 + return tonumber(length) / 1000000 +end + +function music_player:set_shuffle() + self.player:set_shuffle(not self.player.shuffle) +end + +-- None, Track, Playlist, loops trough them if not specified +function music_player:set_loop_status(state) + if state then + self.player:set_loop_status(state) + return + end + if self.player.loop_status == 'NONE' then + self.player:set_loop_status('PLAYLIST') + elseif self.player.loop_status == 'PLAYLIST' then + self.player:set_loop_status('TRACK') + elseif self.player.loop_status == 'TRACK' then + self.player:set_loop_status('NONE') + end +end + +--#endregion + +--#region Metadata getter and setter + +function music_player:get_artist() return self.player:get_artist() end + +function music_player:get_title() return self.player:get_title() end + +function music_player:get_album() return self.player:get_album() end + +function music_player:get_position() return (self.player:get_position() / 1000000) end + +function music_player:set_position() return self.player:set_position() end + +function music_player:get_art(url) + url = url or self.player:print_metadata_prop('mpris:artUrl') + if url and url:match('^https?://') then + local scheme = http_request.new_from_uri(url) + if not scheme then return end + local headers, stream = assert(scheme:go()) + if not (stream or headers) then return end + local body = assert(stream:get_body_as_string()) + if headers:get ':status' ~= '200' then + error(body) + end + local loader = GdkPixbuf.PixbufLoader() + loader:write(body) + loader:close() + + local image = loader:get_pixbuf() + + local surface = Cairo.ImageSurface.create(Cairo.Format.ARGB32, image:get_width(), image:get_height()) + local cr = Cairo.Context(surface) + + -- Render the image onto the surface + Gdk.cairo_set_source_pixbuf(cr, image, 0, 0) + cr:paint() + + body = nil + loader = nil + image = nil + collectgarbage() + + return surface + elseif url and url:match('^file://') then + return url:gsub('%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end):gsub('^file://', '') + end + return icondir .. 'default_image.svg' +end + +--#endregion + +local priority_players = { + 'vlc', + 'spotify', } -local playerctl = { mt = {} } -playerctl._private = {} +function music_player:player_gets_priority(name) + -- If for some reason there is no player, manage the new one + if not name then return true end -function playerctl:play_pause(player) - player = player or self._private.manager.players[1] - if player then - player:play_pause() + for _, n in ipairs(priority_players) do + if name.name:lower():match(n) then return true end end + + -- If the currently managed player is playing, don't change it + if self.player.playback_status == 'PLAYING' then return false end + return true end -function playerctl:next(player) - player = player or self._private.manager.players[1] - if player then - player:next() - end -end +local function start_manage(self, w, name) -function playerctl:previous(player) - player = player or self._private.manager.players[1] - if player then - player:previous() - end -end + if not self:player_gets_priority(name) then return end + self.player = Playerctl.Player.new_from_name(name) -function playerctl:cycle_loop(player) - player = player or self._private.manager.players[1] - if player then - local loop_status = player.loop_status - if loop_status == "NONE" then - player:set_loop_status("TRACK") - elseif loop_status == "TRACK" then - player:set_loop_status("PLAYLIST") - elseif loop_status == "PLAYLIST" then - player:set_loop_status("NONE") - end - end -end + self.playermanager:manage_player(self.player) -function playerctl:cycle_shuffle(player) - player = player or self._private.manager.players[1] - if player then - player:set_shuffle(not player.shuffle) - end -end + if not self.player.player_name then return end -function playerctl:set_position(position, player) - player = player or self._private.manager.players[1] - if player then - player:set_position(position * 1000000) - end -end - -function playerctl:get_manager() - return self._private.manager -end - -function playerctl:get_current_player() - return self._private.manager.players[1].name -end - -local function emit_metadata_callback(self, title, artist, art_url, album, new, player_name) - title = gstring.xml_escape(title) - artist = gstring.xml_escape(artist) - album = gstring.xml_escape(album) - - if player_name == "spotify" then - art_url = art_url:gsub("open.spotify.com", "i.scdn.co") + local function on_metadata(_, metadata) + if not metadata then return end + w:get_children_by_id('title')[1].text = metadata.value['xesam:title'] or 'Unknown Title' + w:get_children_by_id('artist')[1].text = metadata.value['xesam:artist'] and metadata.value['xesam:artist'][1] or 'Unknown Artist' + local length = (metadata.value['mpris:length'] or 0) / 1000000 + w:get_children_by_id('length')[1].text = string.format('%02d:%02d', math.floor(length / 60), math.floor(length % 60)) + w:get_children_by_id('progress')[1].max_value = length + w:get_children_by_id('album_art')[1].image = self:get_art(metadata.value['mpris:artUrl']) + self.gtimer = gtimer { + timeout = 1, + autostart = true, + callback = function() + local position = self:get_position() + w:get_children_by_id('position')[1].text = string.format('%02d:%02d', math.floor(position / 60), math.floor(position % 60)) + w:get_children_by_id('progress')[1].value = position + end, + } end - if not art_url or art_url == "" then - else - capi.awesome.emit_signal("playerctl::title_artist_album", title, artist, "", player_name) - self:emit_signal("metadata", title, artist, "", album, new, player_name) - end -end + self.player.on_metadata = on_metadata + on_metadata(nil, self.player.metadata) -local function metadata_callback(self, player, metadata) - if self.update_on_activity then - self._private.manager:mover_player_to_front(player) - end - - local data = metadata.value - local title = data["xesam:title"] or "" - local artist = data["xesam:artist"] or "" - for i = 2, #data["xesam:artist"] do - artist = artist .. ", " .. data["xesam:artist"][i] - end - local art_url = data["mpris:artUrl"] or "" - local album = data["xesam:album"] or "" - - if player == self._private.manager.players[1] then - if (not player == self._private.last_player) or (not title == self._private.manager.last_title) or - (not artist == self._private.manager.last_artist) or (not art_url == self._private.manager.last_art_url) then - if (title == "") and (artist == "") and (art_url == "") then return end - - if (not self._private.metadata_timer) and self._private.metadata_timer.started then - self._private.metadata_timer:stop() - end - - self._private.metadata_timer = gtimer { - timeout = 1, - autostart = true, - single_shot = true, - callback = function() - emit_metadata_callback(self, title, artist, art_url, album, true, player.name) - end - } - - self._private.manager.pos_timer:again() - self._private.manager.last_title = title - self._private.manager.last_artist = artist - self._private.manager.last_art_url = art_url - self._private.last_player = player - end - end -end - -local function pos_callback(self) - local player = self._private.manager.players[1] - if player then - local pos = player:get_position() / 1000000 - local dur = (player.metadata.value["mpris:length"] or 0) / 1000000 - if (not pos == self._private.last_pos) or (not dur == self._private.last_length) then - self._private.pos = pos - self._private.dur = dur - self:emit_signal("position", pos, dur, player.player_name) - end - end -end - -local function playback_status_callback(self, player, status) - if self.update_on_activity then - self._private.manager:mover_player_to_front(player) - end - - if player == self._private.manager.players[1] then - self._private.active_player = player - - if status == "PLAYING" then - self:emit_signal("playerctl::playback_status", true, player.player_name) - capi.awesome.emit_signal("playerctl::playback_status", true, player.player_name) + local function on_loop_status(_, status) + if status == 'TRACK' then + w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat-once.svg', + Theme_config.notification_center.song_info.repeat_all) + elseif status == 'PLAYLIST' then + w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat.svg', + Theme_config.notification_center.song_info.repeat_all) else - self:emit_signal("playerctl::playback_status", false, player.player_name) - capi.awesome.emit_signal("playerctl::playback_status", false, player.player_name) + w:get_children_by_id('repeat')[1].image = gcolor.recolor_image(icondir .. 'repeat.svg', + Theme_config.notification_center.song_info.repeat_disabled) end end + + self.player.on_loop_status = on_loop_status + on_loop_status(nil, self.player.loop_status) + + local function on_shuffle(_, status) + if status then + w:get_children_by_id('shuffle')[1].image = gcolor.recolor_image(icondir .. 'shuffle.svg', + Theme_config.notification_center.song_info.shuffle_enabled) + else + w:get_children_by_id('shuffle')[1].image = gcolor.recolor_image(icondir .. 'shuffle.svg', + Theme_config.notification_center.song_info.shuffle_disabled) + end + end + + self.player.on_shuffle = on_shuffle + on_shuffle(nil, self.player.shuffle) end -local function loop_callback(self, player, loop_status) - if self.update_on_activity then - self._private.manager:mover_player_to_front(player) - end +if not instance then + instance = setmetatable(music_player, { __call = function(_, w) + if not w then return end - if player == self._private.manager.players[1] then - self._private.active_player = player - self:emit_signal("loop_status", loop_status, player.player_name) - end + local ret = {} + gtable.crush(ret, music_player) + + ret.playermanager = Playerctl.PlayerManager() + ret.player = Playerctl.Player() + + if ret.player.player_name then + start_manage(ret, w, Playerctl:list_players()[1]) + end + + ret.playermanager.on_name_appeared = function(_, name) + start_manage(ret, w, name) + end + + ret.playermanager.on_name_vanished = function() + start_manage(ret, w, Playerctl:list_players()[1]) + end + + return ret + end, }) end - -local function shuffle_callback(self, player, shuffle) - if self.update_on_activity then - self._private.manager:mover_player_to_front(player) - end - - if player == self._private.manager.players[1] then - self._private.active_player = player - self:emit_signal("shuffle", shuffle, player.player_name) - end -end - -local function exit_callback(self, player) - if player == self._private.manager.players[1] then - self:emit_signal("playerctl::exit", player.player_name) - end -end - -local function name_is_selected(self, name) - if self.ignore[name.name] then - return false - end - if self.priority > 0 then - for _, arg in pairs(self.priority) do - if arg == name.name or arg == "%any" then - return true - end - end - return false - end -end - -local function init_player(self, name) - if name_is_selected(self, name) then - local player = self._private.Playerctl.Player.new_from_name(name) - self._private.manager:manage_player(player) - player.on_metadata = function(p, m) - metadata_callback(self, p, m) - end - player.on_playback_status = function(p, s) - playback_status_callback(self, p, s) - end - player.on_loop_status = function(p, s) - loop_callback(self, p, s) - end - player.on_shuffle = function(p, s) - shuffle_callback(self, p, s) - end - player.on_exit = function(p) - exit_callback(self, p) - end - - if not self._private.pos_timer.started then - self._private.pos_timer:start() - end - end -end - -local function player_compare(self, a, b) - local player_a = self._private.Playerctl.Player(a) - local player_b = self._private.Playerctl.Player(b) - local i = math.huge - local ai = nil - local bi = nil - - if player_a == player_b then - return 0 - end - - for index, name in ipairs(self.priority) do - if name == "%any" then - i = (i == math.huge) and index or i - elseif name == player_a.player_name then - ai = ai or index - elseif name == player_b.player_name then - bi = bi or index - end - end - - if not ai and not bi then - return 0 - elseif not ai then - return (bi < i) and 1 or -1 - elseif not bi then - return (ai < i) and -1 or 1 - elseif ai == bi then - return 0 - else - return (ai < bi) and -1 or 1 - end -end - -local function get_current_player(self, player) - local title = player:get_title() or "Unknown" - local artist = player:get_artist() or "Unknown" - local album = player:get_album() or "Unknown" - local art_url = player:print_metadata_prop("mpris:artUtl") or "" - - emit_metadata_callback(self, title, artist, art_url, album, false, player.player_name) - playback_status_callback(self, player, player.playback_status) - loop_callback(self, player, player.loop_status) -end - -local function start_manager(self) - self._private.manager = self.private.Playerctl.PlayerManager() - - if #self.priority > 0 then - self._private.manager:set_sort_func(function(a, b) - return player_compare(self, a, b) - end) - end - - self._private.pos_timer = gtimer { - timeout = 1, - callback = function() - pos_callback(self) - end - } - - for _, name in ipairs(self._private.manager.player_names) do - init_player(self, name) - end - - if self._private.manager.players[1] then - get_current_player(self, self._private.manager.players[1]) - end - - local _self = self - - function self._private.manager:on_name_appeared(name) - init_player(_self, name) - end - - function self._private.manager:on_player_appeared(player) - if player == self.players[1] then - _self._private.active_player = player - end - end - - function self._private.manager:on_player_vanished(player) - if #self.players == 0 then - _self._private.metadata_timer:stop() - _self._private.pos_timer:stop() - _self:emit_signal("playerctl::noplayers") - capi.awesome.emit_signal("playerctl::noplayers") - elseif player == _self._private.active_player then - _self._private.active_player = self.players[1] - get_current_player(_self, _self._private.active_player) - end - end -end - -function playerctl.new(args) - args = args or {} - - local ret = gobject {} - gtable.crush(ret, playerctl, true) - - ret.update_on_activity = true - ret.interval = 1 - - - ret._private = {} - - ret._private.Playerctl = require("lgi").Playerctl - ret._private.manager = nil - - gtimer.delayed_call(function() - start_manager(ret) - end) - - return ret -end - -function playerctl.mt:__call(...) - return playerctl.new(...) -end - -return setmetatable(playerctl, playerctl.mt) +return instance diff --git a/awesome/src/tools/helpers/pulseaudio.lua b/awesome/src/tools/helpers/pulseaudio.lua new file mode 100644 index 0000000..6b95013 --- /dev/null +++ b/awesome/src/tools/helpers/pulseaudio.lua @@ -0,0 +1,35 @@ +package.cpath = package.cpath .. ';./?.so' + +local gobject = require('gears.object') +local gtable = require('gears.table') + +local pulseaudio = require('lua_libpulse_glib') + +local p = {} + +function p.new() + local ret = gobject {} + ret._private = {} + + gtable.crush(ret, p, true) + + local pa = pulseaudio.new() + + local ctx = pa:context('My Test App') + + if not ctx then return end + + ctx:connect(nil, function(state) + if state == 4 then + print('Connection is ready') + + ctx:get_sinks(function(sinks) + print(sinks) + end) + end + end) + + return ret +end + +return setmetatable(p, { __call = function(_, ...) return p.new() end }) diff --git a/awesome/src/tools/helpers/ram.lua b/awesome/src/tools/helpers/ram.lua index 12b0267..335058d 100644 --- a/awesome/src/tools/helpers/ram.lua +++ b/awesome/src/tools/helpers/ram.lua @@ -1,15 +1,18 @@ -local awful = require("awful") -local watch = awful.widget.watch +local awatch = require('awful.widget.watch') +local gobject = require('gears.object') -local capi = { - awesome = awesome, -} +local instance = nil -watch( - [[ bash -c "cat /proc/meminfo| grep Mem | awk '{print $2}'" ]], - 3, - function(_, stdout) - local MemTotal, MemFree, MemAvailable = stdout:match("(%d+)\n(%d+)\n(%d+)\n") - capi.awesome.emit_signal("update::ram_widget", MemTotal, MemFree, MemAvailable) - end -) +local function new() + local self = gobject {} + awatch([[ bash -c "cat /proc/meminfo| grep Mem | awk '{print $2}'" ]], 3, function(_, stdout) + local MemTotal, MemFree, MemAvailable = stdout:match('(%d+)\n(%d+)\n(%d+)\n') + self:emit_signal('update::ram_widget', MemTotal, MemFree, MemAvailable) + end) + return self +end + +if not instance then + instance = new() +end +return instance diff --git a/awesome/src/tools/hover.lua b/awesome/src/tools/hover.lua new file mode 100644 index 0000000..6327bbb --- /dev/null +++ b/awesome/src/tools/hover.lua @@ -0,0 +1,319 @@ +local gcolor = require('gears.color') + +local rubato = require('src.lib.rubato') + +local capi = { + mouse = mouse, +} + +local function hex_to_rgba(hex) + return tonumber(hex:sub(2, 3), 16) / 255, + tonumber(hex:sub(4, 5), 16) / 255, + tonumber(hex:sub(6, 7), 16) / 255, + ((tonumber(hex:sub(8, 9), 16) or 255) / 255) +end + +local function rgba_to_hex(r, g, b, a) + return string.format('%02x%02x%02x%02x', r * 255, g * 255, b * 255, a * 255) +end + +local function overlay_color(col, overlay, opacity) + if tonumber(col:sub(1, 2), 16) < 128 and tonumber(col:sub(3, 4), 16) < 128 and tonumber(col:sub(5, 6), 16) < 128 then + overlay = 'ffffff' + else + overlay = '000000' + end + return math.floor((tonumber(overlay:sub(1, 2), 16) * opacity / 100) + tonumber(col:sub(1, 2), 16) * (1 - opacity / 100)), + math.floor((tonumber(overlay:sub(3, 4), 16) * opacity / 100) + tonumber(col:sub(3, 4), 16) * (1 - opacity / 100)), + math.floor((tonumber(overlay:sub(5, 6), 16) * opacity / 100) + tonumber(col:sub(5, 6), 16) * (1 - opacity / 100)), + math.floor((tonumber(overlay:sub(7, 8), 16) or 255 * opacity / 100) + tonumber(col:sub(7, 8), 16) * (1 - opacity / 100)) +end + +local function bg_hover(args) + --[[ args = args or {} + local old_cursor, old_wibox + + local _, r, g, b, a = args.widget.bg:get_rgba() + + local animation = { + r = rubato.timed { + duration = 0.3 or args.duration, + easing = rubato.easing.linear, + pos = r * 255, + rate = 24, + clamp_position = true, + }, + g = rubato.timed { + duration = 0.3 or args.duration, + easing = rubato.easing.linear, + pos = g * 255, + rate = 24, + clamp_position = true, + }, + b = rubato.timed { + duration = 0.3 or args.duration, + easing = rubato.easing.linear, + pos = b * 255, + rate = 24, + clamp_position = true, + }, + a = rubato.timed { + duration = 0.3 or args.duration, + easing = rubato.easing.linear, + pos = a * 255, + rate = 24, + clamp_position = true, + }, + } + + local function set_bg() + args.widget._private.background = gcolor(string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5))) + args.widget:emit_signal('widget::redraw_needed') + end + + animation.r:subscribe(set_bg) + animation.g:subscribe(set_bg) + animation.b:subscribe(set_bg) + animation.a:subscribe(set_bg) + + args.widget:connect_signal('mouse::enter', function() + if animation.r.running or animation.g.running or animation.b.running or animation.a.running then + args.widget._private.background = gcolor(string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5), + math.floor(animation.a.target + 0.5))) + args.widget:emit_signal('widget::redraw_needed') + end + _, r, g, b, a = args.widget.bg:get_rgba() + animation.r.pos = r * 255 + animation.g.pos = g * 255 + animation.b.pos = b * 255 + animation.a.pos = a * 255 + + local w = capi.mouse.current_wibox + + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' or args.cursor + end + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4) + end) + + args.widget:connect_signal('mouse::leave', function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = r * 255, g * 255, b * 255, a * 255 + end) + + args.widget:connect_signal('button::press', function() + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.press_overlay or 12) + end) + + args.widget:connect_signal('button::release', function() + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4) + end) + + args.widget:connect_signal('property::bg', function(_, newbg) + r, g, b, a = hex_to_rgba(newbg) + end) ]] +end + +--[[ local function fg_hover(args) + args = args or {} + local old_cursor, old_wibox + + local _, r, g, b, a = args.widget.fg:get_rgba() + + local animation = { + r = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = r * 255, + rate = 24, + clamp_position = true, + }, + g = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = g * 255, + rate = 24, + clamp_position = true, + }, + b = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = b * 255, + rate = 24, + clamp_position = true, + }, + a = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = a * 255, + rate = 24, + clamp_position = true, + }, + } + + local function set_fg() + args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5))) + end + + animation.r:subscribe(set_fg) + animation.g:subscribe(set_fg) + animation.b:subscribe(set_fg) + animation.a:subscribe(set_fg) + + args.widget:connect_signal('mouse::enter', function() + if animation.r.running or animation.g.running or animation.b.running or animation.a.running then + args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5), math.floor(animation.a.target + 0.5))) + end + _, r, g, b, a = args.widget.fg:get_rgba() + animation.r.pos = r * 255 + animation.g.pos = g * 255 + animation.b.pos = b * 255 + animation.a.pos = a * 255 + + local w = capi.mouse.current_wibox + + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' or args.cursor + end + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4) + end) + args.widget:connect_signal('mouse::leave', function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + + animation.r.target = r * 255 + animation.g.target = g * 255 + animation.b.target = b * 255 + animation.a.target = a * 255 + end) + args.widget:connect_signal('button::press', function() + _, r, g, b, a = args.widget.fg:get_rgba() + + args.widget:set_fg(string.format('#%02x%02x%02x%02x', math.floor(r + 0.5), math.floor(g + 0.5), math.floor(b + 0.5), math.floor(a + 0.5))) + + animation.r.pos = r * 255 + animation.g.pos = g * 255 + animation.b.pos = b * 255 + animation.a.pos = a * 255 + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 12) + end) + args.widget:connect_signal('button::release', function() + animation.r.target = r * 255 + animation.g.target = g * 255 + animation.b.target = b * 255 + animation.a.target = a * 255 + end) +end ]] + +--[[ local function border_hover(args) + args = args or {} + local old_cursor, old_wibox + + local r, g, b, a = hex_to_rgba(args.widget.border_color) + + local animation = { + r = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = r * 255, + rate = 24, + clamp_position = true, + }, + g = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = g * 255, + rate = 24, + clamp_position = true, + }, + b = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = b * 255, + rate = 24, + clamp_position = true, + }, + a = rubato.timed { + duration = 0.2 or args.duration, + easing = rubato.easing.linear, + pos = a * 255, + rate = 24, + clamp_position = true, + }, + } + + local function set_border() + args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(animation.r.pos + 0.5), math.floor(animation.g.pos + 0.5), math.floor(animation.b.pos + 0.5), math.floor(animation.a.pos + 0.5)) + end + + animation.r:subscribe(set_border) + animation.g:subscribe(set_border) + animation.b:subscribe(set_border) + animation.a:subscribe(set_border) + + args.widget:connect_signal('mouse::enter', function() + if animation.r.running or animation.g.running or animation.b.running or animation.a.running then + args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(animation.r.target + 0.5), math.floor(animation.g.target + 0.5), math.floor(animation.b.target + 0.5), math.floor(animation.a.target + 0.5)) + end + r, g, b, a = hex_to_rgba(args.widget.border_color) + animation.r.pos = r * 255 + animation.g.pos = g * 255 + animation.b.pos = b * 255 + animation.a.pos = a * 255 + + local w = capi.mouse.current_wibox + + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' or args.cursor + end + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 4) + end) + args.widget:connect_signal('mouse::leave', function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + + animation.r.target = r * 255 + animation.g.target = g * 255 + animation.b.target = b * 255 + animation.a.target = a * 255 + end) + args.widget:connect_signal('button::press', function() + r, g, b, a = hex_to_rgba(args.widget.border_color) + + args.widget.border_color = string.format('#%02x%02x%02x%02x', math.floor(r + 0.5), math.floor(g + 0.5), math.floor(b + 0.5), math.floor(a + 0.5)) + + animation.r.pos = r * 255 + animation.g.pos = g * 255 + animation.b.pos = b * 255 + animation.a.pos = a * 255 + + animation.r.target, animation.g.target, animation.b.target, animation.a.target = overlay_color(rgba_to_hex(r, g, b, a), args.overlay_color or 'ffffff', args.overlay or 12) + end) + args.widget:connect_signal('button::release', function() + animation.r.target = r * 255 + animation.g.target = g * 255 + animation.b.target = b * 255 + animation.a.target = a * 255 + end) +end ]] + +return { + bg_hover = bg_hover, + --fg_hover = fg_hover, + --border_hover = border_hover, +} diff --git a/awesome/src/widgets/audio.lua b/awesome/src/widgets/audio.lua index a57de72..c14c29c 100644 --- a/awesome/src/widgets/audio.lua +++ b/awesome/src/widgets/audio.lua @@ -2,98 +2,118 @@ -- This is the audio widget -- ------------------------------ -- Awesome Libs +local abutton = require('awful.button') +local apopup = require('awful.popup') +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 dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +-- Local libs +local audio_controller = require('src.modules.audio.audio_controller') +local audio_helper = require('src.tools.helpers.audio') +local hover = require('src.tools.hover') -require("src.tools.helpers.audio") - -local capi = { - awesome = awesome, -} +local capi = { mouse = mouse } -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/audio/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/audio/' --- Returns the audio widget -return function(s) +return setmetatable({}, { __call = function(_, screen) - local audio_widget = wibox.widget { + local ac_popup = apopup { + widget = audio_controller, + ontop = true, + visible = false, + screen = screen, + border_color = Theme_config.bluetooth_controller.container_border_color, + border_width = Theme_config.bluetooth_controller.container_border_width, + bg = Theme_config.bluetooth_controller.container_bg, + } + + local w = wibox.widget { { { { { - { - id = "icon", - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false - }, - id = "icon_layout", - widget = wibox.container.place + id = 'icon', + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + resize = true, }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" + width = dpi(25), + height = dpi(25), + strategy = 'exact', + widget = wibox.container.constraint, + }, + { + id = 'label', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "audio_layout", - layout = wibox.layout.fixed.horizontal + id = 'audio_layout', + layout = wibox.layout.fixed.horizontal, }, - id = "container", + id = 'container', left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.audio.bg, fg = Theme_config.audio.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background + shape = Theme_config.audio.shape, + widget = wibox.container.background, + buttons = { gtable.join( + abutton({}, 1, function() + local geo = capi.mouse.coords() + ac_popup.y = dpi(65) + ac_popup.x = geo.x - ac_popup.width / 2 + ac_popup.visible = not ac_popup.visible + end) + ), }, } - capi.awesome.connect_signal("audio::get", function(muted, volume) + hover.bg_hover { widget = w } + + local audio_label = w:get_children_by_id('label')[1] + local audio_icon = w:get_children_by_id('icon')[1] + local audio_spacing = w:get_children_by_id('audio_layout')[1] + audio_helper:connect_signal('sink::get', function(_, muted, volume) + volume = tonumber(volume) + assert(type(volume) == 'number' and type(muted) == 'boolean', 'Invalid arguments') + + if w.volume == volume and w.muted == muted then return end + w.volume = volume + w.muted = muted + if muted then - audio_widget.container.audio_layout.label.visible = false - audio_widget.container.audio_layout.icon_margin.icon_layout.icon:set_image( - gears.color.recolor_image(icondir .. "volume-mute" .. ".svg", Theme_config.audio.fg)) + audio_label.visible = false + audio_icon:set_image(gcolor.recolor_image(icondir .. 'volume-mute' .. '.svg', Theme_config.audio.fg)) else - audio_widget.container:set_right(10) - local icon = icondir .. "volume" - audio_widget.container.audio_layout.spacing = dpi(5) - audio_widget.container.audio_layout.label.visible = true - volume = tonumber(volume) - if not volume then - return - end + if not volume then return end + w.container:set_right(10) + audio_spacing.spacing = dpi(5) + audio_label.visible = true + local icon = icondir .. 'volume' if volume < 1 then - icon = icon .. "-mute" - audio_widget.container.audio_layout.spacing = dpi(0) - audio_widget.container.audio_layout.label.visible = false + icon = icon .. '-mute' + audio_spacing.spacing = 0 + audio_label.visible = false elseif volume >= 1 and volume < 34 then - icon = icon .. "-low" + icon = icon .. '-low' elseif volume >= 34 and volume < 67 then - icon = icon .. "-medium" + icon = icon .. '-medium' elseif volume >= 67 then - icon = icon .. "-high" + icon = icon .. '-high' end - audio_widget.container.audio_layout.label:set_text(volume .. "%") - audio_widget.container.audio_layout.icon_margin.icon_layout.icon:set_image( - gears.color.recolor_image(icon .. ".svg", Theme_config.audio.fg)) + audio_label:set_text(volume .. '%') + audio_icon:set_image(gcolor.recolor_image(icon .. '.svg', Theme_config.audio.fg)) end end) - -- Signals - Hover_signal(audio_widget) - - return audio_widget -end + return w +end, }) diff --git a/awesome/src/widgets/battery.lua b/awesome/src/widgets/battery.lua index 0cf947a..ae619af 100644 --- a/awesome/src/widgets/battery.lua +++ b/awesome/src/widgets/battery.lua @@ -3,20 +3,23 @@ -------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local lgi = require("lgi") -local naughty = require("naughty") -local upower_glib = lgi.require("UPowerGlib") -local wibox = require("wibox") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gears = require('gears') +local lgi = require('lgi') +local naughty = require('naughty') +local upower_glib = lgi.require('UPowerGlib') +local wibox = require('wibox') + +-- Local libs +local hover = require('src.tools.hover') local capi = { awesome = awesome, } -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/battery/" +local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/battery/' ---Returns the battery widget ---@return wibox.widget @@ -29,46 +32,46 @@ return function(battery_kind) { { { - id = "icon", - image = gears.color.recolor_image(icondir .. "battery-unknown.svg", Theme_config.battery.fg), + id = 'icon', + image = gears.color.recolor_image(icondir .. 'battery-unknown.svg', Theme_config.battery.fg), widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false + valign = 'center', + halign = 'center', + resize = false, }, - id = "icon_layout", - widget = wibox.container.place + id = 'icon_layout', + widget = wibox.container.place, }, - id = "icon_margin", + id = 'icon_margin', top = dpi(2), - widget = wibox.container.margin + widget = wibox.container.margin, }, spacing = dpi(10), { visible = false, align = 'center', valign = 'center', - id = "label", - widget = wibox.widget.textbox + id = 'label', + widget = wibox.widget.textbox, }, - id = "battery_layout", - layout = wibox.layout.fixed.horizontal + id = 'battery_layout', + layout = wibox.layout.fixed.horizontal, }, - id = "container", + id = 'container', left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.battery.bg, fg = Theme_config.battery.fg, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, dpi(6)) end, - widget = wibox.container.background + widget = wibox.container.background, } -- Color change on mouse over - Hover_signal(battery_widget) + hover.bg_hover { widget = battery_widget } -- Open an energy manager on click battery_widget:connect_signal( @@ -105,9 +108,9 @@ return function(battery_kind) local tooltip = awful.tooltip { objects = { battery_widget }, - mode = "inside", - preferred_alignments = "middle", - margins = dpi(10) + mode = 'inside', + preferred_alignments = 'middle', + margins = dpi(10), } ---Sets the battery information for the widget @@ -125,50 +128,50 @@ return function(battery_kind) battery_time = device.time_to_full end - local battery_string = math.floor(battery_time / 3600) .. "h, " .. math.floor((battery_time / 60) % 60) .. "m" + local battery_string = math.floor(battery_time / 3600) .. 'h, ' .. math.floor((battery_time / 60) % 60) .. 'm' if battery_temp == 0.0 then - battery_temp = "NaN" + battery_temp = 'NaN' else - battery_temp = math.floor(battery_temp + 0.5) .. "°C" + battery_temp = math.floor(battery_temp + 0.5) .. '°C' end if not battery_percentage then return end - battery_widget:get_children_by_id("battery_layout")[1].spacing = dpi(5) - battery_widget:get_children_by_id("label")[1].visible = true - battery_widget:get_children_by_id("label")[1].text = battery_percentage .. '%' + battery_widget:get_children_by_id('battery_layout')[1].spacing = dpi(5) + battery_widget:get_children_by_id('label')[1].visible = true + battery_widget:get_children_by_id('label')[1].text = battery_percentage .. '%' tooltip.markup = "Battery Status: " .. battery_status .. "\nRemaining time: " .. battery_string .. "\nTemperature: " - .. battery_temp .. "" + .. battery_temp .. '' local icon = 'battery' if battery_status == 'fully-charged' or battery_status == 'charging' and battery_percentage == 100 then icon = icon .. '-' .. 'charging.svg' naughty.notification { - title = "Battery notification", - message = "Battery is fully charged", + title = 'Battery notification', + message = 'Battery is fully charged', icon = icondir .. icon, - timeout = 5 + timeout = 5, } - battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir + battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. icon, Theme_config.battery.fg)) return elseif battery_percentage > 0 and battery_percentage < 10 and battery_status == 'discharging' then icon = icon .. '-' .. 'alert.svg' naughty.notification { - title = "Battery warning", - message = "Battery is running low!\n" .. battery_percentage .. "% left", - urgency = "critical", + title = 'Battery warning', + message = 'Battery is running low!\n' .. battery_percentage .. '% left', + urgency = 'critical', icon = icondir .. icon, - timeout = 60 + timeout = 60, } - battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir + battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. icon, Theme_config.battery.fg)) return end @@ -195,9 +198,9 @@ return function(battery_kind) icon = icon .. '-' .. battery_status .. '-' .. '90' end - battery_widget:get_children_by_id("icon")[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. + battery_widget:get_children_by_id('icon')[1].image = gears.surface.load_uncached(gears.color.recolor_image(icondir .. icon .. '.svg', Theme_config.battery.fg)) - capi.awesome.emit_signal("update::battery_widget", battery_percentage, icondir .. icon .. ".svg") + capi.awesome.emit_signal('update::battery_widget', battery_percentage, icondir .. icon .. '.svg') end @@ -208,12 +211,12 @@ return function(battery_kind) ---Will report to the bluetooth widget. ---@param path string device path /org/freedesktop/... local function attach_to_device(path) - local device_path = User_config.battery_path or path or "" + local device_path = User_config.battery_path or path or '' battery_widget.device = get_device_from_path(device_path) or upower_glib.Client():get_display_device() battery_widget.device.on_notify = function(device) - battery_widget:emit_signal("upower::update", device) + battery_widget:emit_signal('upower::update', device) end -- Check which device kind the user wants to display @@ -223,7 +226,7 @@ return function(battery_kind) end -- The delayed call will fire every time awesome finishes its main event loop - gears.timer.delayed_call(battery_widget.emit_signal, battery_widget, "upower::update", battery_widget.device) + gears.timer.delayed_call(battery_widget.emit_signal, battery_widget, 'upower::update', battery_widget.device) end for _, device in ipairs(get_device_path()) do @@ -231,7 +234,7 @@ return function(battery_kind) end battery_widget:connect_signal( - "upower::update", + 'upower::update', function(_, device) if upower_glib.DeviceKind[battery_widget.device.kind] == battery_kind then set_battery(device) diff --git a/awesome/src/widgets/bluetooth.lua b/awesome/src/widgets/bluetooth.lua index f062cb4..cca5a4c 100644 --- a/awesome/src/widgets/bluetooth.lua +++ b/awesome/src/widgets/bluetooth.lua @@ -3,21 +3,22 @@ ---------------------------------- -- Awesome libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local awful = require('awful') +local dpi = require('beautiful').xresources.apply_dpi +local gears = require('gears') +local wibox = require('wibox') -- Own libs -local bt_module = require("src.modules.bluetooth.init") +local bt_module = require('src.modules.bluetooth.init') +local hover = require('src.tools.hover') local capi = { awesome = awesome, - mouse = mouse + mouse = mouse, } -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/" +local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/bluetooth/' -- Returns the bluetooth widget return function(s) @@ -29,29 +30,31 @@ return function(s) { { { - id = "icon", - image = gears.color.recolor_image(icondir .. "bluetooth-off.svg", Theme_config.bluetooth.fg), + id = 'icon', + image = gears.color.recolor_image(icondir .. 'bluetooth-off.svg', Theme_config.bluetooth.fg), widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false + valign = 'center', + halign = 'center', + resize = false, }, - id = "icon_layout", - widget = wibox.container.place + id = 'icon_layout', + widget = wibox.container.place, }, - id = "icon_margin", + id = 'icon_margin', left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.bluetooth.bg, fg = Theme_config.bluetooth.fg, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, dpi(6)) end, - widget = wibox.container.background + widget = wibox.container.background, } + hover.bg_hover { widget = bluetooth_widget } + -- If bt_widget is nil then there is no bluetooth adapter and there shouldn't be done -- anything besides returning the widget without any logic behind if not bt_widget then @@ -67,27 +70,24 @@ return function(s) screen = s, border_color = Theme_config.bluetooth_controller.container_border_color, border_width = Theme_config.bluetooth_controller.container_border_width, - bg = Theme_config.bluetooth_controller.container_bg + bg = Theme_config.bluetooth_controller.container_bg, } -- When the status changes update the icon - bt_widget:connect_signal("bluetooth::status", function(status) - bluetooth_widget:get_children_by_id("icon")[1].image = gears.color.recolor_image(status._private.Adapter1.Powered and - icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg", Theme_config.bluetooth.fg) + bt_widget:connect_signal('bluetooth::status', function(status) + bluetooth_widget:get_children_by_id('icon')[1].image = gears.color.recolor_image(status._private.Adapter1.Powered and + icondir .. 'bluetooth-on.svg' or icondir .. 'bluetooth-off.svg', Theme_config.bluetooth.fg) end) - -- Hover signal to change color when mouse is over - Hover_signal(bluetooth_widget) - -- On left click toggle the bluetooth container else toggle the bluetooth on/off - bluetooth_widget:connect_signal("button::press", function(_, _, _, key) + bluetooth_widget:connect_signal('button::press', function(_, _, _, key) if key == 1 then local geo = capi.mouse.current_wibox:geometry() bluetooth_container.x = geo.x bluetooth_container.y = geo.y + dpi(55) bluetooth_container.visible = not bluetooth_container.visible else - capi.awesome.emit_signal("toggle_bluetooth") + capi.awesome.emit_signal('toggle_bluetooth') end end) diff --git a/awesome/src/widgets/clock.lua b/awesome/src/widgets/clock.lua index ebf92fb..ba76987 100644 --- a/awesome/src/widgets/clock.lua +++ b/awesome/src/widgets/clock.lua @@ -3,62 +3,55 @@ ------------------------------ -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local wibox = require('wibox') + +-- Local libs +local hover = require('src.tools.hover') -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/clock/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/clock/' -- Returns the clock widget -return function() - +return setmetatable({}, { __call = function() local clock_widget = wibox.widget { { { { { - { - id = "icon", - image = gears.color.recolor_image(icondir .. "clock.svg", Theme_config.clock.fg), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false - }, - id = "icon_layout", - widget = wibox.container.place + image = gcolor.recolor_image(icondir .. 'clock.svg', Theme_config.clock.fg), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + resize = true, }, - id = "icon_margin", - top = dpi(2), - widget = wibox.container.margin + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + }, + { + halign = 'center', + valign = 'center', + format = '%H:%M', + widget = wibox.widget.textclock, }, spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - format = "%H:%M", - widget = wibox.widget.textclock - }, - id = "clock_layout", - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - id = "container", left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.clock.bg, fg = Theme_config.clock.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background + shape = Theme_config.clock.shape, + widget = wibox.container.background, } - Hover_signal(clock_widget) + hover.bg_hover { widget = clock_widget } return clock_widget -end +end, }) diff --git a/awesome/src/widgets/cpu_info.lua b/awesome/src/widgets/cpu_info.lua index 32ef7d6..3111610 100644 --- a/awesome/src/widgets/cpu_info.lua +++ b/awesome/src/widgets/cpu_info.lua @@ -3,217 +3,234 @@ --------------------------------- -- Awesome Libs -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local base = require('wibox.widget.base') +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 color = require("src.lib.color") -local rubato = require("src.lib.rubato") +-- Third Party Libs +local color = require('src.lib.color') +local rubato = require('src.lib.rubato') +local hover = require('src.tools.hover') -require("src.tools.helpers.cpu_freq") -require("src.tools.helpers.cpu_temp") -require("src.tools.helpers.cpu_usage") +local icon_dir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/cpu/' -local capi = { - awesome = awesome, -} +local cpu_info = {} -local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/" +local function cpu_temp_new() + local cpu_temp_helper = require('src.tools.helpers.cpu_temp') ---TODO: Add tooltip with more CPU and per core information -return function(widget) - - local cpu_usage_widget = wibox.widget { + local w = base.make_widget_from_value(wibox.widget { { { { { { - id = "icon", + id = 'icon_role', widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icon_dir .. "cpu.svg", Theme_config.cpu_usage.fg), - resize = false + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'thermometer.svg', Theme_config.cpu_temp.fg), + resize = true, }, - id = "icon_layout", - widget = wibox.container.place + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" - }, - spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "cpu_layout", - layout = wibox.layout.fixed.horizontal - }, - id = "container", - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin - }, - bg = Theme_config.cpu_usage.bg, - fg = Theme_config.cpu_usage.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } - - local cpu_temp = wibox.widget { - { - { - { { - { - id = "icon", - image = gears.color.recolor_image(icon_dir .. "thermometer.svg", Theme_config.cpu_temp.fg), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false - }, - id = "icon_layout", - widget = wibox.container.place + id = 'text_role', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, }, - spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "cpu_layout", - layout = wibox.layout.fixed.horizontal + widget = wibox.container.place, }, - id = "container", - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin + left = dpi(5), + right = dpi(5), + widget = wibox.container.margin, }, - bg = Theme_config.cpu_temp.bg_low, + bg = Theme_config.cpu_temp.bg, fg = Theme_config.cpu_temp.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } + shape = Theme_config.cpu_temp.shape, + widget = wibox.container.background, + }) - local cpu_clock = wibox.widget { - { - { - { - { - { - id = "icon", - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icon_dir .. "cpu.svg", Theme_config.cpu_freq.fg), - resize = false - }, - id = "icon_layout", - widget = wibox.container.place - }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" - }, - spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "cpu_layout", - layout = wibox.layout.fixed.horizontal - }, - id = "container", - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin - }, - bg = Theme_config.cpu_freq.bg, - fg = Theme_config.cpu_freq.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } + assert(w, 'Failed to create widget') - capi.awesome.connect_signal("update::cpu_usage", function(usage) - cpu_usage_widget.container.cpu_layout.label.text = usage .. "%" - end) + gtable.crush(w, cpu_info, true) - local r_timed_cpu_bg = rubato.timed { duration = 2.5 } - local g_timed_cpu_bg = rubato.timed { duration = 2.5 } - local b_timed_cpu_bg = rubato.timed { duration = 2.5 } + local r = rubato.timed { duration = 2.5 } + local g = rubato.timed { duration = 2.5 } + local b = rubato.timed { duration = 2.5 } - r_timed_cpu_bg.pos, g_timed_cpu_bg.pos, b_timed_cpu_bg.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low) + r.pos, g.pos, b.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low) -- Subscribable function to have rubato set the bg/fg color local function update_bg() - cpu_temp:set_bg("#" .. color.utils.rgba_to_hex { r_timed_cpu_bg.pos, g_timed_cpu_bg.pos, b_timed_cpu_bg.pos }) + w:set_bg('#' .. color.utils.rgba_to_hex { r.pos, g.pos, b.pos }) end - r_timed_cpu_bg:subscribe(update_bg) - g_timed_cpu_bg:subscribe(update_bg) - b_timed_cpu_bg:subscribe(update_bg) + r:subscribe(update_bg) + g:subscribe(update_bg) + b:subscribe(update_bg) -- Both functions to set a color, if called they take a new color local function set_bg(newbg) - r_timed_cpu_bg.target, g_timed_cpu_bg.target, b_timed_cpu_bg.target = color.utils.hex_to_rgba(newbg) + r.target, g.target, b.target = color.utils.hex_to_rgba(newbg) end - capi.awesome.connect_signal("update::cpu_temp", function(temp) + cpu_temp_helper:connect_signal('update::cpu_temp', function(_, temp) local temp_icon local temp_color if temp < 50 then temp_color = Theme_config.cpu_temp.bg_low - temp_icon = icon_dir .. "thermometer-low.svg" + temp_icon = icon_dir .. 'thermometer-low.svg' elseif temp >= 50 and temp < 80 then temp_color = Theme_config.cpu_temp.bg_mid - temp_icon = icon_dir .. "thermometer.svg" + temp_icon = icon_dir .. 'thermometer.svg' elseif temp >= 80 then temp_color = Theme_config.cpu_temp.bg_high - temp_icon = icon_dir .. "thermometer-high.svg" + temp_icon = icon_dir .. 'thermometer-high.svg' end - cpu_temp.container.cpu_layout.icon_margin.icon_layout.icon:set_image(temp_icon) + w:get_children_by_id('icon_role')[1].image = temp_icon set_bg(temp_color) - cpu_temp.container.cpu_layout.label.text = math.floor(temp) .. "°C" - capi.awesome.emit_signal("update::cpu_temp_widget", temp, temp_icon) + w:get_children_by_id('text_role')[1].text = math.floor(temp) .. '°C' end) - capi.awesome.connect_signal("update::cpu_freq_average", function(average) - cpu_clock.container.cpu_layout.label.text = average .. "Mhz" - end) - - capi.awesome.connect_signal("update::cpu_freq_core", function(freq) - cpu_clock.container.cpu_layout.label.text = freq .. "Mhz" - end) - - Hover_signal(cpu_temp) - Hover_signal(cpu_usage_widget) - Hover_signal(cpu_clock) - - if widget == "usage" then - return cpu_usage_widget - elseif widget == "temp" then - return cpu_temp - elseif widget == "freq" then - return cpu_clock - end - + return w end + +local function cpu_usage_new() + local cpu_usage_helper = require('src.tools.helpers.cpu_usage') + + local w = base.make_widget_from_value(wibox.widget { + { + { + { + { + { + id = 'icon_role', + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'cpu.svg', Theme_config.cpu_usage.fg), + resize = true, + }, + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + }, + { + id = 'text_role', + text = '0%', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + left = dpi(5), + right = dpi(5), + widget = wibox.container.margin, + }, + bg = Theme_config.cpu_usage.bg, + fg = Theme_config.cpu_usage.fg, + shape = Theme_config.cpu_usage.shape, + widget = wibox.container.background, + }) + + assert(w, 'failed to create widget') + + hover.bg_hover { widget = w } + + gtable.crush(w, cpu_info, true) + + cpu_usage_helper:connect_signal('update::cpu_usage', function(_, usage) + w:get_children_by_id('text_role')[1].text = usage .. '%' + end) + + return w +end + +local function cpu_freq_new() + local cpu_freq_helper = require('src.tools.helpers.cpu_freq') + + local w = base.make_widget_from_value(wibox.widget { + { + { + { + { + { + id = 'icon_role', + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'cpu.svg', Theme_config.cpu_freq.fg), + resize = true, + }, + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + }, + { + id = 'text_role', + text = '0Mhz', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + left = dpi(5), + right = dpi(5), + widget = wibox.container.margin, + }, + bg = Theme_config.cpu_freq.bg, + fg = Theme_config.cpu_freq.fg, + shape = Theme_config.cpu_freq.shape, + widget = wibox.container.background, + }) + + assert(w, 'failed to create widget') + + hover.bg_hover { widget = w } + + gtable.crush(w, cpu_info, true) + + cpu_freq_helper:connect_signal('update::cpu_freq_average', function(_, average) + w:get_children_by_id('text_role')[1].text = average .. 'Mhz' + end) + + cpu_freq_helper:connect_signal('update::cpu_freq_core', function(_, freq) + w:get_children_by_id('text_role')[1].text = freq .. 'Mhz' + end) + + return w +end + +return setmetatable(cpu_info, { __call = function(_, widget) + if widget == 'temp' then + return cpu_temp_new() + elseif widget == 'usage' then + return cpu_usage_new() + elseif widget == 'freq' then + return cpu_freq_new() + else + return nil + end +end, }) diff --git a/awesome/src/widgets/date.lua b/awesome/src/widgets/date.lua index a6265ea..cac37f1 100644 --- a/awesome/src/widgets/date.lua +++ b/awesome/src/widgets/date.lua @@ -3,83 +3,81 @@ ----------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local apopup = require('awful.popup') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local abutton = require('awful.button') +local gfilesystem = require('gears.filesystem') +local gtable = require('gears.table') +local gcolor = require('gears.color') + +-- Local libs +local cal = require('src.modules.calendar.init') {} +local hover = require('src.tools.hover') -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/date/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/date/' + +local capi = { mouse = mouse } -- Returns the date widget -return function(s) - local cal = require("src.modules.calendar.init") { screen = s } - +return setmetatable({}, { __call = function(_, screen) local date_widget = wibox.widget { { { { { - { - id = "icon", - image = gears.color.recolor_image(icondir .. "calendar.svg", Theme_config.date.fg), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false - }, - id = "icon_layout", - widget = wibox.container.place + image = gcolor.recolor_image(icondir .. 'calendar.svg', Theme_config.date.fg), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + resize = true, }, - id = "icon_margin", - top = dpi(2), - widget = wibox.container.margin + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + }, + { + halign = 'center', + valign = 'center', + format = '%a, %b %d', + widget = wibox.widget.textclock, }, spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - format = "%a, %b %d", - widget = wibox.widget.textclock - }, - id = "date_layout", - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - id = "container", left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.date.bg, fg = Theme_config.date.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background + shape = Theme_config.date.shape, + widget = wibox.container.background, } - local calendar_popup = awful.popup { + local calendar_popup = apopup { widget = cal:get_widget(), - screen = s, + screen = screen, ontop = true, - bg = "#00000000", visible = false, } - -- Signals - Hover_signal(date_widget) + hover.bg_hover { widget = date_widget } - date_widget:buttons { - gears.table.join( - awful.button({}, 1, function() - local geo = mouse.current_wibox:geometry() - calendar_popup.x = geo.x - calendar_popup.y = geo.y + dpi(55) - calendar_popup.visible = not calendar_popup.visible - end) - ) - } + date_widget:buttons { gtable.join( + abutton({}, 1, function() + local geo = capi.mouse.coords() + calendar_popup.y = dpi(65) + if geo.x + (calendar_popup.width / 2) > capi.mouse.screen.geometry.width then + calendar_popup.x = capi.mouse.screen.geometry.x + capi.mouse.screen.geometry.width - calendar_popup.width + else + calendar_popup.x = geo.x - (calendar_popup.width / 2) + end + calendar_popup.visible = not calendar_popup.visible + end) + ), } return date_widget -end +end, }) diff --git a/awesome/src/widgets/gpu_info.lua b/awesome/src/widgets/gpu_info.lua index 5fdfddc..45ded53 100644 --- a/awesome/src/widgets/gpu_info.lua +++ b/awesome/src/widgets/gpu_info.lua @@ -3,179 +3,173 @@ --------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local wibox = require('wibox') -local color = require("src.lib.color") -local rubato = require("src.lib.rubato") +-- Third Party Libs +local color = require('src.lib.color') +local rubato = require('src.lib.rubato') +local hover = require('src.tools.hover') -require("src.tools.helpers.gpu_temp") -require("src.tools.helpers.gpu_usage") +local icon_dir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/cpu/' -local capi = { - awesome = awesome, -} +local gpu_info = {} -local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/" +local function gpu_temp_new() + local gpu_temp_helper = require('src.tools.helpers.gpu_temp') -return function(widget) - - local gpu_usage_widget = wibox.widget { + local w = base.make_widget_from_value(wibox.widget { { { { { { - id = "icon", + id = 'icon_role', widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icon_dir .. "gpu.svg", Theme_config.gpu_usage.fg), - resize = false + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'gpu.svg', Theme_config.gpu_temp.fg), + resize = true, }, - id = "icon_layout", - widget = wibox.container.place + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" - }, - spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "gpu_layout", - layout = wibox.layout.fixed.horizontal - }, - id = "container", - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin - }, - bg = Theme_config.gpu_usage.bg, - fg = Theme_config.gpu_usage.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } - - local gpu_temp_widget = wibox.widget { - { - { - { { - { - id = "icon", - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icon_dir .. "gpu.svg", Theme_config.gpu_temp.fg), - resize = false - }, - id = "icon_layout", - widget = wibox.container.place + id = 'text_role', + text = '0°C', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, }, - spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "gpu_layout", - layout = wibox.layout.fixed.horizontal + widget = wibox.container.place, }, - id = "container", - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin + left = dpi(5), + right = dpi(5), + widget = wibox.container.margin, }, - bg = Theme_config.gpu_temp.bg_low, + bg = Theme_config.gpu_temp.bg, fg = Theme_config.gpu_temp.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } + shape = Theme_config.gpu_temp.shape, + widget = wibox.container.background, + }) - Hover_signal(gpu_temp_widget) - Hover_signal(gpu_usage_widget) + assert(w, 'Widget not created') - -- GPU Utilization - capi.awesome.connect_signal( - "update::gpu_usage", - function(stdout) - gpu_usage_widget.container.gpu_layout.label.text = stdout:gsub("\n", "") .. "%" - end - ) + local r = rubato.timed { duration = 2.5 } + local g = rubato.timed { duration = 2.5 } + local b = rubato.timed { duration = 2.5 } - local r_timed_gpu_bg = rubato.timed { duration = 2.5 } - local g_timed_gpu_bg = rubato.timed { duration = 2.5 } - local b_timed_gpu_bg = rubato.timed { duration = 2.5 } - - r_timed_gpu_bg.pos, g_timed_gpu_bg.pos, b_timed_gpu_bg.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low) + r.pos, g.pos, b.pos = color.utils.hex_to_rgba(Theme_config.cpu_temp.bg_low) -- Subscribable function to have rubato set the bg/fg color local function update_bg() - gpu_temp_widget:set_bg("#" .. - color.utils.rgba_to_hex { math.max(0, r_timed_gpu_bg.pos), math.max(0, g_timed_gpu_bg.pos), - math.max(0, b_timed_gpu_bg.pos) }) + w:set_bg('#' .. color.utils.rgba_to_hex { math.max(0, r.pos), math.max(0, g.pos), + math.max(0, b.pos), }) end - r_timed_gpu_bg:subscribe(update_bg) - g_timed_gpu_bg:subscribe(update_bg) - b_timed_gpu_bg:subscribe(update_bg) + r:subscribe(update_bg) + g:subscribe(update_bg) + b:subscribe(update_bg) -- Both functions to set a color, if called they take a new color local function set_bg(newbg) - r_timed_gpu_bg.target, g_timed_gpu_bg.target, b_timed_gpu_bg.target = color.utils.hex_to_rgba(newbg) + r.target, g.target, b.target = color.utils.hex_to_rgba(newbg) end -- GPU Temperature - capi.awesome.connect_signal( - "update::gpu_temp", - function(stdout) - - local temp_icon - local temp_color - local temp_num = tonumber(stdout) or "N/A" - - if temp_num then - - if temp_num < 50 then - temp_color = Theme_config.gpu_temp.bg_low - temp_icon = icon_dir .. "thermometer-low.svg" - elseif temp_num >= 50 and temp_num < 80 then - temp_color = Theme_config.gpu_temp.bg_mid - temp_icon = icon_dir .. "thermometer.svg" - elseif temp_num >= 80 then - temp_color = Theme_config.gpu_temp.bg_high - temp_icon = icon_dir .. "thermometer-high.svg" - end - else - temp_num = "N/A" + gpu_temp_helper:connect_signal('update::gpu_temp', function(_, stdout) + local temp_icon + local temp_color + local temp_num = tonumber(stdout) or 0 + if temp_num then + if temp_num < 50 then temp_color = Theme_config.gpu_temp.bg_low - temp_icon = icon_dir .. "thermometer-low.svg" + temp_icon = icon_dir .. 'thermometer-low.svg' + elseif temp_num >= 50 and temp_num < 80 then + temp_color = Theme_config.gpu_temp.bg_mid + temp_icon = icon_dir .. 'thermometer.svg' + elseif temp_num >= 80 then + temp_color = Theme_config.gpu_temp.bg_high + temp_icon = icon_dir .. 'thermometer-high.svg' end - gpu_temp_widget.container.gpu_layout.icon_margin.icon_layout.icon:set_image(temp_icon) - set_bg(temp_color) - gpu_temp_widget.container.gpu_layout.label.text = tostring(temp_num) .. "°C" + else + temp_color = Theme_config.gpu_temp.bg_low + temp_icon = icon_dir .. 'thermometer-low.svg' end - ) + w:get_children_by_id('icon_role')[1]:set_image(temp_icon) + set_bg(temp_color) + w:get_children_by_id('text_role')[1].text = tostring(temp_num) .. '°C' + end) - if widget == "usage" then - return gpu_usage_widget - elseif widget == "temp" then - return gpu_temp_widget - end + return w end + +local function gpu_usage_new() + local gpu_usage_helper = require('src.tools.helpers.gpu_usage') + + local w = base.make_widget_from_value(wibox.widget { + { + { + { + { + { + id = 'icon_role', + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'gpu.svg', Theme_config.gpu_usage.fg), + resize = true, + }, + widget = wibox.container.constraint, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + }, + { + id = 'text_role', + text = '0%', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }, + widget = wibox.container.place, + }, + left = dpi(5), + right = dpi(5), + widget = wibox.container.margin, + }, + bg = Theme_config.gpu_usage.bg, + fg = Theme_config.gpu_usage.fg, + shape = Theme_config.gpu_usage.shape, + widget = wibox.container.background, + }) + + assert(w, 'Widget not created') + + hover.bg_hover { widget = w } + + gpu_usage_helper:connect_signal('update::gpu_usage', function(_, stdout) + w:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '') .. '%' + end) + + return w +end + +return setmetatable(gpu_info, { __call = function(_, widget) + if widget == 'usage' then + return gpu_usage_new() + elseif widget == 'temp' then + return gpu_temp_new() + end +end, }) diff --git a/awesome/src/widgets/kblayout.lua b/awesome/src/widgets/kblayout.lua index 60de3a2..c39db25 100644 --- a/awesome/src/widgets/kblayout.lua +++ b/awesome/src/widgets/kblayout.lua @@ -3,395 +3,278 @@ ------------------------------ -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local gtable = require('gears.table') +local abutton = require('awful.button') +local apopup = require('awful.popup') + +-- Local libs +local kb_helper = require('src.tools.helpers.kb_helper') +local hover = require('src.tools.hover') local capi = { - awesome = awesome, - mousegrabber = mousegrabber, + mouse = mouse, } -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/kblayout/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/kblayout/' -return function(s) +local kb_layout_popup +local function create_kb_layout_list() + local widget = wibox.widget { + { + { + id = 'list', + layout = wibox.layout.fixed.vertical, + spacing = dpi(10), + }, + widget = wibox.container.margin, + margins = dpi(10), + }, + widget = wibox.container.background, + bg = Theme_config.kblayout.bg_container, + } + + local list = widget:get_children_by_id('list')[1] + for _, keymap in pairs(User_config.kblayout) do + -- TODO: Add more, too lazy rn + local xkeyboard_country_code = { + ['af'] = { 'أفغانيش(Afghanistan)', 'AFG' }, -- Afghanistan + ['al'] = { 'Shqip(Albania)', 'ALB' }, -- Albania + ['am'] = { 'Hայերեն(Armenia)', 'ARM' }, -- Armenia + ['ara'] = { 'عربي(Arab)', 'ARB' }, -- Arabic + ['at'] = { 'Österreichisch (Austria)', 'AUT' }, -- Austria + ['az'] = { 'Azərbaycan(Azerbaijan)', 'AZE' }, -- Azerbaijan + ['ba'] = { 'Bosanski(Bosnia and Herzegovina)', 'BIH' }, -- Bosnia and Herzegovina + ['bd'] = { '', 'BGD' }, -- Bangladesh + ['be'] = { '', 'BEL' }, -- Belgium + ['bg'] = { '', 'BGR' }, -- Bulgaria + ['br'] = { '', 'BRA' }, -- Brazil + ['bt'] = { '', 'BTN' }, -- Bhutan + ['bw'] = { '', 'BWA' }, -- Botswana + ['by'] = { '', 'BLR' }, -- Belarus + ['ca'] = { '', 'CAN' }, -- Canada + ['cd'] = { '', 'COD' }, -- Congo + ['ch'] = { '', 'CHE' }, -- Switzerland + ['cm'] = { '', 'CMR' }, -- Cameroon + ['cn'] = { '', 'CHN' }, -- China + ['cz'] = { '', 'CZE' }, -- Czechia + ['de'] = { 'Deutsch (Germany)', 'GER' }, -- Germany + ['dk'] = { '', 'DNK' }, -- Denmark + ['ee'] = { '', 'EST' }, -- Estonia + ['es'] = { '', 'ESP' }, -- Spain + ['et'] = { '', 'ETH' }, -- Ethiopia + ['eu'] = { '?', '?' }, -- EurKey + ['fi'] = { '', 'FIN' }, -- Finland + ['fo'] = { '', 'FRO' }, -- Faroe Islands + ['fr'] = { '', 'FRA' }, -- France + ['gb'] = { "English (Bri'ish)", 'ENG' }, -- United Kingdom + ['ge'] = { '', 'GEO' }, -- Georgia + ['gh'] = { '', 'GHA' }, -- Ghana + ['gn'] = { '', 'GIN' }, -- Guinea + ['gr'] = { '', 'GRC' }, -- Greece + ['hr'] = { '', 'HRV' }, -- Croatia + ['hu'] = { '', 'HUN' }, -- Hungary + ['ie'] = { '', 'IRL' }, -- Ireland + ['il'] = { '', 'ISR' }, -- Israel + ['in'] = { '', 'IND' }, -- India + ['iq'] = { '', 'IRQ' }, -- Iraq + ['ir'] = { '', 'IRN' }, -- Iran + ['is'] = { '', 'ISL' }, -- Iceland + ['it'] = { '', 'ITA' }, -- Italy + ['jp'] = { '', 'JPN' }, -- Japan + ['ke'] = { '', 'KEN' }, -- Kenya + ['kg'] = { '', 'KGZ' }, -- Kyrgyzstan + ['kh'] = { '', 'KHM' }, -- Cambodia + ['kr'] = { '', 'KOR' }, -- Korea + ['kz'] = { '', 'KAZ' }, -- Kazakhstan + ['la'] = { '', 'LAO' }, -- Laos + ['latm'] = { '?', '?' }, -- Latin America + ['latn'] = { '?', '?' }, -- Latin + ['lk'] = { '', 'LKA' }, -- Sri Lanka + ['lt'] = { '', 'LTU' }, -- Lithuania + ['lv'] = { '', 'LVA' }, -- Latvia + ['ma'] = { '', 'MAR' }, -- Morocco + ['mao'] = { '?', '?' }, -- Maori + ['me'] = { '', 'MNE' }, -- Montenegro + ['mk'] = { '', 'MKD' }, -- Macedonia + ['ml'] = { '', 'MLI' }, -- Mali + ['mm'] = { '', 'MMR' }, -- Myanmar + ['mn'] = { '', 'MNG' }, -- Mongolia + ['mt'] = { '', 'MLT' }, -- Malta + ['mv'] = { '', 'MDV' }, -- Maldives + ['ng'] = { '', 'NGA' }, -- Nigeria + ['nl'] = { '', 'NLD' }, -- Netherlands + ['no'] = { '', 'NOR' }, -- Norway + ['np'] = { '', 'NRL' }, -- Nepal + ['ph'] = { '', 'PHL' }, -- Philippines + ['pk'] = { '', 'PAK' }, -- Pakistan + ['pl'] = { '', 'POL' }, -- Poland + ['pt'] = { '', 'PRT' }, -- Portugal + ['ro'] = { '', 'ROU' }, -- Romania + ['rs'] = { '', 'SRB' }, -- Serbia + ['ru'] = { 'Русский (Russia)', 'RUS' }, -- Russia + ['se'] = { '', 'SWE' }, -- Sweden + ['si'] = { '', 'SVN' }, -- Slovenia + ['sk'] = { '', 'SVK' }, -- Slovakia + ['sn'] = { '', 'SEN' }, -- Senegal + ['sy'] = { '', 'SYR' }, -- Syria + ['th'] = { '', 'THA' }, -- Thailand + ['tj'] = { '', 'TJK' }, -- Tajikistan + ['tm'] = { '', 'TKM' }, -- Turkmenistan + ['tr'] = { '', 'TUR' }, -- Turkey + ['tw'] = { '', 'TWN' }, -- Taiwan + ['tz'] = { '', 'TZA' }, -- Tanzania + ['ua'] = { '', 'UKR' }, -- Ukraine + ['us'] = { 'English (United States)', 'USA' }, -- USA + ['uz'] = { '', 'UZB' }, -- Uzbekistan + ['vn'] = { '', 'VNM' }, -- Vietnam + ['za'] = { '', 'ZAF' }, -- South Africa + } + + local longname, shortname = table.unpack(xkeyboard_country_code[keymap]) + + local kb_layout_item = wibox.widget { + { + { + { + id = 'shortname', + markup = '' .. shortname .. '', + widget = wibox.widget.textbox, + valign = 'center', + halign = 'center', + }, + { + id = 'longname', + markup = '' .. longname .. '', + widget = wibox.widget.textbox, + font = User_config.font.bold, + }, + spacing = dpi(15), + layout = wibox.layout.fixed.horizontal, + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + id = 'hover', + shape = Theme_config.kblayout.item.shape, + border_width = Theme_config.kblayout.item.border_width, + border_color = Theme_config.kblayout.item.border_color, + bg = Theme_config.kblayout.item.bg, + widget = wibox.container.background, + } + + kb_helper:connect_signal('KB::layout_changed', function(_, k) + if keymap == k then + kb_layout_item.bg = Theme_config.kblayout.item.bg_selected + kb_layout_item.border_color = Theme_config.kblayout.item.bg_selected + kb_layout_item:get_children_by_id('shortname')[1].markup = '' .. shortname .. '' + kb_layout_item:get_children_by_id('longname')[1].markup = '' .. longname .. '' + else + kb_layout_item.bg = Theme_config.kblayout.item.bg + kb_layout_item.border_color = Theme_config.kblayout.item.border_color + kb_layout_item:get_children_by_id('shortname')[1].markup = '' .. shortname .. '' + kb_layout_item:get_children_by_id('longname')[1].markup = '' .. longname .. '' + end + end) + + kb_helper:get_layout_async(function(k) + if keymap == k then + kb_layout_item.bg = Theme_config.kblayout.item.bg_selected + kb_layout_item.border_color = Theme_config.kblayout.item.bg_selected + kb_layout_item:get_children_by_id('shortname')[1].markup = '' .. shortname .. '' + kb_layout_item:get_children_by_id('longname')[1].markup = '' .. longname .. '' + else + kb_layout_item.bg = Theme_config.kblayout.item.bg + kb_layout_item.border_color = Theme_config.kblayout.item.border_color + kb_layout_item:get_children_by_id('shortname')[1].markup = '' .. shortname .. '' + kb_layout_item:get_children_by_id('longname')[1].markup = '' .. longname .. '' + end + end) + + hover.bg_hover { widget = kb_layout_item } + + kb_layout_item:buttons { gtable.join( + abutton({}, 1, function() + kb_helper:set_layout(keymap) + --kb_layout_popup.visible = not kb_layout_popup.visible + end) + ), } + + list:add(kb_layout_item) + end + + return widget +end + +return setmetatable({}, { __call = function(_, screen) local kblayout_widget = wibox.widget { { { { { - { - id = "icon", - widget = wibox.widget.imagebox, - resize = false, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icondir .. "keyboard.svg", Theme_config.kblayout.fg) - }, - id = "icon_layout", - widget = wibox.container.place + widget = wibox.widget.imagebox, + resize = true, + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icondir .. 'keyboard.svg', Theme_config.kblayout.fg), }, - top = dpi(2), - widget = wibox.container.margin, - id = "icon_margin" + widget = wibox.container.constraint, + width = dpi(24), + height = dpi(24), + strategy = 'exact', + }, + { + id = 'text_role', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, spacing = dpi(10), - { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - id = "kblayout_layout", - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, - id = "container", left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.kblayout.bg, fg = Theme_config.kblayout.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } - - local function get_kblayout() - awful.spawn.easy_async_with_shell( - [[ setxkbmap -query | grep layout | awk '{print $2}' ]], - function(stdout) - local layout = stdout:gsub("\n", "") - kblayout_widget.container.kblayout_layout.label.text = layout - capi.awesome.emit_signal("update::background:kblayout") - end - ) - end - - local function create_kb_layout_item(keymap) - -- TODO: Add more, too lazy rn - local longname, shortname - - local xkeyboard_country_code = { - { "af", "أفغانيش(Afghanistan)", "AFG" }, -- Afghanistan - { "al", "Shqip(Albania)", "ALB" }, -- Albania - { "am", "Hայերեն(Armenia)", "ARM" }, -- Armenia - { "ara", "عربي(Arab)", "ARB" }, -- Arabic - { "at", "Österreichisch (Austria)", "AUT" }, -- Austria - { "az", "Azərbaycan(Azerbaijan)", "AZE" }, -- Azerbaijan - { "ba", "Bosanski(Bosnia and Herzegovina)", "BIH" }, -- Bosnia and Herzegovina - { "bd", "", "BGD" }, -- Bangladesh - { "be", "", "BEL" }, -- Belgium - { "bg", "", "BGR" }, -- Bulgaria - { "br", "", "BRA" }, -- Brazil - { "bt", "", "BTN" }, -- Bhutan - { "bw", "", "BWA" }, -- Botswana - { "by", "", "BLR" }, -- Belarus - { "ca", "", "CAN" }, -- Canada - { "cd", "", "COD" }, -- Congo - { "ch", "", "CHE" }, -- Switzerland - { "cm", "", "CMR" }, -- Cameroon - { "cn", "", "CHN" }, -- China - { "cz", "", "CZE" }, -- Czechia - { "de", "Deutsch (Germany)", "GER" }, -- Germany - { "dk", "", "DNK" }, -- Denmark - { "ee", "", "EST" }, -- Estonia - { "es", "", "ESP" }, -- Spain - { "et", "", "ETH" }, -- Ethiopia - { "eu", "?", "?" }, -- EurKey - { "fi", "", "FIN" }, -- Finland - { "fo", "", "FRO" }, -- Faroe Islands - { "fr", "", "FRA" }, -- France - { "gb", "English (Bri'ish)", "ENG" }, -- United Kingdom - { "ge", "", "GEO" }, -- Georgia - { "gh", "", "GHA" }, -- Ghana - { "gn", "", "GIN" }, -- Guinea - { "gr", "", "GRC" }, -- Greece - { "hr", "", "HRV" }, -- Croatia - { "hu", "", "HUN" }, -- Hungary - { "ie", "", "IRL" }, -- Ireland - { "il", "", "ISR" }, -- Israel - { "in", "", "IND" }, -- India - { "iq", "", "IRQ" }, -- Iraq - { "ir", "", "IRN" }, -- Iran - { "is", "", "ISL" }, -- Iceland - { "it", "", "ITA" }, -- Italy - { "jp", "", "JPN" }, -- Japan - { "ke", "", "KEN" }, -- Kenya - { "kg", "", "KGZ" }, -- Kyrgyzstan - { "kh", "", "KHM" }, -- Cambodia - { "kr", "", "KOR" }, -- Korea - { "kz", "", "KAZ" }, -- Kazakhstan - { "la", "", "LAO" }, -- Laos - { "latam", "?", "?" }, -- Latin America - { "latin", "?", "?" }, -- Latin - { "lk", "", "LKA" }, -- Sri Lanka - { "lt", "", "LTU" }, -- Lithuania - { "lv", "", "LVA" }, -- Latvia - { "ma", "", "MAR" }, -- Morocco - { "mao", "?", "?" }, -- Maori - { "me", "", "MNE" }, -- Montenegro - { "mk", "", "MKD" }, -- Macedonia - { "ml", "", "MLI" }, -- Mali - { "mm", "", "MMR" }, -- Myanmar - { "mn", "", "MNG" }, -- Mongolia - { "mt", "", "MLT" }, -- Malta - { "mv", "", "MDV" }, -- Maldives - { "ng", "", "NGA" }, -- Nigeria - { "nl", "", "NLD" }, -- Netherlands - { "no", "", "NOR" }, -- Norway - { "np", "", "NRL" }, -- Nepal - { "ph", "", "PHL" }, -- Philippines - { "pk", "", "PAK" }, -- Pakistan - { "pl", "", "POL" }, -- Poland - { "pt", "", "PRT" }, -- Portugal - { "ro", "", "ROU" }, -- Romania - { "rs", "", "SRB" }, -- Serbia - { "ru", "Русский (Russia)", "RUS" }, -- Russia - { "se", "", "SWE" }, -- Sweden - { "si", "", "SVN" }, -- Slovenia - { "sk", "", "SVK" }, -- Slovakia - { "sn", "", "SEN" }, -- Senegal - { "sy", "", "SYR" }, -- Syria - { "th", "", "THA" }, -- Thailand - { "tj", "", "TJK" }, -- Tajikistan - { "tm", "", "TKM" }, -- Turkmenistan - { "tr", "", "TUR" }, -- Turkey - { "tw", "", "TWN" }, -- Taiwan - { "tz", "", "TZA" }, -- Tanzania - { "ua", "", "UKR" }, -- Ukraine - { "us", "English (United States)", "USA" }, -- USA - { "uz", "", "UZB" }, -- Uzbekistan - { "vn", "", "VNM" }, -- Vietnam - { "za", "", "ZAF" } -- South Africa - } - - for _, c in ipairs(xkeyboard_country_code) do - if c[1] == keymap then - longname = c[2] - shortname = c[3] - end - end - - local kb_layout_item = wibox.widget { - { - { - -- Short name e.g. GER, ENG, RUS - { - { - text = shortname, - widget = wibox.widget.textbox, - font = User_config.font.extrabold, - id = "shortname" - }, - fg = Theme_config.kblayout.item.fg_short, - widget = wibox.container.background, - id = "background2" - }, - { - { - text = longname, - widget = wibox.widget.textbox, - font = User_config.font.bold, - id = "longname", - }, - fg = Theme_config.kblayout.item.fg_long, - widget = wibox.container.background, - id = "background1" - }, - spacing = dpi(15), - layout = wibox.layout.fixed.horizontal, - id = "container" - }, - margins = dpi(10), - widget = wibox.container.margin, - id = "margin" - }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(8)) - end, - bg = Theme_config.kblayout.item.bg, - widget = wibox.container.background, - id = "background", - keymap = keymap - } - - Hover_signal(kb_layout_item) - - capi.awesome.connect_signal( - "update::background:kblayout", - function() - awful.spawn.easy_async_with_shell( - [[ setxkbmap -query | grep layout | awk '{print $2}' ]], - function(stdout) - local layout = stdout:gsub("\n", "") - if kb_layout_item.keymap == layout then - kb_layout_item.bg = Theme_config.kblayout.item.bg_selected - kb_layout_item:get_children_by_id("background2")[1].fg = Theme_config.kblayout.item.fg_selected - kb_layout_item:get_children_by_id("background1")[1].fg = Theme_config.kblayout.item.fg_selected - else - kb_layout_item.bg = Theme_config.kblayout.item.bg - kb_layout_item:get_children_by_id("background2")[1].fg = Theme_config.kblayout.item.fg_short - kb_layout_item:get_children_by_id("background1")[1].fg = Theme_config.kblayout.item.fg_long - end - end - ) - end - ) - get_kblayout() - - kb_layout_item:connect_signal( - "button::press", - function() - awful.spawn.easy_async_with_shell( - "setxkbmap " .. keymap, - function() - capi.awesome.emit_signal("kblayout::hide:kbmenu") - capi.mousegrabber.stop() - get_kblayout() - end - ) - end - ) - return kb_layout_item - end - - local function get_kblist() - local kb_layout_items = { - layout = wibox.layout.fixed.vertical, - spacing = dpi(10) - } - for i, keymap in pairs(User_config.kblayout) do - kb_layout_items[i] = create_kb_layout_item(keymap) - end - local cont = { - { - kb_layout_items, - margins = dpi(10), - widget = wibox.container.margin - }, - layout = wibox.layout.fixed.vertical, - } - return cont - end - - local kb_menu_widget = awful.popup { - screen = s, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(12)) - end, + shape = Theme_config.kblayout.shape, widget = wibox.container.background, - bg = Theme_config.kblayout.bg_container, - border_width = dpi(4), - border_color = Theme_config.kblayout.border_color_container, - width = dpi(100), - max_height = dpi(600), - visible = false, + } + + hover.bg_hover { widget = kblayout_widget } + + kb_helper:get_layout_async(function(stdout) + kblayout_widget:get_children_by_id('text_role')[1].text = stdout:gsub('\n', '') + end) + + kb_helper:connect_signal('KB::layout_changed', function(_, k) + kblayout_widget:get_children_by_id('text_role')[1].text = k + end) + + kb_layout_popup = apopup { + widget = create_kb_layout_list(), + border_color = Theme_config.kblayout.border_color, + border_width = Theme_config.kblayout.border_width, + screen = screen, ontop = true, - placement = function(c) awful.placement.align(c, - { position = "top_right", margins = { right = dpi(255), top = dpi(60) } }) - end + visible = false, + bg = Theme_config.kblayout.bg_container, } - kb_menu_widget:connect_signal( - "mouse::leave", - function() - capi.mousegrabber.run( - function() - kblayout_widget.bg = Theme_config.kblayout.bg - capi.awesome.emit_signal("kblayout::hide:kbmenu") - capi.mousegrabber.stop() - return true - end, - "arrow" - ) - end - ) + kblayout_widget:buttons { gtable.join( + abutton({}, 1, function() + local geo = capi.mouse.coords() + kb_layout_popup.y = dpi(65) + kb_layout_popup.x = geo.x - kb_layout_popup.width / 2 + kb_layout_popup.visible = not kb_layout_popup.visible + end) + ), } - kb_menu_widget:connect_signal( - "mouse::enter", - function() - mousegrabber.stop() - end - ) - - kb_menu_widget:setup( - get_kblist() - ) - - local function toggle_kb_layout() - awful.spawn.easy_async_with_shell( - "setxkbmap -query | grep layout: | awk '{print $2}'", - function(stdout) - for j, n in ipairs(User_config.kblayout) do - if stdout:match(n) then - if j == #User_config.kblayout then - awful.spawn.easy_async_with_shell( - "setxkbmap " .. User_config.kblayout[1], - function() - get_kblayout() - end - ) - else - awful.spawn.easy_async_with_shell( - "setxkbmap " .. User_config.kblayout[j + 1], - function() - get_kblayout() - end - ) - end - end - end - end - ) - end - - capi.awesome.connect_signal( - "kblayout::toggle", - function() - toggle_kb_layout() - end - ) - - -- Signals - Hover_signal(kblayout_widget) - - local kblayout_keygrabber = awful.keygrabber { - autostart = false, - stop_event = 'release', - keypressed_callback = function(self, mod, key, command) - capi.awesome.emit_signal("kblayout::hide:kbmenu") - capi.mousegrabber.stop() - end - } - - kblayout_widget:connect_signal( - "button::press", - function() - capi.mousegrabber.stop() - if kb_menu_widget.visible then - kb_menu_widget.visible = false - kblayout_keygrabber:stop() - else - kb_menu_widget.visible = true - kblayout_keygrabber:start() - end - end - ) - - capi.awesome.connect_signal( - "kblayout::hide:kbmenu", - function() - kb_menu_widget.visible = false - kblayout_keygrabber:stop() - end - ) - - get_kblayout() - kb_menu_widget.visible = false return kblayout_widget -end +end, }) diff --git a/awesome/src/widgets/layout_list.lua b/awesome/src/widgets/layout_list.lua index f8a44f4..9b7183c 100644 --- a/awesome/src/widgets/layout_list.lua +++ b/awesome/src/widgets/layout_list.lua @@ -3,32 +3,35 @@ ---------------------------------- -- Awesome Libs -local abutton = require("awful.button") -local alayout = require("awful.layout") -local awidget = require("awful.widget") -local dpi = require("beautiful").xresources.apply_dpi -local gtable = require("gears.table") -local wibox = require("wibox") +local abutton = require('awful.button') +local alayout = require('awful.layout') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local wibox = require('wibox') + +-- Local libs +local hover = require('src.tools.hover') --#region Layout icons -local layout_path = Theme_path .. "../assets/layout/" +local layout_path = Theme_path .. '../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" +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 -- Returns the layoutbox widget @@ -39,22 +42,21 @@ return function() { awidget.layoutbox(), widget = wibox.container.place, - halign = "center", - valign = "center" }, left = dpi(5), right = dpi(5), widget = wibox.container.margin, }, widget = wibox.container.constraint, - width = dpi(40) + strategy = 'exact', + width = dpi(40), }, bg = Theme_config.layout_list.bg, shape = Theme_config.layout_list.shape, - widget = wibox.container.background + widget = wibox.container.background, } - Hover_signal(layout) + hover.bg_hover { widget = layout } layout:buttons(gtable.join( abutton({}, 1, function() diff --git a/awesome/src/widgets/network.lua b/awesome/src/widgets/network.lua index f268b2f..0416836 100644 --- a/awesome/src/widgets/network.lua +++ b/awesome/src/widgets/network.lua @@ -3,15 +3,14 @@ -------------------------------- -- Awesome Libs -local abutton = require("awful.button") -local apopup = require("awful.popup") -local atooltip = require("awful.tooltip") -local base = require("wibox.widget.base") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local gtable = require("gears.table") -local naughty = require("naughty") -local wibox = require("wibox") +local abutton = require('awful.button') +local apopup = require('awful.popup') +local atooltip = require('awful.tooltip') +local base = require('wibox.widget.base') +local dpi = require('beautiful').xresources.apply_dpi +local gears = require('gears') +local gtable = require('gears.table') +local wibox = require('wibox') local capi = { awesome = awesome, @@ -19,51 +18,79 @@ local capi = { } -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/network/" +local icondir = gears.filesystem.get_configuration_dir() .. 'src/assets/icons/network/' -local nm_widget = require("src.modules.network_controller.init") +local nm_widget = require('src.modules.network_controller.init') +local hover = require('src.tools.hover') local network = { mt = {} } function network.new(args) args = args or {} - local w = base.make_widget_from_value({ + local w = base.make_widget_from_value { { { { { id = 'wifi_icon', - image = gears.color.recolor_image(icondir .. "no-internet" .. ".svg", Theme_config.network.fg), + image = gears.color.recolor_image(icondir .. 'no-internet.svg', Theme_config.network.fg), widget = wibox.widget.imagebox, - resize = false + resize = false, }, { - id = "wifi_strength", + id = 'wifi_strength', visible = true, - widget = wibox.widget.textbox + widget = wibox.widget.textbox, }, spacing = dpi(10), - layout = wibox.layout.fixed.horizontal + layout = wibox.layout.fixed.horizontal, }, left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, widget = wibox.container.place, - halign = "center", - valign = "center" + halign = 'center', + valign = 'center', }, bg = Theme_config.network.bg, fg = Theme_config.network.fg, shape = Theme_config.network.shape, - widget = wibox.container.background - }) + widget = wibox.container.background, + } - Hover_signal(w) + assert(w, 'Failed to create widget') + + hover.bg_hover { widget = w } gtable.crush(w, network, true) + capi.awesome.connect_signal('NM::AccessPointStrength', function(strength) + strength = math.floor(strength) + w:get_children_by_id('wifi_strength')[1].text = strength .. '%' + w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir .. + 'wifi-strength-' .. math.floor(strength / 25) + 1 .. '.svg', Theme_config.network.fg) + end) + + capi.awesome.connect_signal('NM::EthernetStatus', function(connected, speed) + local tt = atooltip { + objects = { w }, + mode = 'outside', + preferred_alignments = 'middle', + margins = dpi(10), + } + if connected then + w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir .. 'ethernet.svg', + Theme_config.network.fg) + tt.text = 'Connected via Ethernet at ' .. math.floor(speed or 0) .. '/Mbps' + else + w:get_children_by_id('wifi_icon')[1].image = gears.color.recolor_image(icondir .. 'no-internet.svg', + Theme_config.network.fg) + tt.text = 'No connection found' + end + end) + local nm = nm_widget { screen = args.screen } local network_controler_popup = apopup { @@ -82,25 +109,6 @@ function network.new(args) end) )) - awesome.connect_signal("NM::AccessPointStrength", function(strength) - strength = math.floor(strength) - w:get_children_by_id("wifi_strength")[1].text = strength .. "%" - w:get_children_by_id("wifi_icon")[1].image = gears.color.recolor_image(icondir .. - "wifi-strength-" .. math.floor(strength / 25) + 1 .. ".svg", Theme_config.network.fg) - end) - - nm:connect_signal("NM::Bitrate", function(_, bitrate) - print(bitrate) - end) - - atooltip { - objects = { w }, - mode = "outside", - preferred_alignments = "middle", - margins = dpi(10), - text = "Connected to " .. "" .. " with " .. "" .. " signal strength" - } - return w end diff --git a/awesome/src/widgets/power.lua b/awesome/src/widgets/power.lua index 5f240b1..29fc9fe 100644 --- a/awesome/src/widgets/power.lua +++ b/awesome/src/widgets/power.lua @@ -3,65 +3,49 @@ -------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local abutton = require('awful.button') +local gtable = require('gears.table') +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') +local gfilesystem = require('gears.filesystem') +local gcolor = require('gears.color') -local capi = { - awesome = awesome, -} +-- Local libs +local powermenu = require('src.modules.powermenu.init') +local hover = require('src.tools.hover') -- Icon directory path -local icondir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/power/" +local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/power/' -return function() +return setmetatable({}, { __call = function() local power_widget = wibox.widget { { { - { - { - { - id = "icon", - image = gears.color.recolor_image(icondir .. "power.svg", Theme_config.power_button.fg), - widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - resize = false - }, - id = "icon_layout", - widget = wibox.container.place - }, - id = "icon_margin", - top = dpi(2), - widget = wibox.container.margin - }, - id = "power_layout", - layout = wibox.layout.fixed.horizontal + image = gcolor.recolor_image(icondir .. 'power.svg', Theme_config.power_button.fg), + widget = wibox.widget.imagebox, + valign = 'center', + halign = 'center', + resize = false, }, - id = "container", left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.power_button.bg, fg = Theme_config.power_button.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background + shape = Theme_config.power_button.shape, + widget = wibox.container.background, } -- Signals - Hover_signal(power_widget) + hover.bg_hover { widget = power_widget } - power_widget:connect_signal( - "button::release", - function() - capi.awesome.emit_signal("module::powermenu:show") - end - ) + power_widget:buttons { gtable.join( + abutton({}, 1, function() + powermenu:toggle() + end) + ), } return power_widget -end +end, }) diff --git a/awesome/src/widgets/ram_info.lua b/awesome/src/widgets/ram_info.lua index 2c7dcc2..34a5ee3 100644 --- a/awesome/src/widgets/ram_info.lua +++ b/awesome/src/widgets/ram_info.lua @@ -3,19 +3,16 @@ --------------------------------- -- Awesome Libs -local awful = require("awful") -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local watch = awful.widget.watch -local wibox = require("wibox") +local dpi = require('beautiful').xresources.apply_dpi +local gcolor = require('gears.color') +local gfilesystem = require('gears.filesystem') +local gshape = require('gears.shape') +local wibox = require('wibox') -require("src.tools.helpers.ram") +local ram_helper = require('src.tools.helpers.ram') +local hover = require('src.tools.hover') -local capi = { - awesome = awesome, -} - -local icon_dir = gears.filesystem.get_configuration_dir() .. "src/assets/icons/cpu/" +local icon_dir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/cpu/' return function() local ram_widget = wibox.widget { @@ -24,53 +21,50 @@ return function() { { { - id = "icon", + id = 'icon', widget = wibox.widget.imagebox, - valign = "center", - halign = "center", - image = gears.color.recolor_image(icon_dir .. "ram.svg", Theme_config.ram_info.fg), - resize = false + valign = 'center', + halign = 'center', + image = gcolor.recolor_image(icon_dir .. 'ram.svg', Theme_config.ram_info.fg), + resize = false, }, - id = "icon_layout", - widget = wibox.container.place + id = 'icon_layout', + widget = wibox.container.place, }, top = dpi(2), widget = wibox.container.margin, - id = "icon_margin" + id = 'icon_margin', }, spacing = dpi(10), { - id = "label", - align = "center", - valign = "center", - widget = wibox.widget.textbox + id = 'label', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox, }, - id = "ram_layout", - layout = wibox.layout.fixed.horizontal + id = 'ram_layout', + layout = wibox.layout.fixed.horizontal, }, - id = "container", + id = 'container', left = dpi(8), right = dpi(8), - widget = wibox.container.margin + widget = wibox.container.margin, }, bg = Theme_config.ram_info.bg, fg = Theme_config.ram_info.fg, shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) + gshape.rounded_rect(cr, width, height, dpi(6)) end, - widget = wibox.container.background + widget = wibox.container.background, } - Hover_signal(ram_widget) + hover.bg_hover { widget = ram_widget } - capi.awesome.connect_signal( - "update::ram_widget", - function(MemTotal, MemFree, MemAvailable) - local ram_string = tostring(string.format("%.1f", ((MemTotal - MemAvailable) / 1024 / 1024)) .. - "/" .. string.format("%.1f", (MemTotal / 1024 / 1024)) .. "GB"):gsub(",", ".") - ram_widget.container.ram_layout.label.text = ram_string - end - ) + ram_helper:connect_signal('update::ram_widget', function(_, MemTotal, MemFree, MemAvailable) + local ram_string = tostring(string.format('%.1f', ((MemTotal - MemAvailable) / 1024 / 1024)) .. + '/' .. string.format('%.1f', (MemTotal / 1024 / 1024)) .. 'GB'):gsub(',', '.') + ram_widget.container.ram_layout.label.text = ram_string + end) return ram_widget end diff --git a/awesome/src/widgets/systray.lua b/awesome/src/widgets/systray.lua index 6e85aab..63358df 100644 --- a/awesome/src/widgets/systray.lua +++ b/awesome/src/widgets/systray.lua @@ -3,47 +3,48 @@ -------------------------------- -- Awesome Libs -local dpi = require("beautiful").xresources.apply_dpi -local gears = require("gears") -local wibox = require("wibox") +local dpi = require('beautiful').xresources.apply_dpi +local wibox = require('wibox') -local capi = { - awesome = awesome, -} +local capi = { awesome = awesome } +-- Systray theme variables Theme.bg_systray = Theme_config.systray.bg Theme.systray_icon_spacing = dpi(10) -return function(s) +return function() local systray = wibox.widget { { { wibox.widget.systray(), + id = 'systray_margin', widget = wibox.container.margin, - id = 'st' }, - strategy = "exact", + strategy = 'exact', widget = wibox.container.constraint, - id = "container" }, widget = wibox.container.background, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, + shape = Theme_config.systray.shape, bg = Theme_config.systray.bg } - capi.awesome.connect_signal("systray::update", function() + local systray_margin = systray:get_children_by_id('systray_margin')[1] + + -- Wait for an systray update + capi.awesome.connect_signal('systray::update', function() + -- Get the number of entries in the systray local num_entries = capi.awesome.systray() + -- If its 0 remove the margins to hide the widget if num_entries == 0 then - systray.container.st:set_margins(0) + systray_margin:set_margins(0) else - systray.container.st:set_margins(dpi(6)) + systray_margin:set_margins(dpi(6)) end end) - systray.container.st.widget:set_base_size(dpi(24)) + -- Set the icon size + systray_margin.widget:set_base_size(dpi(24)) return systray end diff --git a/awesome/src/widgets/taglist.lua b/awesome/src/widgets/taglist.lua index 43efd80..88bf781 100644 --- a/awesome/src/widgets/taglist.lua +++ b/awesome/src/widgets/taglist.lua @@ -3,178 +3,135 @@ -------------------------------- -- Awesome Libs -local wibox = require("wibox") -local awful = require("awful") -local gears = require("gears") -local dpi = require("beautiful").xresources.apply_dpi +local abutton = require('awful.button') +local ascreen = require('awful.screen') +local atag = require('awful.tag') +local awidget = require('awful.widget') +local dpi = require('beautiful').xresources.apply_dpi +local gtable = require('gears.table') +local wibox = require('wibox') -local capi = { - client = client, -} +-- Local Libs +local hover = require('src.tools.hover') + +local capi = { client = client } local modkey = User_config.modkey -local list_update = function(widget, buttons, _, _, objects) - widget:reset() +local tag_text = { + [1] = '一', + [2] = '二', + [3] = '三', + [4] = '四', + [5] = '五', + [6] = '六', + [7] = '七', + [8] = '八', + [9] = '九', + [10] = '十', +} - for _, object in ipairs(objects) do +return setmetatable({}, { __call = function(_, screen) + return awidget.taglist { + filter = awidget.taglist.filter.noempty, + layout = wibox.layout.fixed.horizontal, + screen = screen, + update_function = function(widget, _, _, _, tags) + widget:reset() + -- Create a tag widget for each tag + for _, tag in ipairs(tags) do - local tag_widget = wibox.widget { - { - { + local tag_widget = wibox.widget { { - text = "", - align = "center", - valign = "center", - visible = true, - font = User_config.font.extrabold, - forced_width = dpi(25), - id = "label", - widget = wibox.widget.textbox + { + { + text = tag_text[tag.index], + halign = 'center', + valign = 'center', + id = 'text_role', + widget = wibox.widget.textbox, + }, + id = 'tag_layout', + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, }, - id = "margin", - left = dpi(5), - right = dpi(5), - widget = wibox.container.margin - }, - id = "container", - layout = wibox.layout.fixed.horizontal - }, - fg = Theme_config.taglist.fg, - bg = Theme_config.taglist.bg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } + fg = Theme_config.taglist.fg, + bg = Theme_config.taglist.bg, + shape = Theme_config.taglist.shape, + widget = wibox.container.background, + } - local function create_buttons(buttons_t, object_t) - if buttons_t then - local btns = {} - for _, b in ipairs(buttons_t) do - local btn = awful.button { - modifiers = b.modifiers, - button = b.button, - on_press = function() - b:emit_signal('press', object_t) - end, - on_release = function() - b:emit_signal('release', object_t) + -- Add the buttons for each tag + tag_widget:buttons { gtable.join( + abutton({}, 1, function() + tag:view_only() + end), + + abutton({ modkey }, 1, function() + if capi.client.focus then + capi.client.focus:move_to_tag(tag) end - } - btns[#btns + 1] = btn + end), + + abutton({}, 3, function() + if capi.client.focus then + capi.client.focus:toggle_tag(tag) + end + end), + + abutton({ modkey }, 3, function() + if capi.client.focus then + capi.client.focus:toggle_tag(tag) + end + end), + + abutton({}, 4, function() + atag.viewnext(tag.screen) + end), + + abutton({}, 5, function() + atag.viewprev(tag.screen) + end) + ), } + + -- Change the taglist colors depending on the state of the tag + if tag == ascreen.focused().selected_tag then + tag_widget:set_bg(Theme_config.taglist.bg_focus) + tag_widget:set_fg(Theme_config.taglist.fg_focus) + elseif tag.urgent == true then + tag_widget:set_bg(Theme_config.taglist.bg_urgent) + tag_widget:set_fg(Theme_config.taglist.fg_urgent) + else + tag_widget:set_bg(Theme_config.taglist.bg) + tag_widget:set_fg(Theme_config.taglist.fg) end - return btns + + -- Add the client icons to the tag widget + for _, client in ipairs(tag:clients()) do + tag_widget:get_children_by_id('tag_layout')[1]:add(wibox.widget { + { + resize = true, + valign = 'center', + halign = 'center', + image = client.icon or '', + widget = wibox.widget.imagebox, + }, + height = dpi(25), + width = dpi(25), + strategy = 'exact', + widget = wibox.container.constraint, + }) + end + + hover.bg_hover { widget = tag_widget } + + widget:add(tag_widget) + widget:set_spacing(dpi(5)) end - end - - tag_widget:buttons(create_buttons(buttons, object)) - - tag_widget.container.margin.label:set_text(object.index) - -- Use the wraper function to call the set_bg and set_fg based on the client state - if object == awful.screen.focused().selected_tag then - tag_widget:set_bg(Theme_config.taglist.bg_focus) - tag_widget:set_fg(Theme_config.taglist.fg_focus) - elseif object.urgent == true then - tag_widget:set_bg(Theme_config.taglist.bg_urgent) - tag_widget:set_fg(Theme_config.taglist.fg_urgent) - else - tag_widget:set_bg(Theme_config.taglist.bg) - tag_widget:set_fg(Theme_config.taglist.fg) - end - --#endregion - - -- Set the icon for each client - for _, client in ipairs(object:clients()) do - tag_widget.container.margin:set_right(0) - local icon = wibox.widget { - { - id = "icon_container", - { - id = "icon", - image = Get_icon(client.class, client.name) or client.icon, - resize = true, - valign = "center", - halign = "center", - widget = wibox.widget.imagebox - }, - widget = wibox.container.place - }, - forced_width = dpi(33), - margins = dpi(6), - widget = wibox.container.margin - } - - tag_widget.container:setup({ - icon, - strategy = "exact", - layout = wibox.container.constraint, - }) - end - - Hover_signal(tag_widget) - - widget:add(tag_widget) - widget:set_spacing(dpi(6)) - end -end - -return function(s) - return awful.widget.taglist( - s, - awful.widget.taglist.filter.noempty, - gears.table.join( - awful.button( - {}, - 1, - function(t) - t:view_only() - end - ), - awful.button( - { modkey }, - 1, - function(t) - if capi.client.focus then - capi.client.focus:move_to_tag(t) - end - end - ), - awful.button( - {}, - 3, - function(t) - if capi.client.focus then - capi.client.focus:toggle_tag(t) - end - end - ), - awful.button( - { modkey }, - 3, - function(t) - if capi.client.focus then - capi.client.focus:toggle_tag(t) - end - end - ), - awful.button( - {}, - 4, - function(t) - awful.tag.viewnext(t.screen) - end - ), - awful.button( - {}, - 5, - function(t) - awful.tag.viewprev(t.screen) - end - ) - ), - {}, - list_update, - wibox.layout.fixed.horizontal() - ) -end + end, + } +end, }) diff --git a/awesome/src/widgets/tasklist.lua b/awesome/src/widgets/tasklist.lua index 0400fce..ba1e86a 100644 --- a/awesome/src/widgets/tasklist.lua +++ b/awesome/src/widgets/tasklist.lua @@ -3,152 +3,110 @@ --------------------------------- -- Awesome Libs -local awful = require('awful') -local wibox = require('wibox') +local abutton = require('awful.button') +local atooltip = require('awful.tooltip') +local awidget = require('awful.widget') local dpi = require('beautiful').xresources.apply_dpi -local gears = require('gears') +local gtable = require('gears.table') +local wibox = require('wibox') -local capi = { - client = client, -} +-- Local libs +local hover = require('src.tools.hover') -local list_update = function(widget, buttons, label, _, objects) - widget:reset() - for _, object in ipairs(objects) do - local task_widget = wibox.widget { - { - { +local capi = { client = client } + +return setmetatable({}, { __call = function(_, screen) + return awidget.tasklist { + filter = awidget.tasklist.filter.currenttags, + layout = wibox.layout.fixed.horizontal, + screen = screen, + update_function = function(widget, _, _, _, clients) + widget:reset() + + -- Create a task widget for each client + for _, client in ipairs(clients) do + local task_widget = wibox.widget { { { - nil, { - id = "icon", - valign = "center", - halign = "center", - resize = true, - image = Get_icon(object.class, object.name) or object.icon, - widget = wibox.widget.imagebox + { + valign = 'center', + halign = 'center', + resize = true, + image = client.icon or '', + widget = wibox.widget.imagebox, + }, + width = dpi(25), + height = dpi(25), + strategy = 'exact', + widget = wibox.container.constraint, }, - nil, - layout = wibox.layout.align.horizontal, - id = "layout_icon" + { + id = 'text_role', + halign = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, }, - forced_width = dpi(33), - margins = dpi(3), + right = dpi(10), + left = dpi(10), widget = wibox.container.margin, - id = "margin" }, - { - text = "", - align = "center", - valign = "center", - visible = true, - widget = wibox.widget.textbox, - id = "title" - }, - layout = wibox.layout.fixed.horizontal, - id = "layout_it" - }, - right = dpi(5), - left = dpi(5), - widget = wibox.container.margin, - id = "container" - }, - fg = Theme_config.tasklist.fg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(6)) - end, - widget = wibox.container.background - } + fg = Theme_config.tasklist.fg, + bg = Theme_config.tasklist.bg, + shape = Theme_config.tasklist.shape, + widget = wibox.container.background, + } - local task_tool_tip = awful.tooltip { - objects = { task_widget }, - mode = "inside", - preferred_alignments = "middle", - preferred_positions = "bottom", - margins = dpi(10), - gaps = 0, - delay_show = 1 - } - - local function create_buttons(buttons_t, object_t) - if buttons_t then - local btns = {} - for _, b in ipairs(buttons_t) do - local btn = awful.button { - modifiers = b.modifiers, - button = b.button, - on_press = function() - b:emit_signal('press', object_t) - end, - on_release = function() - b:emit_signal('release', object_t) + task_widget:buttons { gtable.join( + abutton({}, 1, nil, function() + if client == capi.client.focus then + client.minimized = true + else + client.minimized = false + if not client:isvisible() and client.first_tag then + client.first_tag:view_only() + end + client:emit_signal('request::activate') + client:raise() end + end), + + abutton({}, 3, function(c) + client:kill() + end) + ), } + + local label = User_config.taskbar_use_name and client.name or client.class or '' + + -- If the client is focused, show the tooltip and add a label + if client == capi.client.focus then + atooltip { + text = label, + objects = { task_widget }, + mode = 'outside', + preferred_alignments = 'middle', + preferred_positions = 'bottom', + margins = dpi(10), + delay_show = 1, } - btns[#btns + 1] = btn + task_widget:get_children_by_id('text_role')[1].text = label:sub(1, 20) + task_widget.bg = Theme_config.tasklist.bg_focus + task_widget.fg = Theme_config.tasklist.fg_focus + else + task_widget.bg = Theme_config.tasklist.bg + task_widget:get_children_by_id('text_role')[1].text = '' end - return btns + + hover.bg_hover { widget = task_widget } + + widget:add(task_widget) + widget:set_spacing(dpi(5)) end - end - task_widget:buttons(create_buttons(buttons, object)) - - local client_string = User_config.taskbar_use_name and object.name or object.class - - if object == capi.client.focus then - if client_string == nil or client_string == '' then - task_widget.container.layout_it.title:set_margins(0) - else - task_tool_tip:set_text(client_string) - task_tool_tip:add_to_object(task_widget) - task_widget.container.layout_it.title:set_text(client_string:sub(1, 20)) - end - task_widget:set_bg(Theme_config.tasklist.bg_focus) - task_widget:set_fg(Theme_config.tasklist.fg_focus) - else - task_widget:set_bg(Theme_config.tasklist.bg) - task_widget.container.layout_it.title:set_text('') - end - - Hover_signal(task_widget) - - widget:add(task_widget) - widget:set_spacing(dpi(6)) - end - return widget -end - -return function(s) - return awful.widget.tasklist( - s, - awful.widget.tasklist.filter.currenttags, - awful.util.table.join( - awful.button( - {}, - 1, - function(c) - if c == capi.client.focus then - c.minimized = true - else - c.minimized = false - if not c:isvisible() and c.first_tag then - c.first_tag:view_only() - end - c:emit_signal('request::activate') - c:raise() - end - end - ), - awful.button( - {}, - 3, - function(c) - c:kill() - end - ) - ), - {}, - list_update, - wibox.layout.fixed.horizontal() - ) -end + return widget + end, + } +end, }) diff --git a/awesome/todo.md b/awesome/todo.md index 36931db..2bc0a81 100644 --- a/awesome/todo.md +++ b/awesome/todo.md @@ -165,3 +165,8 @@ - Rewrite and try to make more performant ## Widgets + +## General + +- Constantly monitor for a bluetooth adapter to appear and then add the bluetooth module +- Probably the same with WiFi diff --git a/awesome/wibox/layout/fixed.lua b/awesome/wibox/layout/fixed.lua index 51522b4..7b34eed 100644 --- a/awesome/wibox/layout/fixed.lua +++ b/awesome/wibox/layout/fixed.lua @@ -23,6 +23,7 @@ -- @supermodule wibox.widget.base --------------------------------------------------------------------------- +---@diagnostic disable-next-line: deprecated local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) local base = require("wibox.widget.base") local table = table @@ -363,7 +364,7 @@ function fixed:fit(context, orig_width, orig_height) local is_enough if is_y then - is_enough = h > 0 and height_left >= h + is_enough = height_left >= h if is_enough then used_max = math.max(used_max, w)

+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