diff --git a/.config/awesome/configuration/apps.lua b/.config/awesome/configuration/apps.lua
new file mode 100644
index 0000000..246996a
--- /dev/null
+++ b/.config/awesome/configuration/apps.lua
@@ -0,0 +1,86 @@
+local filesystem = require('gears.filesystem')
+local config_dir = filesystem.get_configuration_dir()
+local utils_dir = config_dir .. 'utilities/'
+
+return {
+ -- The default applications that we will use in keybindings and widgets
+ default = {
+ -- Default terminal emulator
+ terminal = 'alacritty',
+ -- Default web browser
+ web_browser = 'firefox',
+ -- Default text editor
+ text_editor = 'subl3',
+ -- Default file manager
+ file_manager = 'dolphin',
+ -- Default media player
+ multimedia = 'vlc',
+ -- Default game, can be a launcher like steam
+ game = 'supertuxkart',
+ -- Default graphics editor
+ graphics = 'gimp-2.10',
+ -- Default sandbox
+ sandbox = 'virtualbox',
+ -- Default IDE
+ development = '',
+ -- Default network manager
+ network_manager = 'kitty iwctl',
+ -- Default bluetooth manager
+ bluetooth_manager = 'blueman-manager',
+ -- Default power manager
+ power_manager = 'xfce4-power-manager',
+ -- Default GUI package manager
+ package_manager = 'pamac-manager',
+ -- Default locker
+ lock = 'awesome-client "awesome.emit_signal(\'module::lockscreen_show\')"',
+ -- Default quake terminal
+ quake = 'alacritty --name QuakeTerminal',
+ -- Default rofi global menu
+ rofi_global = 'rofi -dpi ' .. screen.primary.dpi ..
+ ' -show "Global Search" -modi "Global Search":' .. config_dir ..
+ '/configuration/rofi/global/rofi-spotlight.sh' ..
+ ' -theme ' .. config_dir ..
+ '/configuration/rofi/global/rofi.rasi',
+ -- Default app menu
+ rofi_appmenu = 'rofi -dpi ' .. screen.primary.dpi ..
+ ' -show drun -theme ' .. config_dir ..
+ '/configuration/rofi/appmenu/rofi.rasi'
+
+ -- You can add more default applications here
+ },
+
+ -- List of apps to start once on start-up
+ run_on_start_up = {
+ -- Compositor
+ 'picom -b --experimental-backends --dbus --config ' ..
+ config_dir .. '/configuration/picom.conf',
+ -- Blueman applet
+ 'blueman-applet',
+ -- Music server
+ 'mpd',
+ -- Polkit and keyring
+ '/usr/bin/lxqt-policykit-agent &' ..
+ ' eval $(gnome-keyring-daemon -s --components=pkcs11,secrets,ssh,gpg)',
+ -- Load X colors
+ 'xrdb $HOME/.Xresources',
+ -- Audio equalizer
+ 'pulseeffects --gapplication-service',
+ -- Lockscreen timer
+ [[
+ xidlehook --not-when-fullscreen --not-when-audio --timer 600 \
+ "awesome-client 'awesome.emit_signal(\"module::lockscreen_show\")'" ""
+ ]]
+
+ -- You can add more start-up applications here
+ },
+
+ -- List of binaries/shell scripts that will execute for a certain task
+ utils = {
+ -- Fullscreen screenshot
+ full_screenshot = utils_dir .. 'snap full',
+ -- Area screenshot
+ area_screenshot = utils_dir .. 'snap area',
+ -- Update profile picture
+ update_profile = utils_dir .. 'profile-image'
+ }
+}
diff --git a/.config/awesome/configuration/client/buttons.lua b/.config/awesome/configuration/client/buttons.lua
new file mode 100644
index 0000000..e744393
--- /dev/null
+++ b/.config/awesome/configuration/client/buttons.lua
@@ -0,0 +1,37 @@
+local awful = require('awful')
+local modkey = require('configuration.keys.mod').mod_key
+
+return awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function(c)
+ c:emit_signal('request::activate')
+ c:raise()
+ end
+ ),
+ awful.button(
+ {modkey},
+ 1,
+ awful.mouse.client.move
+ ),
+ awful.button(
+ {modkey},
+ 3,
+ awful.mouse.client.resize
+ ),
+ awful.button(
+ {modkey},
+ 4,
+ function()
+ awful.layout.inc(1)
+ end
+ ),
+ awful.button(
+ {modkey},
+ 5,
+ function()
+ awful.layout.inc(-1)
+ end
+ )
+)
diff --git a/.config/awesome/configuration/client/init.lua b/.config/awesome/configuration/client/init.lua
new file mode 100644
index 0000000..a5bc872
--- /dev/null
+++ b/.config/awesome/configuration/client/init.lua
@@ -0,0 +1,2 @@
+require('configuration.client.rules')
+require('configuration.client.signals')
diff --git a/.config/awesome/configuration/client/keys.lua b/.config/awesome/configuration/client/keys.lua
new file mode 100644
index 0000000..3182e41
--- /dev/null
+++ b/.config/awesome/configuration/client/keys.lua
@@ -0,0 +1,216 @@
+local awful = require('awful')
+local gears = require('gears')
+local dpi = require('beautiful').xresources.apply_dpi
+require('awful.autofocus')
+local modkey = require('configuration.keys.mod').mod_key
+local altkey = require('configuration.keys.mod').alt_key
+
+local client_keys = awful.util.table.join(
+ awful.key(
+ {modkey},
+ 'f',
+ function(c)
+ c.fullscreen = not c.fullscreen
+ c:raise()
+ end,
+ {description = 'toggle fullscreen', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'q',
+ function(c)
+ c:kill()
+ end,
+ {description = 'close', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'd',
+ function()
+ awful.client.focus.byidx(1)
+ end,
+ {description = 'focus next by index', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'a',
+ function()
+ awful.client.focus.byidx(-1)
+ end,
+ {description = 'focus previous by index', group = 'client'}
+ ),
+ awful.key(
+ { modkey, 'Shift' },
+ 'd',
+ function ()
+ awful.client.swap.byidx(1)
+ end,
+ {description = 'swap with next client by index', group = 'client'}
+ ),
+ awful.key(
+ { modkey, 'Shift' },
+ 'a',
+ function ()
+ awful.client.swap.byidx(-1)
+ end,
+ {description = 'swap with next client by index', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'u',
+ awful.client.urgent.jumpto,
+ {description = 'jump to urgent client', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Tab',
+ function()
+ awful.client.focus.history.previous()
+ if client.focus then
+ client.focus:raise()
+ end
+ end,
+ {description = 'go back', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'n',
+ function(c)
+ c.minimized = true
+ end,
+ {description = 'minimize client', group = 'client'}
+ ),
+ awful.key(
+ { modkey, 'Shift' },
+ 'c',
+ function(c)
+ local focused = awful.screen.focused()
+
+ awful.placement.centered(c, {
+ honor_workarea = true
+ })
+ end,
+ {description = 'align a client to the center of the focused screen', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'c',
+ function(c)
+ c.fullscreen = false
+ c.maximized = false
+ c.floating = not c.floating
+ c:raise()
+ end,
+ {description = 'toggle floating', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Up',
+ function(c)
+ c:relative_move(0, dpi(-10), 0, 0)
+ end,
+ {description = 'move floating client up by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Down',
+ function(c)
+ c:relative_move(0, dpi(10), 0, 0)
+ end,
+ {description = 'move floating client down by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Left',
+ function(c)
+ c:relative_move(dpi(-10), 0, 0, 0)
+ end,
+ {description = 'move floating client to the left by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Right',
+ function(c)
+ c:relative_move(dpi(10), 0, 0, 0)
+ end,
+ {description = 'move floating client to the right by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Up',
+ function(c)
+ c:relative_move(0, dpi(-10), 0, dpi(10))
+ end,
+ {description = 'increase floating client size vertically by 10 px up', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Down',
+ function(c)
+ c:relative_move(0, 0, 0, dpi(10))
+ end,
+ {description = 'increase floating client size vertically by 10 px down', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Left',
+ function(c)
+ c:relative_move(dpi(-10), 0, dpi(10), 0)
+ end,
+ {description = 'increase floating client size horizontally by 10 px left', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Right',
+ function(c)
+ c:relative_move(0, 0, dpi(10), 0)
+ end,
+ {description = 'increase floating client size horizontally by 10 px right', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'Up',
+ function(c)
+ if c.height > 10 then
+ c:relative_move(0, 0, 0, dpi(-10))
+ end
+ end,
+ {description = 'decrease floating client size vertically by 10 px up', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'Down',
+ function(c)
+ local c_height = c.height
+ c:relative_move(0, 0, 0, dpi(-10))
+ if c.height ~= c_height and c.height > 10 then
+ c:relative_move(0, dpi(10), 0, 0)
+ end
+ end,
+ {description = 'decrease floating client size vertically by 10 px down', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'Left',
+ function(c)
+ if c.width > 10 then
+ c:relative_move(0, 0, dpi(-10), 0)
+ end
+ end,
+ {description = 'decrease floating client size horizontally by 10 px left', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'Right',
+ function(c)
+ local c_width = c.width
+ c:relative_move(0, 0, dpi(-10), 0)
+ if c.width ~= c_width and c.width > 10 then
+ c:relative_move(dpi(10), 0 , 0, 0)
+ end
+ end,
+ {description = 'decrease floating client size horizontally by 10 px right', group = 'client'}
+ )
+)
+
+return client_keys
diff --git a/.config/awesome/configuration/client/rules.lua b/.config/awesome/configuration/client/rules.lua
new file mode 100644
index 0000000..0ab0b11
--- /dev/null
+++ b/.config/awesome/configuration/client/rules.lua
@@ -0,0 +1,393 @@
+local awful = require('awful')
+local gears = require('gears')
+local ruled = require('ruled')
+local beautiful = require('beautiful')
+local client_keys = require('configuration.client.keys')
+local client_buttons = require('configuration.client.buttons')
+
+ruled.client.connect_signal(
+ 'request::rules',
+ function()
+ -- All clients will match this rule.
+ ruled.client.append_rule {
+ id = 'global',
+ rule = {},
+ properties = {
+ focus = awful.client.focus.filter,
+ raise = true,
+ floating = false,
+ maximized = false,
+ above = false,
+ below = false,
+ ontop = false,
+ sticky = false,
+ maximized_horizontal = false,
+ maximized_vertical = false,
+ keys = client_keys,
+ buttons = client_buttons,
+ screen = awful.screen.preferred,
+ placement = awful.placement.no_overlap + awful.placement.no_offscreen
+ }
+ }
+
+ ruled.client.append_rule {
+ id = 'round_clients',
+ rule_any = {
+ type = {
+ 'normal',
+ 'dialog'
+ }
+ },
+ except_any = {
+ name = {'Discord Updater'}
+ },
+ properties = {
+ round_corners = true,
+ shape = beautiful.client_shape_rounded
+ }
+ }
+
+ -- Titlebar rules
+ ruled.client.append_rule {
+ id = 'titlebars',
+ rule_any = {
+ type = {
+ 'normal',
+ 'dialog',
+ 'modal',
+ 'utility'
+ }
+ },
+ properties = {
+ titlebars_enabled = true
+ }
+ }
+
+ -- Dialogs
+ ruled.client.append_rule {
+ id = 'dialog',
+ rule_any = {
+ type = {'dialog'},
+ class = {'Wicd-client.py', 'calendar.google.com'}
+ },
+ properties = {
+ titlebars_enabled = true,
+ floating = true,
+ above = true,
+ skip_decoration = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Modals
+ ruled.client.append_rule {
+ id = 'modal',
+ rule_any = {
+ type = {'modal'}
+ },
+ properties = {
+ titlebars_enabled = true,
+ floating = true,
+ above = true,
+ skip_decoration = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Utilities
+ ruled.client.append_rule {
+ id = 'utility',
+ rule_any = {
+ type = {'utility'}
+ },
+ properties = {
+ titlebars_enabled = false,
+ floating = true,
+ skip_decoration = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Splash
+ ruled.client.append_rule {
+ id = 'splash',
+ rule_any = {
+ type = {'splash'},
+ name = {'Discord Updater'}
+ },
+ properties = {
+ titlebars_enabled = false,
+ round_corners = false,
+ floating = true,
+ above = true,
+ skip_decoration = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Terminal emulators
+ ruled.client.append_rule {
+ id = 'terminals',
+ rule_any = {
+ class = {
+ 'URxvt',
+ 'XTerm',
+ 'UXTerm',
+ 'kitty',
+ 'K3rmit'
+ }
+ },
+ properties = {
+ tag = '1',
+ switch_to_tags = true,
+ size_hints_honor = false,
+ titlebars_enabled = true
+ }
+ }
+
+ -- Browsers and chats
+ ruled.client.append_rule {
+ id = 'internet',
+ rule_any = {
+ class = {
+ 'firefox',
+ 'Tor Browser',
+ 'discord',
+ 'Chromium',
+ 'Google-chrome',
+ 'TelegramDesktop'
+ }
+ },
+ properties = {
+ tag = '2'
+ }
+ }
+
+ -- Text editors and word processing
+ ruled.client.append_rule {
+ id = 'text',
+ rule_any = {
+ class = {
+ 'Geany',
+ 'Atom',
+ 'Subl3',
+ 'code-oss'
+ },
+ name = {
+ 'LibreOffice',
+ 'libreoffice'
+ }
+ },
+ properties = {
+ tag = '3'
+ }
+ }
+
+ -- File managers
+ ruled.client.append_rule {
+ id = 'files',
+ rule_any = {
+ class = {
+ 'dolphin',
+ 'ark',
+ 'Nemo',
+ 'File-roller'
+ }
+ },
+ properties = {
+ tag = '4',
+ switch_to_tags = true
+ }
+ }
+
+ -- Multimedia
+ ruled.client.append_rule {
+ id = 'multimedia',
+ rule_any = {
+ class = {
+ 'vlc',
+ 'Spotify'
+ }
+ },
+ properties = {
+ tag = '5',
+ switch_to_tags = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Gaming
+ ruled.client.append_rule {
+ id = 'gaming',
+ rule_any = {
+ class = {
+ 'Wine',
+ 'dolphin-emu',
+ 'Steam',
+ 'Citra',
+ 'supertuxkart'
+ },
+ name = {'Steam'}
+ },
+ properties = {
+ tag = '6',
+ skip_decoration = true,
+ switch_to_tags = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Multimedia Editing
+ ruled.client.append_rule {
+ id = 'graphics',
+ rule_any = {
+ class = {
+ 'Gimp-2.10',
+ 'Inkscape',
+ 'Flowblade'
+ }
+ },
+ properties = {
+ tag = '7'
+ }
+ }
+
+ -- Sandboxes and VMs
+ ruled.client.append_rule {
+ id = 'sandbox',
+ rule_any = {
+ class = {
+ 'VirtualBox Manage',
+ 'VirtualBox Machine',
+ 'Gnome-boxes',
+ 'Virt-manager'
+ }
+ },
+ properties = {
+ tag = '8'
+ }
+ }
+
+ -- IDEs and Tools
+ ruled.client.append_rule {
+ id = 'development',
+ rule_any = {
+ class = {
+ 'Oomox',
+ 'Unity',
+ 'UnityHub',
+ 'jetbrains-studio',
+ 'Ettercap',
+ 'scrcpy'
+ }
+ },
+ properties = {
+ tag = '9',
+ skip_decoration = true
+ }
+ }
+
+ -- Image viewers
+ ruled.client.append_rule {
+ id = 'image_viewers',
+ rule_any = {
+ class = {
+ 'feh',
+ 'Pqiv',
+ 'Sxiv'
+ },
+ },
+ properties = {
+ titlebars_enabled = true,
+ skip_decoration = true,
+ floating = true,
+ ontop = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Floating
+ ruled.client.append_rule {
+ id = 'floating',
+ rule_any = {
+ instance = {
+ 'file_progress',
+ 'Popup',
+ 'nm-connection-editor',
+ },
+ class = {
+ 'scrcpy',
+ 'Mugshot',
+ 'Pulseeffects'
+ },
+ role = {
+ 'AlarmWindow',
+ 'ConfigManager',
+ 'pop-up'
+ }
+ },
+ properties = {
+ titlebars_enabled = true,
+ skip_decoration = true,
+ ontop = true,
+ floating = true,
+ focus = awful.client.focus.filter,
+ raise = true,
+ keys = client_keys,
+ buttons = client_buttons,
+ placement = awful.placement.centered
+ }
+ }
+ end
+)
+
+-- Normally we'd do this with a rule, but some program like spotify doesn't set its class or name
+-- until after it starts up, so we need to catch that signal.
+client.connect_signal(
+ 'property::class',
+ function(c)
+ if c.class == 'Spotify' then
+ local window_mode = false
+
+ -- Check if fullscreen or window mode
+ if c.fullscreen then
+ window_mode = false
+ c.fullscreen = false
+ else
+ window_mode = true
+ end
+
+ -- Check if Spotify is already open
+ local app = function (c)
+ return ruled.client.match(c, {class = 'Spotify'})
+ end
+
+ local app_count = 0
+ for c in awful.client.iterate(app) do
+ app_count = app_count + 1
+ end
+
+ -- If Spotify is already open, don't open a new instance
+ if app_count > 1 then
+ c:kill()
+ -- Switch to previous instance
+ for c in awful.client.iterate(app) do
+ c:jump_to(false)
+ end
+ else
+ -- Move the instance to specified tag on this screen
+ local t = awful.tag.find_by_name(awful.screen.focused(), '5')
+ c:move_to_tag(t)
+ t:view_only()
+
+ -- Fullscreen mode if not window mode
+ if not window_mode then
+ c.fullscreen = true
+ else
+ c.floating = true
+ awful.placement.centered(c, {honor_workarea = true})
+ end
+ end
+ end
+ end
+)
diff --git a/.config/awesome/configuration/client/signals.lua b/.config/awesome/configuration/client/signals.lua
new file mode 100644
index 0000000..a13a4aa
--- /dev/null
+++ b/.config/awesome/configuration/client/signals.lua
@@ -0,0 +1,115 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local update_client = function(c)
+ -- Set client's shape based on its tag's layout and status (floating, maximized, etc.)
+ local current_layout = awful.tag.getproperty(c.first_tag, 'layout')
+ if current_layout == awful.layout.suit.max and (not c.floating) then
+ c.shape = beautiful.client_shape_rectangle
+ elseif c.maximized or c.fullscreen then
+ c.shape = beautiful.client_shape_rectangle
+ elseif (not c.round_corners) then
+ c.shape = beautiful.client_shape_rectangle
+ else
+ c.shape = beautiful.client_shape_rounded
+ end
+end
+
+-- Signal function to execute when a new client appears.
+client.connect_signal(
+ 'manage',
+ function(c)
+ -- Focus, raise and activate
+ c:emit_signal(
+ 'request::activate',
+ 'mouse_enter',
+ {
+ raise = true
+ }
+ )
+
+ -- Set the windows at the slave,
+ -- i.e. put it at the end of others instead of setting it master.
+ if not awesome.startup then
+ awful.client.setslave(c)
+ end
+
+ if awesome.startup and not c.size_hints.user_position and
+ not c.size_hints.program_position then
+ -- Prevent clients from being unreachable after screen count changes.
+ awful.placement.no_offscreen(c)
+ end
+
+ -- Update client shape
+ update_client(c)
+ end
+)
+
+-- Enable sloppy focus, so that focus follows mouse then raises it.
+client.connect_signal(
+ 'mouse::enter',
+ function(c)
+ c:emit_signal(
+ 'request::activate',
+ 'mouse_enter',
+ {
+ raise = true
+ }
+ )
+ end
+)
+
+client.connect_signal(
+ 'focus',
+ function(c)
+ c.border_color = beautiful.border_focus
+ end
+)
+
+client.connect_signal(
+ 'unfocus',
+ function(c)
+ c.border_color = beautiful.border_normal
+ end
+)
+
+-- Manipulate client shape on fullscreen/non-fullscreen
+client.connect_signal(
+ 'property::fullscreen',
+ function(c)
+ if c.fullscreen then
+ c.shape = beautiful.client_shape_rectangle
+ else
+ update_client(c)
+ end
+ end
+)
+
+-- Manipulate client shape on maximized
+client.connect_signal(
+ 'property::maximized',
+ function(c)
+ local current_layout = awful.tag.getproperty(c.first_tag, 'layout')
+ if c.maximized then
+ c.shape = beautiful.client_shape_rectangle
+ else
+ update_client(c)
+ end
+ end
+)
+
+-- Manipulate client shape on floating
+client.connect_signal(
+ 'property::floating',
+ function(c)
+ local current_layout = awful.tag.getproperty(c.first_tag, 'layout')
+ if c.floating and not c.maximized then
+ c.shape = beautiful.client_shape_rounded
+ else
+ if current_layout == awful.layout.suit.max then
+ c.shape = beautiful.client_shape_rectangle
+ end
+ end
+ end
+)
diff --git a/.config/awesome/configuration/config.lua b/.config/awesome/configuration/config.lua
new file mode 100644
index 0000000..7bc752d
--- /dev/null
+++ b/.config/awesome/configuration/config.lua
@@ -0,0 +1,103 @@
+return {
+ widget = {
+ email = {
+ -- Email address
+ address = '',
+ -- App password
+ app_password = '',
+ -- Imap server
+ imap_server = 'imap.gmail.com',
+ -- Port
+ port = '993'
+ },
+
+ weather = {
+ -- API Key
+ key = '67784a48d58d4cab5beb5d7f1b03a4ce',
+ -- City ID
+ city_id = '2153953',
+ -- Units
+ units = 'metric',
+ -- Update in N seconds
+ update_interval = 1200
+ },
+
+ network = {
+ -- Wired interface
+ wired_interface = 'enp34s0',
+ -- Wireless interface
+ wireless_interface = 'wlan0'
+ },
+
+ clock = {
+ -- Clock widget format
+ military_mode = false
+ },
+
+ screen_recorder = {
+ -- Default record dimension
+ resolution = '1366x768',
+ -- X,Y coordinate
+ offset = '0,0',
+ -- Enable audio by default
+ audio = false,
+ -- Recordings directory
+ save_directory = '$(xdg-user-dir VIDEOS)/Recordings/',
+ -- Mic level
+ mic_level = '20',
+ -- FPS
+ fps = '30'
+ }
+ },
+
+ module = {
+ auto_start = {
+ -- Will create notification if true
+ debug_mode = false
+ },
+
+ dynamic_wallpaper = {
+ -- Will look for wallpapers here
+ wall_dir = 'theme/wallpapers/',
+ -- Image formats
+ valid_picture_formats = {'jpg', 'png', 'jpeg'},
+ -- Leave this table empty for full auto scheduling
+ wallpaper_schedule = {
+ ['00:00:00'] = 'midnight-wallpaper.jpg',
+ ['06:22:00'] = 'morning-wallpaper.jpg',
+ ['12:00:00'] = 'noon-wallpaper.jpg',
+ ['17:58:00'] = 'night-wallpaper.jpg'
+ -- Example of just using auto-scheduling with keywords
+ --[[
+ 'midnight',
+ 'morning',
+ 'noon',
+ 'afternoon',
+ 'evening',
+ 'night'
+ --]]
+ },
+ -- Stretch background image across all screens(monitor)
+ stretch = true
+ },
+
+ lockscreen = {
+ -- Clock format
+ military_clock = false,
+ -- Default password if there's no PAM integration
+ fallback_password = 'toor',
+ -- Capture intruder using webcam
+ capture_intruder = true,
+ -- Intruder image save location (Will create directory if it doesn't exist)
+ face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/',
+ -- Background directory - Defaults to 'awesome/config/theme/wallpapers/' if null
+ bg_dir = nil,
+ -- Will look for this image file under 'bg_dir'
+ bg_image = 'locksreen-bg.jpg',
+ -- Blur lockscreen background
+ blur_background = false,
+ -- Blurred/filtered background image path (No reason to change this)
+ tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/'
+ }
+ }
+}
diff --git a/.config/awesome/configuration/config.lua.broken b/.config/awesome/configuration/config.lua.broken
new file mode 100644
index 0000000..76b4f4c
--- /dev/null
+++ b/.config/awesome/configuration/config.lua.broken
@@ -0,0 +1,103 @@
+return {
+ widget = {
+ email = {
+ -- Email address
+ address = '',
+ -- App password
+ app_password = '',
+ -- Imap server
+ imap_server = 'imap.gmail.com',
+ -- Port
+ port = '993'
+ },
+
+ weather = {
+ -- API Key
+ key = '67784a48d58d4cab5beb5d7f1b03a4ce',
+ -- City ID
+ city_id = '2153953',
+ -- Units
+ units = 'metric',
+ -- Update in N seconds
+ update_interval = 1200
+ },
+
+ network = {
+ -- Wired interface
+ wired_interface = 'enp34s0',
+ -- Wireless interface
+ wireless_interface = 'wlan0'
+ },
+
+ clock = {
+ -- Clock widget format
+ military_mode = false
+ },
+
+ screen_recorder = {
+ -- Default record dimension
+ resolution = '1366x768',
+ -- X,Y coordinate
+ offset = '0,0',
+ -- Enable audio by default
+ audio = false,
+ -- Recordings directory
+ save_directory = '$(xdg-user-dir VIDEOS)/Recordings/',
+ -- Mic level
+ mic_level = '20',
+ -- FPS
+ fps = '30'
+ }
+ },
+
+ module = {
+ auto_start = {
+ -- Will create notification if true
+ debug_mode = true
+ },
+
+ -- dynamic_wallpaper = {
+ -- -- Will look for wallpapers here
+ -- wall_dir = 'theme/wallpapers/',
+ -- -- Image formats
+ -- valid_picture_formats = {'jpg', 'png', 'jpeg'},
+ -- -- Leave this table empty for full auto scheduling
+ -- wallpaper_schedule = {
+ -- ['00:00:00'] = 'midnight-wallpaper.jpg',
+ -- ['06:22:00'] = 'morning-wallpaper.jpg',
+ -- ['12:00:00'] = 'noon-wallpaper.jpg',
+ -- ['17:58:00'] = 'night-wallpaper.jpg'
+ -- -- Example of just using auto-scheduling with keywords
+ -- --[[
+ -- 'midnight',
+ -- 'morning',
+ -- 'noon',
+ -- 'afternoon',
+ -- 'evening',
+ -- 'night'
+ -- --]]
+ -- },
+ -- -- Stretch background image across all screens(monitor)
+ -- stretch = true
+ -- },
+
+ lockscreen = {
+ -- Clock format
+ military_clock = false,
+ -- Default password if there's no PAM integration
+ fallback_password = 'toor',
+ -- Capture intruder using webcam
+ capture_intruder = true,
+ -- Intruder image save location (Will create directory if it doesn't exist)
+ face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/',
+ -- Background directory - Defaults to 'awesome/config/theme/wallpapers/' if null
+ bg_dir = nil,
+ -- Will look for this image file under 'bg_dir'
+ bg_image = 'locksreen-bg.jpg',
+ -- Blur lockscreen background
+ blur_background = false,
+ -- Blurred/filtered background image path (No reason to change this)
+ tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/'
+ }
+ }
+}
diff --git a/.config/awesome/configuration/init.lua b/.config/awesome/configuration/init.lua
new file mode 100644
index 0000000..f93e86b
--- /dev/null
+++ b/.config/awesome/configuration/init.lua
@@ -0,0 +1,4 @@
+return {
+ keys = require('configuration.keys'),
+ apps = require('configuration.apps')
+}
diff --git a/.config/awesome/configuration/keys/global.lua b/.config/awesome/configuration/keys/global.lua
new file mode 100644
index 0000000..90ad1f2
--- /dev/null
+++ b/.config/awesome/configuration/keys/global.lua
@@ -0,0 +1,606 @@
+local awful = require('awful')
+local beautiful = require('beautiful')
+
+require('awful.autofocus')
+
+local hotkeys_popup = require('awful.hotkeys_popup').widget
+
+local modkey = require('configuration.keys.mod').mod_key
+local altkey = require('configuration.keys.mod').alt_key
+local apps = require('configuration.apps')
+
+-- Key bindings
+local global_keys = awful.util.table.join(
+
+ -- Hotkeys
+ awful.key(
+ {modkey},
+ 'F1',
+ hotkeys_popup.show_help,
+ {description = 'show help', group = 'awesome'}
+ ),
+ awful.key({modkey, 'Control'},
+ 'r',
+ awesome.restart,
+ {description = 'reload awesome', group = 'awesome'}
+ ),
+
+ awful.key({modkey, 'Control'},
+ 'q',
+ awesome.quit,
+ {description = 'quit awesome', group = 'awesome'}
+ ),
+ awful.key(
+ {altkey, 'Shift'},
+ 'l',
+ function()
+ awful.tag.incmwfact(0.05)
+ end,
+ {description = 'increase master width factor', group = 'layout'}
+ ),
+ awful.key(
+ {altkey, 'Shift'},
+ 'h',
+ function()
+ awful.tag.incmwfact(-0.05)
+ end,
+ {description = 'decrease master width factor', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'h',
+ function()
+ awful.tag.incnmaster(1, nil, true)
+ end,
+ {description = 'increase the number of master clients', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'l',
+ function()
+ awful.tag.incnmaster(-1, nil, true)
+ end,
+ {description = 'decrease the number of master clients', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'h',
+ function()
+ awful.tag.incncol(1, nil, true)
+ end,
+ {description = 'increase the number of columns', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'l',
+ function()
+ awful.tag.incncol(-1, nil, true)
+ end,
+ {description = 'decrease the number of columns', group = 'layout'}
+ ),
+ awful.key(
+ {modkey},
+ 'space',
+ function()
+ awful.layout.inc(1)
+ end,
+ {description = 'select next layout', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'space',
+ function()
+ awful.layout.inc(-1)
+ end,
+ {description = 'select previous layout', group = 'layout'}
+ ),
+ awful.key(
+ {modkey},
+ 'o',
+ function()
+ awful.tag.incgap(1)
+ end,
+ {description = 'increase gap', group = 'layout'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'o',
+ function()
+ awful.tag.incgap(-1)
+ end,
+ {description = 'decrease gap', group = 'layout'}
+ ),
+ awful.key(
+ {modkey},
+ 'w',
+ awful.tag.viewprev,
+ {description = 'view previous tag', group = 'tag'}
+ ),
+ awful.key(
+ {modkey},
+ 's',
+ awful.tag.viewnext,
+ {description = 'view next tag', group = 'tag'}
+ ),
+ awful.key(
+ {modkey},
+ 'Escape',
+ awful.tag.history.restore,
+ {description = 'alternate between current and previous tag', group = 'tag'}
+ ),
+ awful.key({ modkey, 'Control' },
+ 'w',
+ function ()
+ -- tag_view_nonempty(-1)
+ local focused = awful.screen.focused()
+ for i = 1, #focused.tags do
+ awful.tag.viewidx(-1, focused)
+ if #focused.clients > 0 then
+ return
+ end
+ end
+ end,
+ {description = 'view previous non-empty tag', group = 'tag'}
+ ),
+ awful.key({ modkey, 'Control' },
+ 's',
+ function ()
+ -- tag_view_nonempty(1)
+ local focused = awful.screen.focused()
+ for i = 1, #focused.tags do
+ awful.tag.viewidx(1, focused)
+ if #focused.clients > 0 then
+ return
+ end
+ end
+ end,
+ {description = 'view next non-empty tag', group = 'tag'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'F1',
+ function()
+ awful.screen.focus_relative(-1)
+ end,
+ { description = 'focus the previous screen', group = 'screen'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'F2',
+ function()
+ awful.screen.focus_relative(1)
+ end,
+ { description = 'focus the next screen', group = 'screen'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'n',
+ function()
+ local c = awful.client.restore()
+ -- Focus restored client
+ if c then
+ c:emit_signal('request::activate')
+ c:raise()
+ end
+ end,
+ {description = 'restore minimized', group = 'screen'}
+ ),
+ awful.key(
+ {},
+ 'XF86MonBrightnessUp',
+ function()
+ awful.spawn('light -A 10', false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show', true)
+ end,
+ {description = 'increase brightness by 10%', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86MonBrightnessDown',
+ function()
+ awful.spawn('light -U 10', false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show', true)
+ end,
+ {description = 'decrease brightness by 10%', group = 'hotkeys'}
+ ),
+ -- ALSA volume control
+ awful.key(
+ {},
+ 'XF86AudioRaiseVolume',
+ function()
+ awful.spawn('amixer -D pulse sset Master 5%+', false)
+ awesome.emit_signal('widget::volume')
+ awesome.emit_signal('module::volume_osd:show', true)
+ end,
+ {description = 'increase volume up by 5%', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86AudioLowerVolume',
+ function()
+ awful.spawn('amixer -D pulse sset Master 5%-', false)
+ awesome.emit_signal('widget::volume')
+ awesome.emit_signal('module::volume_osd:show', true)
+ end,
+ {description = 'decrease volume up by 5%', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86AudioMute',
+ function()
+ awful.spawn('amixer -D pulse set Master 1+ toggle', false)
+ end,
+ {description = 'toggle mute', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86AudioNext',
+ function()
+ awful.spawn('mpc next', false)
+ end,
+ {description = 'next music', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86AudioPrev',
+ function()
+ awful.spawn('mpc prev', false)
+ end,
+ {description = 'previous music', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86AudioPlay',
+ function()
+ awful.spawn('mpc toggle', false)
+ end,
+ {description = 'play/pause music', group = 'hotkeys'}
+
+ ),
+ awful.key(
+ {},
+ 'XF86AudioMicMute',
+ function()
+ awful.spawn('amixer set Capture toggle', false)
+ end,
+ {description = 'mute microphone', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86PowerDown',
+ function()
+ --
+ end,
+ {description = 'shutdown skynet', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86PowerOff',
+ function()
+ awesome.emit_signal('module::exit_screen:show')
+ end,
+ {description = 'toggle exit screen', group = 'hotkeys'}
+ ),
+ awful.key(
+ {},
+ 'XF86Display',
+ function()
+ awful.spawn.single_instance('arandr', false)
+ end,
+ {description = 'arandr', group = 'hotkeys'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'q',
+ function()
+ awesome.emit_signal('module::exit_screen:show')
+ end,
+ {description = 'toggle exit screen', group = 'hotkeys'}
+ ),
+ awful.key(
+ {modkey},
+ '`',
+ function()
+ awesome.emit_signal('module::quake_terminal:toggle')
+ end,
+ {description = 'dropdown application', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey},
+ 'm',
+ function()
+ if awful.screen.focused().musicpop then
+ awesome.emit_signal('widget::music', 'keyboard')
+ end
+ end,
+ {description = 'toggle music widget', group = 'launcher'}
+ ),
+ awful.key(
+ { },
+ 'Print',
+ function ()
+ -- awful.spawn.easy_async_with_shell(apps.utils.full_screenshot,function() end)
+ awful.util.spawn("flameshot gui")
+ end,
+ {description = 'fullscreen screenshot', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 's',
+ function ()
+ awful.spawn.easy_async_with_shell(apps.utils.area_screenshot,function() end)
+ end,
+ {description = 'area/selected screenshot', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ 'x',
+ function()
+ awesome.emit_signal('widget::blur:toggle')
+ end,
+ {description = 'toggle blur effects', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ ']',
+ function()
+ awesome.emit_signal('widget::blur:increase')
+ end,
+ {description = 'increase blur effect by 10%', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ '[',
+ function()
+ awesome.emit_signal('widget::blur:decrease')
+ end,
+ {description = 'decrease blur effect by 10%', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ 't',
+ function()
+ awesome.emit_signal('widget::blue_light:toggle')
+ end,
+ {description = 'toggle redshift filter', group = 'Utility'}
+ ),
+ awful.key(
+ { 'Control' },
+ 'Escape',
+ function ()
+ if screen.primary.systray then
+ if not screen.primary.tray_toggler then
+ local systray = screen.primary.systray
+ systray.visible = not systray.visible
+ else
+ awesome.emit_signal('widget::systray:toggle')
+ end
+ end
+ end,
+ {description = 'toggle systray visibility', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ 'l',
+ function()
+ awful.spawn(apps.default.lock, false)
+ end,
+ {description = 'lock the screen', group = 'Utility'}
+ ),
+ awful.key(
+ {modkey},
+ 'Return',
+ function()
+ awful.spawn(apps.default.terminal)
+ end,
+ {description = 'open default terminal', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'e',
+ function()
+ awful.spawn(apps.default.file_manager)
+ end,
+ {description = 'open default file manager', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'f',
+ function()
+ awful.spawn(apps.default.web_browser)
+ end,
+ {description = 'open default web browser', group = 'launcher'}
+ ),
+ awful.key(
+ {'Control', 'Shift'},
+ 'Escape',
+ function()
+ awful.spawn(apps.default.terminal .. ' ' .. 'htop')
+ end,
+ {description = 'open system monitor', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey},
+ 'e',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.left_panel then
+ focused.left_panel:hide_dashboard()
+ focused.left_panel.opened = false
+ end
+ if focused.right_panel then
+ focused.right_panel:hide_dashboard()
+ focused.right_panel.opened = false
+ end
+ awful.spawn(apps.default.rofi_appmenu, false)
+ end,
+ {description = 'open application drawer', group = 'launcher'}
+ ),
+ awful.key(
+ {},
+ 'XF86Launch1',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.left_panel then
+ focused.left_panel:hide_dashboard()
+ focused.left_panel.opened = false
+ end
+ if focused.right_panel then
+ focused.right_panel:hide_dashboard()
+ focused.right_panel.opened = false
+ end
+ awful.spawn(apps.default.rofi_appmenu, false)
+ end,
+ {description = 'open application drawer', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey},
+ 'r',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.right_panel and focused.right_panel.visible then
+ focused.right_panel.visible = false
+ end
+ screen.primary.left_panel:toggle()
+ end,
+ {description = 'open sidebar', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'r',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.right_panel and focused.right_panel.visible then
+ focused.right_panel.visible = false
+ end
+ screen.primary.left_panel:toggle(true)
+ end,
+ {description = 'open sidebar and global search', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey},
+ 'F2',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.left_panel and focused.left_panel.opened then
+ focused.left_panel:toggle()
+ end
+
+ if focused.right_panel then
+ if _G.right_panel_mode == 'today_mode' or not focused.right_panel.visible then
+ focused.right_panel:toggle()
+ switch_rdb_pane('today_mode')
+ else
+ switch_rdb_pane('today_mode')
+ end
+
+ _G.right_panel_mode = 'today_mode'
+ end
+ end,
+ {description = 'open today pane', group = 'launcher'}
+ ),
+ awful.key(
+ {modkey},
+ 'F3',
+ function()
+ local focused = awful.screen.focused()
+
+ if focused.left_panel and focused.left_panel.opened then
+ focused.left_panel:toggle()
+ end
+
+ if focused.right_panel then
+ if _G.right_panel_mode == 'notif_mode' or not focused.right_panel.visible then
+ focused.right_panel:toggle()
+ switch_rdb_pane('notif_mode')
+ else
+ switch_rdb_pane('notif_mode')
+ end
+
+ _G.right_panel_mode = 'notif_mode'
+ end
+ end,
+ {description = 'open notification center', group = 'launcher'}
+ )
+)
+
+-- Bind all key numbers to tags.
+-- Be careful: we use keycodes to make it work on any keyboard layout.
+-- This should map on the top row of your keyboard, usually 1 to 9.
+for i = 1, 9 do
+ -- Hack to only show tags 1 and 9 in the shortcut window (mod+s)
+ local descr_view, descr_toggle, descr_move, descr_toggle_focus
+ if i == 1 or i == 9 then
+ descr_view = {description = 'view tag #', group = 'tag'}
+ descr_toggle = {description = 'toggle tag #', group = 'tag'}
+ descr_move = {description = 'move focused client to tag #', group = 'tag'}
+ descr_toggle_focus = {description = 'toggle focused client on tag #', group = 'tag'}
+ end
+ global_keys =
+ awful.util.table.join(
+ global_keys,
+ -- View tag only.
+ awful.key(
+ {modkey},
+ '#' .. i + 9,
+ function()
+ local focused = awful.screen.focused()
+ local tag = focused.tags[i]
+ if tag then
+ tag:view_only()
+ end
+ end,
+ descr_view
+ ),
+ -- Toggle tag display.
+ awful.key(
+ {modkey, 'Control'},
+ '#' .. i + 9,
+ function()
+ local focused = awful.screen.focused()
+ local tag = focused.tags[i]
+ if tag then
+ awful.tag.viewtoggle(tag)
+ end
+ end,
+ descr_toggle
+ ),
+ -- Move client to tag.
+ awful.key(
+ {modkey, 'Shift'},
+ '#' .. i + 9,
+ function()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:move_to_tag(tag)
+ end
+ end
+ end,
+ descr_move
+ ),
+ -- Toggle tag on focused client.
+ awful.key(
+ {modkey, 'Control', 'Shift'},
+ '#' .. i + 9,
+ function()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:toggle_tag(tag)
+ end
+ end
+ end,
+ descr_toggle_focus
+ )
+ )
+end
+
+return global_keys
diff --git a/.config/awesome/configuration/keys/init.lua b/.config/awesome/configuration/keys/init.lua
new file mode 100644
index 0000000..9591667
--- /dev/null
+++ b/.config/awesome/configuration/keys/init.lua
@@ -0,0 +1,4 @@
+return {
+ mod = require('configuration.keys.mod'),
+ global = require('configuration.keys.global')
+}
diff --git a/.config/awesome/configuration/keys/mod.lua b/.config/awesome/configuration/keys/mod.lua
new file mode 100644
index 0000000..d7791de
--- /dev/null
+++ b/.config/awesome/configuration/keys/mod.lua
@@ -0,0 +1,4 @@
+return {
+ mod_key = 'Mod4',
+ alt_key = 'Mod1'
+}
diff --git a/.config/awesome/configuration/picom.conf b/.config/awesome/configuration/picom.conf
new file mode 100644
index 0000000..9868338
--- /dev/null
+++ b/.config/awesome/configuration/picom.conf
@@ -0,0 +1,156 @@
+# ░█▀█░▀█▀░█▀▀░█▀█░█▄█░░░░█▀▀░█▀█░█▀█░█▀▀
+# ░█▀▀░░█░░█░░░█░█░█░█░░░░█░░░█░█░█░█░█▀▀
+# ░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░░▀▀▀░▀▀▀░▀░▀░▀░░
+#
+# X compositor configuration
+
+# ░█▀▀░█░█░█▀█░█▀▄░█▀█░█░█
+# ░▀▀█░█▀█░█▀█░█░█░█░█░█▄█
+# ░▀▀▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀
+
+shadow = false;
+shadow-radius = 12;
+shadow-opacity = 0.75;
+shadow-offset-x = -12;
+shadow-offset-y = -12;
+
+# shadow-red = 0
+# shadow-green = 0
+# shadow-blue = 0
+shadow-color = "#000000";
+
+shadow-exclude = [
+ "name = 'Notification'",
+ "class_g = 'Conky'",
+ "class_g ?= 'Notify-osd'",
+ "class_g = 'Cairo-clock'",
+ "class_g = 'slop'",
+ "class_g = 'Firefox' && argb",
+ "class_g = 'Rofi'",
+ "_GTK_FRAME_EXTENTS@:c",
+ "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
+];
+
+# shadow-exclude-reg = "x10+0+0";
+# xinerama-shadow-crop = true;
+
+# ░█▀▀░█▀█░█▀▄░▀█▀░█▀█░█▀▀
+# ░█▀▀░█▀█░█░█░░█░░█░█░█░█
+# ░▀░░░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀
+
+fading = true;
+fade-in-step = 0.03;
+fade-out-step = 0.03;
+fade-delta = 3;
+
+fade-exclude = [];
+
+no-fading-openclose = false;
+no-fading-destroyed-argb = true;
+
+# ░█▀█░█▀█░█▀█░█▀▀░▀█▀░▀█▀░█░█
+# ░█░█░█▀▀░█▀█░█░░░░█░░░█░░░█░
+# ░▀▀▀░▀░░░▀░▀░▀▀▀░▀▀▀░░▀░░░▀░
+
+inactive-opacity = 1;
+frame-opacity = 1;
+inactive-opacity-override = false;
+active-opacity = 1.0;
+inactive-dim = 0.0;
+
+focus-exclude = [
+ "class_g = 'Cairo-clock'",
+ "class_g ?= 'rofi'",
+ "class_g ?= 'slop'",
+ "class_g ?= 'Steam'"
+];
+
+# inactive-dim-fixed = 1.0;
+
+opacity-rule = [
+ "80:class_g = 'URxvt'",
+ "80:class_g = 'UXTerm'",
+ "80:class_g = 'XTerm'"
+]
+
+# ░█▀▄░█░░░█░█░█▀▄░█▀▄░▀█▀░█▀█░█▀▀
+# ░█▀▄░█░░░█░█░█▀▄░█▀▄░░█░░█░█░█░█
+# ░▀▀░░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀░▀░▀▀▀
+
+blur: {
+ method = "dual_kawase";
+ strength = 4.0;
+ deviation = 1.0;
+ kernel = "11x11gaussian";
+}
+
+blur-background = false;
+blur-background-frame = true;
+blur-background-fixed = true;
+# blur-kern = "3x3box";
+
+blur-background-exclude = [
+ "class_g = 'slop'",
+ "class_g = 'Firefox' && argb",
+ "name = 'rofi - Global Search'",
+ "_GTK_FRAME_EXTENTS@:c"
+];
+
+# ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░█░░░░░█▀▀░█▀▀░▀█▀░▀█▀░▀█▀░█▀█░█▀▀░█▀▀
+# ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░█░░░░░▀▀█░█▀▀░░█░░░█░░░█░░█░█░█░█░▀▀█
+# ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░▀▀▀░░░▀▀▀░▀▀▀░░▀░░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀
+
+daemon = false;
+backend = "glx";
+vsync = true;
+dbus = false;
+mark-wmwin-focused = true;
+mark-ovredir-focused = true;
+detect-rounded-corners = true;
+detect-client-opacity = true;
+refresh-rate = 0;
+# use-ewmh-active-win = true;
+# unredir-if-possible = false;
+# unredir-if-possible-delay = 0;
+
+unredir-if-possible-exclude = [];
+
+detect-transient = true;
+detect-client-leader = true;
+resize-damage = 1;
+
+invert-color-include = [];
+
+glx-no-stencil = true;
+# glx-no-rebind-pixmap = false;
+use-damage = true;
+# xrender-sync-fence = true;
+
+# glx-fshader-win = "";
+# force-win-blend = false;
+
+# no-ewmh-fullscreen = false;
+# max-brightness = 1.0;
+
+transparent-clipping = false;
+
+log-level = "warn";
+log-file = "~/.cache/picom-log.log";
+show-all-xerrors = true;
+# write-pid-path = '/path/to/your/mom';
+
+wintypes: {
+ tooltip = { fade = true; shadow = false; focus = false; };
+ normal = { shadow = false; };
+ dock = { shadow = false; };
+ dnd = { shadow = false; };
+ popup_menu = { shadow = true; focus = false; opacity = 0.90; };
+ dropdown_menu = { shadow = false; focus = false; };
+ above = { shadow = true; };
+ splash = { shadow = false; };
+ utility = { focus = false; shadow = false; blur-background = false; };
+ notification = { shadow = false; };
+ desktop = { shadow = false; blur-background = false; };
+ menu = { focus = false; };
+ dialog = { shadow = true; };
+};
diff --git a/.config/awesome/configuration/rofi/appmenu/rofi.rasi b/.config/awesome/configuration/rofi/appmenu/rofi.rasi
new file mode 100644
index 0000000..c4af2c2
--- /dev/null
+++ b/.config/awesome/configuration/rofi/appmenu/rofi.rasi
@@ -0,0 +1,152 @@
+configuration {
+ font: "Inter Regular 10";
+ show-icons: true;
+ drun-display-format: "{name}";
+ fullscreen: false;
+ threads: 0;
+ matching: "fuzzy";
+ scroll-method: 0;
+ disable-history: false;
+ fullscreen: true;
+ window-thumbnail: true;
+}
+
+* {
+ transparent: #00000000;
+ foreground: #F2F2F2EE;
+ background-selected: #F2F2F245;
+ background-active: #F2F2F230;
+ background-white: #F2F2F211;
+ background-black: #00000066;
+ urgent: #E91E6366;
+ urgent-selected: #E91E6377;
+}
+
+window {
+ transparency: "real";
+ background-color: @transparent;
+ text-color: @foreground;
+ location: northwest;
+ anchor: northwest;
+}
+
+prompt {
+ enabled: false;
+}
+
+button {
+ action: "ok";
+ str: " ";
+ font: "FantasqueSansMono Nerd Font 11";
+ expand: false;
+ text-color: @foreground;
+ background-color: @transparent;
+ vertical-align: 0.7;
+ horizontal-align: 0.5;
+}
+
+entry {
+ font: "Inter Regular 11";
+ background-color: @transparent;
+ text-color: @foreground;
+ expand: true;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+ placeholder: "Type to search";
+ placeholder-color: @foreground;
+ blink: true;
+}
+
+case-indicator {
+ background-color: @transparent;
+ text-color: @foreground;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+entry-wrapper {
+ orientation: horizontal;
+ vertical-align: 0.5;
+ spacing: 4px;
+ background-color: @transparent;
+ children: [ button, entry, case-indicator ];
+}
+
+inputbar {
+ background-color: @background-white;
+ text-color: @foreground;
+ expand: false;
+ border-radius: 6px;
+ margin: 0px calc((100% - 640px) / 2) 0px calc((100% - 640px) / 2);
+ padding: 10px 10px 10px 10px;
+ position: north;
+ children: [ entry-wrapper ];
+}
+
+listview {
+ background-color: @transparent;
+ columns: 6;
+ spacing: 5px;
+ cycle: false;
+ dynamic: true;
+ layout: vertical;
+}
+
+mainbox {
+ background-color: @background-black;
+ children: [ inputbar, listview ];
+ spacing: 25px;
+ padding: 70px 15% 0 15%;
+ /*padding: 70px 135px 0 135px;*/
+}
+
+element {
+ background-color: @transparent;
+ text-color: @foreground;
+ orientation: vertical;
+ border-radius: 12px;
+ padding: 25px 0 25px 0;
+}
+
+element-icon {
+ background-color: @transparent;
+ size: 72px;
+ border: 0;
+}
+
+element-text {
+ background-color: @transparent;
+ text-color: @foreground;
+ expand: true;
+ horizontal-align: 0.5;
+ vertical-align: 0.5;
+ margin: 0 10px 0 10px;
+}
+
+element normal.urgent,
+element alternate.urgent {
+ background-color: @urgent;
+ text-color: @foreground;
+ border-radius: 9px;
+}
+
+element normal.active,
+element alternate.active {
+ background-color: @background-active;
+ text-color: @foreground;
+}
+
+element selected {
+ background-color: @background-selected;
+ text-color: @foreground;
+}
+
+element selected.urgent {
+ background-color: @urgent-selected;
+ text-color: @foreground;
+}
+
+element selected.active {
+ background-color: @background-active;
+ color: @foreground-selected;
+}
diff --git a/.config/awesome/configuration/rofi/global/history.txt b/.config/awesome/configuration/rofi/global/history.txt
new file mode 100644
index 0000000..e69de29
diff --git a/.config/awesome/configuration/rofi/global/icons/ddg.svg b/.config/awesome/configuration/rofi/global/icons/ddg.svg
new file mode 100644
index 0000000..20ea387
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/icons/ddg.svg
@@ -0,0 +1,615 @@
+
+
+
+
diff --git a/.config/awesome/configuration/rofi/global/icons/google.svg b/.config/awesome/configuration/rofi/global/icons/google.svg
new file mode 100644
index 0000000..21e5bf3
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/icons/google.svg
@@ -0,0 +1,365 @@
+
+
+
+
diff --git a/.config/awesome/configuration/rofi/global/icons/history.svg b/.config/awesome/configuration/rofi/global/icons/history.svg
new file mode 100644
index 0000000..872bac8
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/icons/history.svg
@@ -0,0 +1,75 @@
+
+
diff --git a/.config/awesome/configuration/rofi/global/icons/result.svg b/.config/awesome/configuration/rofi/global/icons/result.svg
new file mode 100644
index 0000000..0f4d883
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/icons/result.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/configuration/rofi/global/icons/suggestion.svg b/.config/awesome/configuration/rofi/global/icons/suggestion.svg
new file mode 100644
index 0000000..bf67346
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/icons/suggestion.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.config/awesome/configuration/rofi/global/rofi-spotlight.sh b/.config/awesome/configuration/rofi/global/rofi-spotlight.sh
new file mode 100755
index 0000000..d5c4a23
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/rofi-spotlight.sh
@@ -0,0 +1,692 @@
+#!/usr/bin/env bash
+
+TMP_DIR="/tmp/rofi/${USER}/"
+
+PREV_LOC_FILE="${TMP_DIR}rofi_fb_prevloc"
+CURRENT_FILE="${TMP_DIR}rofi_fb_current_file"
+
+MY_PATH="$(realpath "$0" | xargs dirname)"
+HIST_FILE="${MY_PATH}/history.txt"
+
+OPENER=xdg-open
+TERM_EMU=kitty
+TEXT_EDITOR=$EDITOR
+FILE_MANAGER=xdg-open
+BLUETOOTH_SEND=blueman-sendto
+
+CUR_DIR=$PWD
+NEXT_DIR=""
+FD_INSTALLED=$(command -v fd)
+
+SHOW_HIDDEN=false
+
+# Setup menu options
+declare -a OPEN_FILE_LOCATION=(
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+)
+declare -a RUN_COMMANDS=(
+ "Run"
+ "Execute in ${TERM_EMU}"
+)
+declare -a STANDARD_CONTROLS=(
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+declare -a SHELL_NO_X_OPTIONS=(
+ "Edit"
+ "${OPEN_FILE_LOCATION[@]}"
+ "${STANDARD_CONTROLS[@]}"
+)
+declare -a SHELL_OPTIONS=(
+ "${RUN_COMMANDS[@]}"
+ "${SHELL_NO_X_OPTIONS[@]}"
+)
+declare -a BIN_NO_X_OPTIONS=(
+ "${OPEN_FILE_LOCATION[@]}"
+ "Back"
+)
+declare -a BIN_OPTIONS=(
+ "${RUN_COMMANDS[@]}"
+ "${BIN_NO_X_OPTIONS[@]}"
+)
+declare -a TEXT_OPTIONS=("${SHELL_NO_X_OPTIONS[@]}")
+declare -a HTML_OPTIONS=(
+ "Open"
+ "Edit"
+ "${OPEN_FILE_LOCATION[@]}"
+ "${STANDARD_CONTROLS[@]}"
+)
+declare -a XCF_SVG_OPTIONS=(
+ "Open"
+ "${OPEN_FILE_LOCATION[@]}"
+ "${STANDARD_CONTROLS[@]}"
+)
+declare -a IMAGE_OPTIONS=(
+ "Open"
+ "Send via Bluetooth"
+ "${OPEN_FILE_LOCATION[@]}"
+ "${STANDARD_CONTROLS[@]}"
+)
+
+declare -a ALL_OPTIONS=()
+
+# Combine all context menu
+COMBINED_OPTIONS=(
+ "${SHELL_OPTIONS[@]}"
+ "${IMAGE_OPTIONS[@]}"
+)
+
+# Remove duplicates
+ALL_OPTIONS=("$(printf '%s\n' "${COMBINED_OPTIONS[@]}" | sort -u)")
+
+# Create tmp dir for rofi
+[ ! -d "${TMP_DIR}" ] && mkdir -p "${TMP_DIR}";
+
+# Create hist file if it doesn't exist
+[ ! -f "${HIST_FILE}" ] && touch "${HIST_FILE}"
+
+# Help message
+if [ -n "$*" ] && [[ "$*" = ":help" ]]
+then
+ echo -en "Rofi Spotlight
+A Rofi with file and web searching functionality
+
+Commands:
+:help to print this help message
+:h or :hidden to show hidden files/dirs
+:sh or :show_hist to show search history
+:ch or :clear_hist to clear search history
+:xdg to jump to an xdg directory
+Examples:
+ :xdg DOCUMENTS
+ :xdg DOWNLOADS
+Also supports incomplete path:
+Examples:
+ :xdg doc
+ :xdg down
+For more info about XDG dirs, see:
+\`man xdg-user-dir\`
+
+File search syntaxes:
+! to search for a file and web suggestions
+? to search parent directories
+Examples:
+ !half-life 3
+ ?portal 3
+
+Web search syntaxes:
+! to gets search suggestions
+:web/:w to also to gets search suggestions
+:webbro/:wb to search directly from your browser
+Examples:
+ !how to install archlinux
+ :web how to install gentoo
+ :w how to make a nuclear fission
+ :webbro how to install wine in windowsxp
+Back\0icon\x1fdraw-arrow-back\n"
+
+ exit
+fi
+
+# Return the icon string
+function icon_file_type(){
+ icon_name=""
+ mime_type=$(file --mime-type -b "${1}")
+
+ case "${mime_type}" in
+ "inode/directory")
+ case "${1}" in
+ "Desktop/" )
+ icon_name='folder-blue-desktop'
+ ;;
+ "Documents/" )
+ icon_name='folder-blue-documents'
+ ;;
+ "Downloads/" )
+ icon_name='folder-blue-downloads'
+ ;;
+ "Music/" )
+ icon_name='folder-blue-music'
+ ;;
+ "Pictures/" )
+ icon_name='folder-blue-pictures'
+ ;;
+ "Public/" )
+ icon_name='folder-blue-public'
+ ;;
+ "Templates/" )
+ icon_name='folder-blue-templates'
+ ;;
+ "Videos/" )
+ icon_name='folder-blue-videos'
+ ;;
+ "root/" )
+ icon_name='folder-root'
+ ;;
+ "home/" | "${USER}/")
+ icon_name='folder-home'
+ ;;
+ *"$" )
+ icon_name='folder-blue'
+ ;;
+ *)
+ icon_name='folder-blue'
+ ;;
+ esac
+ ;;
+ "inode/symlink" )
+ icon_name='inode-symlink'
+ ;;
+ "audio/flac" | "audio/mpeg" )
+ icon_name='music'
+ ;;
+ "video/mp4" )
+ icon_name='video-mp4'
+ ;;
+ "video/x-matroska" )
+ icon_name=video-x-matroska
+ ;;
+ "image/x-xcf" )
+ # notify-send '123'
+ icon_name='image-x-xcf'
+ ;;
+ "image/jpeg" | "image/png" | "image/svg+xml")
+ icon_name="${CUR_DIR}/${1}"
+ ;;
+ "image/gif" )
+ icon_name='gif'
+ ;;
+ "image/vnd.adobe.photoshop" )
+ icon_name='image-vnd.adobe.photoshop'
+ ;;
+ "image/webp" )
+ icon_name='gif'
+ ;;
+ "application/x-pie-executable" )
+ icon_name='binary'
+ ;;
+ "application/pdf" )
+ icon_name='pdf'
+ ;;
+ "application/zip" )
+ icon_name='application-zip'
+ ;;
+ "application/x-xz" )
+ icon_name='application-x-xz-compressed-tar'
+ ;;
+ "application/x-7z-compressed" )
+ icon_name='application-x-7zip'
+ ;;
+ "application/x-rar" )
+ icon_name='application-x-rar'
+ ;;
+ "application/octet-stream" | "application/x-iso9660-image" )
+ icon_name='application-x-iso'
+ ;;
+ "application/x-dosexec" )
+ icon_name='application-x-ms-dos-executable'
+ ;;
+ "text/plain" )
+ icon_name='application-text'
+ ;;
+ "text/x-shellscript" )
+ icon_name='application-x-shellscript'
+ ;;
+ "text/html" )
+ icon_name='text-html'
+ ;;
+ "font/sfnt" | "application/vnd.ms-opentype" )
+ icon_name='application-x-font-ttf'
+ ;;
+ * )
+ case "${1}" in
+ *."docx" | *".doc" )
+ icon_name='application-msword'
+ ;;
+ *."apk" )
+ icon_name='android-package-archive'
+ ;;
+ * )
+ icon_name='unknown'
+ ;;
+ esac
+ ;;
+ esac
+
+ echo -en "$1\0icon\x1f$icon_name\n"
+}
+
+export -f icon_file_type
+
+# Pass the argument to python script
+function web_search() {
+ # Pass the search query to web-search script
+ "${MY_PATH}/web-search.py" "${1}"
+ exit;
+}
+
+# Handles the web search method
+if [ ! -z "$@" ] && ([[ "$@" == ":webbro"* ]] || [[ "$@" == ":wb"* ]])
+then
+ remove=''
+ [[ "$*" = ":webbro"* ]] && remove=":webbro" || remove=":wb"
+
+ # Search directly from your web browser
+ web_search "$(printf '%s\n' "${1//$remove/}")"
+ exit;
+
+elif [ ! -z "$@" ] && ([[ "$@" == ":web"* ]] || [[ "$@" == ":w"* ]])
+then
+ remove=''
+ [[ "$*" = ":web"* ]] && remove=":web" || remove=":w"
+
+ # Get search suggestions
+ web_search "!$(printf '%s\n' "${1//$remove/}")"
+ exit;
+fi
+
+function find_query() {
+ QUERY=${1}
+ if [[ ! "${QUERY}" =~ ( |\') ]]
+ then
+ if [ -z "$FD_INSTALLED" ];
+ then
+ find "${HOME}" -iname *"${QUERY}"* | sed "s/\/home\/$USER/\~/" |
+ awk -v MY_PATH="${MY_PATH}" '{print $0"\0icon\x1f"MY_PATH"/icons/result.svg\n"}'
+ else
+ fd -H ${QUERY} ${HOME} | sed "s/\/home\/$USER/\~/" |
+ awk -v MY_PATH="${MY_PATH}" '{print $0"\0icon\x1f"MY_PATH"/icons/result.svg\n"}'
+ fi
+ fi
+}
+
+# File and calls to the web search
+if [ ! -z "$@" ] && ([[ "$@" == ?(\~)/* ]] || [[ "$@" == \?* ]] || [[ "$@" == \!* ]])
+then
+ QUERY=$@
+
+ echo "${QUERY}" >> "${HIST_FILE}"
+
+ if [[ "$@" == ?(\~)/* ]]
+ then
+ [[ "$*" = \~* ]] && QUERY="${QUERY//"~"/"$HOME"}"
+
+ coproc ${OPENER} "${QUERY}" > /dev/null 2>&1
+ exec 1>&-
+ exit
+
+ elif [[ "$@" == \?* ]]
+ then
+ find_query ${QUERY#\?}
+
+ else
+ # Find the file
+ find_query ${QUERY#!}
+
+ # Web search
+ web_search "! ${QUERY#!}"
+ fi
+ exit;
+fi
+
+# Create notification if there's an error
+function create_notification() {
+ case "${1}" in
+ "denied" )
+ notify-send -a "Global Search" "Permission denied!" \
+ 'You have no permission to access '"${CUR_DIR}!"
+ ;;
+ "deleted" )
+ notify-send -a "Global Search" "Success!" \
+ 'File deleted!'
+ ;;
+ "trashed" )
+ notify-send -a "Global Search" "Success!" \
+ 'The file has been moved to trash!'
+ ;;
+ "cleared" )
+ notify-send -a "Global Search" "Success!" \
+ 'Search history has been successfully cleared!'
+ ;;
+ * )
+ notify-send -a "Global Search" "Somethings wrong I can feel it!" \
+ 'This incident will be reported!'
+ ;;
+ esac
+}
+
+# Show the files in the current directory
+function navigate_to() {
+ # process current dir.
+ if [ -n "${CUR_DIR}" ]
+ then
+ CUR_DIR=$(readlink -e "${CUR_DIR}")
+ if [ ! -d "${CUR_DIR}" ] || [ ! -r "${CUR_DIR}" ]
+ then
+ create_notification "denied"
+ CUR_DIR=$(realpath ${CUR_DIR} | xargs dirname)
+ echo "${CUR_DIR}" > "${PREV_LOC_FILE}"
+ else
+ echo "${CUR_DIR}/" > "${PREV_LOC_FILE}"
+ fi
+ pushd "${CUR_DIR}" >/dev/null || exit
+ fi
+
+ printf "..\0icon\x1fup\n"
+
+ if [[ -z "$FD_INSTALLED" ]]
+ then
+ #Group directories
+ if [[ ${SHOW_HIDDEN} == true ]]
+ then
+ for i in .*/
+ do
+ [[ -d "${i}" ]] && ([[ "${i}" != "./" ]] && [[ "${i}" != "../"* ]]) && icon_file_type "${i}"
+ done
+ fi
+ for i in */
+ do
+ [[ -d "${i}" ]] && icon_file_type "${i}"
+ done
+ #Group files
+ if [[ ${SHOW_HIDDEN} = true ]]
+ then
+ for i in .*
+ do
+ [[ -f "${i}" ]] && icon_file_type "${i}"
+ done
+ fi
+ for i in *
+ do
+ [[ -f "${i}" ]] && icon_file_type "${i}"
+ done
+ else
+ THREADS=$(getconf _NPROCESSORS_ONLN)
+ export CUR_DIR
+ if [[ ${SHOW_HIDDEN} == true ]]
+ then
+ fd -Ht d -d 1 -x bash -c 'icon_file_type "$1/"' _ {} \ | sort -V --parallel=$THREADS
+ fd -Ht f -d 1 -x bash -c 'icon_file_type "$1"' _ {} \ | sort -V --parallel=$THREADS
+ else
+ fd -t d -d 1 -x bash -c 'icon_file_type "$1/"' _ {} \ | sort -V --parallel=$THREADS
+ fd -t f -d 1 -x bash -c 'icon_file_type "$1"' _ {} \ | sort -V --parallel=$THREADS
+ fi
+ fi
+}
+
+# Set XDG dir
+function return_xdg_dir() {
+ target_dir=${1^^}
+
+ if [[ "HOME" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir)
+
+ elif [[ "DESKTOP" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir DESKTOP)
+
+ elif [[ "DOCUMENTS" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir DOCUMENTS)
+
+ elif [[ "DOWNLOADS" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir DOWNLOAD)
+
+ elif [[ "MUSIC" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir MUSIC)
+
+ elif [[ "PICTURES" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir PICTURES)
+
+ elif [[ "PUBLICSHARE" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir PUBLICSHARE)
+
+ elif [[ "TEMPLATES" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir TEMPLATES)
+
+ elif [[ "VIDEOS" == *"${target_dir}"* ]]
+ then
+ CUR_DIR=$(xdg-user-dir VIDEOS)
+
+ elif [[ "ROOT" == *"${target_dir}"* ]]
+ then
+ CUR_DIR="/"
+
+ else
+ CUR_DIR="${HOME}"
+ fi
+ navigate_to
+ exit;
+}
+
+# Show and Clear History
+if [ ! -z "$@" ] && ([[ "$@" == ":sh" ]] || [[ "$@" == ":show_hist" ]])
+then
+ hist=$(tac "${HIST_FILE}")
+
+ echo -en "Back\0icon\x1fdraw-arrow-back\n"
+ [ -z "${hist}" ] && echo -en "No History Yet\0icon\x1ftext-plain\n"
+
+ while IFS= read -r line;
+ do
+ echo -en "${line}\0icon\x1f${MY_PATH}/icons/history.svg\n";
+ done <<< "${hist}"
+
+ exit;
+elif [ ! -z "$@" ] && ([[ "$@" == ":ch" ]] || [[ "$@" == ":clear_hist" ]])
+then
+ :> "${HIST_FILE}"
+ create_notification "cleared"
+
+ CUR_DIR="${HOME}"
+ navigate_to
+ exit;
+fi
+
+# Accepts XDG command
+if [[ ! -z "$@" ]] && [[ "$@" == ":xdg"* ]]
+then
+ NEXT_DIR=${*//":xdg "/}
+
+ [[ -n "$NEXT_DIR" ]] && return_xdg_dir "${NEXT_DIR}" || return_xdg_dir "${HOME}"
+fi
+
+# Read last location, otherwise we default to PWD.
+[ -f "${PREV_LOC_FILE}" ] && CUR_DIR=$(< "${PREV_LOC_FILE}")
+
+if [[ ! -z "$@" ]] && ([[ "$@" == ":h" ]] || [[ "$@" == ":hidden" ]])
+then
+ SHOW_HIDDEN=true
+ navigate_to
+ exit;
+fi
+
+# Handle argument.
+[ -n "$*" ] && CUR_DIR="${CUR_DIR}/$*"
+
+# Context Menu
+if [ -n "$*" ] && [[ "${ALL_OPTIONS[*]} " = *"$*"* ]]
+then
+ case "${1}" in
+ "Run" )
+ coproc ( eval "$(< ${CURRENT_FILE})" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Execute in ${TERM_EMU}" )
+ coproc ( eval "${TERM_EMU} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Open" )
+ coproc ( eval "${OPENER} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Open file location in ${TERM_EMU}" )
+ file_path="$(< ${CURRENT_FILE})"
+ coproc ( ${TERM_EMU} bash -c "cd ${file_path%/*} ; ${SHELL}" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Open file location in ${FILE_MANAGER}" )
+ file_path="$(< "${CURRENT_FILE}")"
+ coproc ( eval "${FILE_MANAGER} "${file_path%/*}"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Edit" )
+ coproc ( eval "${TERM_EMU} ${TEXT_EDITOR} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Move to trash" )
+ coproc( gio trash "$(< ${CURRENT_FILE})" & > /dev/null 2>&1 )
+ create_notification "trashed"
+ CUR_DIR="$(dirname "$(< ${CURRENT_FILE})")"
+ navigate_to
+ ;;
+ "Delete" )
+ shred "$(< ${CURRENT_FILE})"
+ rm "$(< ${CURRENT_FILE})"
+ create_notification "deleted"
+ CUR_DIR="$(dirname "$(< ${CURRENT_FILE})")"
+ navigate_to
+ ;;
+ "Send via Bluetooth" )
+ rfkill unblock bluetooth && bluetoothctl power on
+ sleep 1
+ blueman-sendto "$(< ${CURRENT_FILE})" & > /dev/null 2>&1
+ kill -9 $(pgrep rofi)
+ ;;
+ "Back" )
+ CUR_DIR="$(< ${PREV_LOC_FILE})"
+ navigate_to
+ ;;
+ esac
+ exit;
+fi
+
+function context_menu_icons() {
+
+ if [[ "${1}" == "Run" ]]
+ then
+ echo '\0icon\x1fsystem-run\n'
+
+ elif [[ "${1}" == "Execute in ${TERM_EMU}" ]]
+ then
+ echo "\0icon\x1f${TERM_EMU}\n"
+
+ elif [[ "${1}" == "Open" ]]
+ then
+ echo "\0icon\x1futilities-x-terminal\n"
+
+ elif [[ "${1}" == "Open file location in ${TERM_EMU}" ]]
+ then
+ echo "\0icon\x1f${TERM_EMU}\n"
+
+ elif [[ "${1}" == "Open file location in ${FILE_MANAGER}" ]]
+ then
+ echo "\0icon\x1fblue-folder-open\n"
+
+ elif [[ "${1}" == "Edit" ]]
+ then
+ echo "\0icon\x1faccessories-text-editor\n"
+
+ elif [[ "${1}" == "Move to trash" ]]
+ then
+ echo "\0icon\x1fapplication-x-trash\n"
+
+ elif [[ "${1}" == "Delete" ]]
+ then
+ echo "\0icon\x1findicator-trashindicator\n"
+
+ elif [[ "${1}" == "Send via Bluetooth" ]]
+ then
+ echo "\0icon\x1fbluetooth\n"
+
+ elif [[ "${1}" == "Back" ]]
+ then
+ echo "\0icon\x1fback\n"
+ fi
+}
+
+function print_context_menu() {
+ declare -a arg_arr=("${!1}")
+
+ for menu in "${arg_arr[@]}"
+ do
+ printf "$menu$(context_menu_icons "${menu}")\n"
+ done
+}
+
+function context_menu() {
+
+ type="$(file --mime-type -b "${CUR_DIR}")"
+
+ if [ -w "${CUR_DIR}" ] && [[ "${type}" == "text/x-shellscript" ]]
+ then
+ if [ -x "${CUR_DIR}" ];
+ then
+ print_context_menu SHELL_OPTIONS[@]
+ else
+ print_context_menu SHELL_NO_X_OPTIONS[@]
+ fi
+
+ elif [[ "${type}" == "application/x-executable" ]] || [[ "${type}" == "application/x-pie-executable" ]]
+ then
+ if [ -x "${CUR_DIR}" ]
+ then
+ print_context_menu BIN_OPTIONS[@]
+ else
+ print_context_menu BIN_NO_X_OPTIONS[@]
+ fi
+
+ elif [[ "${type}" == "text/plain" ]]
+ then
+ print_context_menu TEXT_OPTIONS[@]
+
+ elif [[ "${type}" == "text/html" ]]
+ then
+ print_context_menu HTML_OPTIONS[@]
+
+ elif [[ "${type}" == "image/jpeg" ]] || [[ "${type}" == "image/png" ]]
+ then
+ print_context_menu IMAGE_OPTIONS[@]
+
+ elif [[ "${type}" == "image/x-xcf" ]] || [[ "${type}" == "image/svg+xml" ]]
+ then
+ print_context_menu XCF_SVG_OPTIONS[@]
+
+ elif [ ! -w "${CUR_DIR}" ] && [[ "${type}" == "text/x-shellscript" ]]
+ then
+ coproc ( exec "${CUR_DIR}" & > /dev/null 2>&1 )
+
+ else
+ if [ ! -d "${CUR_DIR}" ] && [ ! -f "${CUR_DIR}" ]
+ then
+ QUERY="${CUR_DIR//*\/\//}"
+
+ echo "${QUERY}" >> "${HIST_FILE}"
+
+ find_query "${QUERY#!}"
+
+ web_search "!${QUERY}"
+ else
+ coproc ( ${OPENER} "${CUR_DIR}" & > /dev/null 2>&1 )
+ fi
+ fi
+ exit;
+}
+
+# If argument is not a directory/folder
+if [ ! -d "${CUR_DIR}" ]
+then
+ echo "${CUR_DIR}" > "${CURRENT_FILE}"
+ context_menu
+ exit;
+fi
+
+navigate_to
diff --git a/.config/awesome/configuration/rofi/global/rofi.rasi b/.config/awesome/configuration/rofi/global/rofi.rasi
new file mode 100644
index 0000000..d14ecd2
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/rofi.rasi
@@ -0,0 +1,157 @@
+configuration {
+ font: "Inter Regular 10";
+ sidebar-mode: true;
+ show-icons: true;
+ fullscreen: false;
+ threads: 0;
+ matching: "fuzzy";
+ scroll-method: 0;
+ monitor: "primary";
+}
+
+* {
+ transparent: #00000000;
+ foreground: #F2F2F2EE;
+ background-selected: #F2F2F245;
+ background-active: #F2F2F230;
+ background-white: #F2F2F211;
+ background-black: #00000000;
+ urgent: #E91E6366;
+ urgent-selected: #E91E6377;
+}
+
+window {
+ transparency: "real";
+ background-color: @transparent;
+ text-color: @foreground;
+ location: west;
+ anchor: west;
+ x-offset: 0;
+ height: 100%;
+ width: 350px;
+ orientation: vertical;
+}
+
+prompt {
+ enabled: false;
+}
+
+button {
+ action: "ok";
+ str: " ";
+ font: "FantasqueSansMono Nerd Font 16";
+ expand: false;
+ text-color: @foreground;
+ background-color: @transparent;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+entry {
+ font: "Inter Regular 12";
+ background-color: @transparent;
+ text-color: @foreground;
+ expand: true;
+ vertical-align: 0.5;
+ horizontal-align: 0;
+ placeholder: "Global Search";
+ placeholder-color: @foreground;
+ blink: true;
+}
+
+entry-wrapper {
+ orientation: horizontal;
+ margin: 0 12px 0 12px;
+ spacing: 24px;
+ vertical-align: 0.5;
+ background-color: @transparent;
+ children: [ button, entry ];
+}
+
+inputbar {
+ padding: 14px;
+ margin: 10px 10px 14px 10px;
+ background-color: @background-white;
+ text-color: @foreground;
+ expand: false;
+ border-radius: 9px;
+ position: north;
+ children: [ entry-wrapper ];
+}
+
+listview {
+ background-color: @transparent;
+ spacing: 0;
+ cycle: true;
+ dynamic: true;
+ scrollbar: true;
+}
+
+mainbox {
+ width: 200px;
+ expand: true;
+ spacing: 12px;
+ padding: 5px;
+ background-color: @background-black;
+ children: [ inputbar, listview ];
+}
+
+scrollbar {
+ background-color: @background-white;
+ handle-width: 0;
+ margin: 0 0 5px 0;
+ border-radius: 9px;
+}
+
+element {
+ background-color: @transparent;
+ text-color: @foreground;
+ orientation: horizontal;
+ border: 0;
+ border-color: @background-white;
+ border-radius: 6px;
+ spacing: 24px;
+ margin: 0px 12px 0px 12px;
+ padding: 10px 24px 10px 24px;
+}
+
+element-icon {
+ size: 24px;
+ border: 0;
+ border-color: @transparent;
+}
+
+element-text {
+ font: "Inter Regular 11";
+ expand: true;
+ horizontal-align: 0;
+ vertical-align: 0.5;
+}
+
+element normal.urgent,
+element alternate.urgent {
+ background-color: @urgent;
+ text-color: @foreground;
+ border-radius: 9px;
+}
+
+element normal.active,
+element alternate.active {
+ background-color: @background-active;
+ text-color: @foreground;
+}
+
+element selected {
+ background-color: @background-selected;
+ text-color: @foreground;
+}
+
+element selected.urgent {
+ background-color: @urgent-selected;
+ text-color: @foreground;
+}
+
+element selected.active {
+ background-color: @background-active;
+ color: @foreground-selected;
+}
diff --git a/.config/awesome/configuration/rofi/global/web-search.py b/.config/awesome/configuration/rofi/global/web-search.py
new file mode 100755
index 0000000..ba314d5
--- /dev/null
+++ b/.config/awesome/configuration/rofi/global/web-search.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python3
+
+# MIT License
+
+# Copyright (c) 2019 Paolo Donadeo
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+
+import json
+import re
+import urllib.parse
+import urllib.request
+import sys
+import os
+import datetime
+import gzip
+
+import subprocess as sp
+
+import html
+
+
+################################################################################
+##### C O N F I G U R A T I O N ######
+################################################################################
+SEARCH_ENGINE = 'google' # or 'duckduckgo'
+BROWSER = 'firefox' # or 'firefox', 'chromium', 'brave', 'lynx'
+TERMINAL = ['kitty', '--'] # or ['st', '-e'] or something like that
+################################################################################
+
+CONFIG = {
+ 'BROWSER_PATH' : {
+ 'chrome' : ['google-chrome-stable'],
+ 'firefox' : ['firefox'],
+ 'chromium' : ['chromium-browser'],
+ 'brave' : ['brave-browser'],
+ 'lynx' : TERMINAL + ['lynx']
+ },
+ 'USER_AGENT' : {
+ 'chrome' : 'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
+ 'firefox' : 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0',
+ 'chromium' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/76.0.3809.100 Chrome/76.0.3809.100 Safari/537.36',
+ 'brave' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
+ 'lynx' : 'Lynx/2.8.9rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.1.1d'
+ },
+ 'SEARCH_ENGINE_NAME' : {
+ 'google' : 'Google',
+ 'duckduckgo' : 'DuckDuckGo'
+ },
+ 'SEARCH_URL' : {
+ 'google' : 'https://www.google.com/search?q=',
+ 'duckduckgo' : 'https://duckduckgo.com/?q='
+ },
+ 'SUGGESTION_URL' : {
+ 'google' : 'https://www.google.com/complete/search?',
+ 'duckduckgo' : 'https://duckduckgo.com/ac/?'
+ }
+}
+
+def cleanhtml(txt):
+ return re.sub(r'<.*?>', '', txt)
+
+def fetch_suggestions(search_string):
+ if SEARCH_ENGINE == 'google':
+ r = {
+ 'q' : search_string,
+ 'cp' : '11',
+ 'client' : 'psy-ab',
+ 'xssi' : 't',
+ 'gs_ri' : 'gws-wiz',
+ 'hl' : 'en-IT',
+ 'authuser' : '0'
+ }
+ url = CONFIG['SUGGESTION_URL'][SEARCH_ENGINE] + urllib.parse.urlencode(r)
+ headers = {
+ 'sec-fetch-mode' : 'cors',
+ 'dnt' : '1',
+ 'accept-encoding' : 'gzip',
+ 'accept-language' : 'en-US;q=0.9,en;q=0.8',
+ 'pragma' : 'no-cache',
+ 'user-agent' : CONFIG['USER_AGENT'][BROWSER],
+ 'accept' : '*/*',
+ 'cache-control' : 'no-cache',
+ 'authority' : 'www.google.com',
+ 'referer' : 'https://www.google.com/',
+ 'sec-fetch-site' : 'same-origin'
+ }
+ req = urllib.request.Request(url, headers=headers, method='GET')
+
+ reply_data = gzip.decompress(urllib.request.urlopen(req).read()).split(b'\n')[1]
+ reply_data = json.loads(reply_data)
+ return [ cleanhtml(res[0]).strip() for res in reply_data[0] ]
+ else: # 'duckduckgo'
+ if search_string.startswith('!'):
+ bang_search = True
+ search_string = search_string.lstrip('!')
+ else:
+ bang_search = False
+ r = {
+ 'q' : search_string,
+ 'callback' : 'autocompleteCallback',
+ 'kl' : 'wt-wt',
+ '_' : str(int((datetime.datetime.now().timestamp())*1000))
+ }
+ url = CONFIG['SUGGESTION_URL'][SEARCH_ENGINE] + urllib.parse.urlencode(r)
+ if bang_search:
+ url = url.replace('?q=', '?q=!')
+ headers = {
+ 'pragma' : 'no-cache',
+ 'dnt' : '1',
+ 'accept-encoding' : 'gzip',
+ 'accept-language' : 'en-US;q=0.9,en;q=0.8',
+ 'user-agent' : CONFIG['USER_AGENT'][BROWSER],
+ 'sec-fetch-mode' : 'no-cors',
+ 'accept' : '*/*',
+ 'cache-control' : 'no-cache',
+ 'authority' : 'duckduckgo.com',
+ 'referer' : 'https://duckduckgo.com/',
+ 'sec-fetch-site' : 'same-origin',
+ }
+ req = urllib.request.Request(url, headers=headers, method='GET')
+ reply_data = gzip.decompress(urllib.request.urlopen(req).read()).decode('utf8')
+ reply_data = json.loads(re.match(r'autocompleteCallback\((.*)\);', reply_data).group(1))
+ return [ cleanhtml(res['phrase']).strip() for res in reply_data ]
+
+def main():
+ search_string = html.unescape((' '.join(sys.argv[1:])).strip())
+
+ path_str = os.path.dirname(os.path.realpath(__file__)) + '/'
+ icon_path_str = path_str + 'icons/'
+ icon_name = icon_path_str
+
+ if SEARCH_ENGINE == 'google':
+ icon_name += 'google.svg'
+ else:
+ icon_name += 'ddg.svg'
+
+ if search_string.startswith('!'):
+ search_string = search_string.rstrip('!').strip()
+ results = fetch_suggestions(search_string)
+ for r in results:
+ print(":wb " + html.unescape(r) + "\0icon\x1f"+icon_name+"\n")
+ else:
+ url = CONFIG['SEARCH_URL'][SEARCH_ENGINE] + urllib.parse.quote_plus(search_string)
+ sp.Popen(CONFIG['BROWSER_PATH'][BROWSER] + [url], stdout=sp.DEVNULL, stderr=sp.DEVNULL, shell=False)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except Exception as e:
+ if e:
+ sys.exit(1)
diff --git a/.config/awesome/configuration/root/init.lua b/.config/awesome/configuration/root/init.lua
new file mode 100644
index 0000000..55e43b3
--- /dev/null
+++ b/.config/awesome/configuration/root/init.lua
@@ -0,0 +1,84 @@
+local gears = require('gears')
+local awful = require('awful')
+
+local apps = require('configuration.apps')
+
+root.buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ if mymainmenu then
+ mymainmenu:hide()
+ end
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ function ()
+ if mymainmenu then
+ mymainmenu:toggle()
+ end
+ end
+ ),
+ awful.button(
+ {},
+ 2,
+ function ()
+ awful.util.spawn(apps.default.rofi_appmenu)
+ end
+ ),
+ awful.button(
+ {'Control'},
+ 2,
+ function ()
+ awesome.emit_signal('module::exit_screen:show')
+ end
+ ),
+ awful.button(
+ {'Shift'},
+ 2,
+ function ()
+ awesome.emit_signal('widget::blue_light:toggle')
+ end
+ ),
+ awful.button(
+ {},
+ 4,
+ function()
+ awful.spawn('light -A 10',false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show',true)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ function()
+ awful.spawn('light -U 10',false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show',true)
+ end
+ ),
+ awful.button(
+ {'Control'},
+ 4,
+ function()
+ awful.spawn('amixer -D pulse sset Master 5%+',false)
+ awesome.emit_signal('widget::volume')
+ awesome.emit_signal('module::volume_osd:show',true)
+ end
+ ),
+ awful.button(
+ {'Control'},
+ 5,
+ function()
+ awful.spawn('amixer -D pulse sset Master 5%-',false)
+ awesome.emit_signal('widget::volume')
+ awesome.emit_signal('module::volume_osd:show',true)
+ end
+ )
+ )
+)
\ No newline at end of file
diff --git a/.config/awesome/configuration/tags/init.lua b/.config/awesome/configuration/tags/init.lua
new file mode 100644
index 0000000..a637fd4
--- /dev/null
+++ b/.config/awesome/configuration/tags/init.lua
@@ -0,0 +1,168 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local icons = require('theme.icons')
+local apps = require('configuration.apps')
+
+local tags = {
+ {
+ type = 'terminal',
+ icon = icons.terminal,
+ default_app = apps.default.terminal,
+ gap = beautiful.useless_gap
+ },
+ {
+ type = 'internet',
+ icon = icons.web_browser,
+ default_app = apps.default.web_browser,
+ gap = beautiful.useless_gap
+ },
+ {
+ type = 'code',
+ icon = icons.text_editor,
+ default_app = apps.default.text_editor,
+ gap = beautiful.useless_gap
+ },
+ {
+ type = 'files',
+ icon = icons.file_manager,
+ default_app = apps.default.file_manager,
+ gap = beautiful.useless_gap,
+ layout = awful.layout.suit.tile
+ },
+ {
+ type = 'multimedia',
+ icon = icons.multimedia,
+ default_app = apps.default.multimedia,
+ gap = beautiful.useless_gap,
+ layout = awful.layout.suit.floating,
+ gap = 0
+ },
+ {
+ type = 'games',
+ icon = icons.games,
+ default_app = apps.default.game,
+ gap = beautiful.useless_gap,
+ layout = awful.layout.suit.floating
+ },
+ {
+ type = 'graphics',
+ icon = icons.graphics,
+ default_app = apps.default.graphics,
+ gap = beautiful.useless_gap
+ },
+ {
+ type = 'sandbox',
+ icon = icons.sandbox,
+ default_app = apps.default.sandbox,
+ layout = awful.layout.suit.max,
+ gap = 0
+ },
+ {
+ type = 'any',
+ icon = icons.development,
+ default_app = apps.default.development,
+ gap = beautiful.useless_gap,
+ layout = awful.layout.suit.floating
+ }
+ -- {
+ -- type = 'social',
+ -- icon = icons.social,
+ -- default_app = 'discord',
+ -- gap = beautiful.useless_gap
+ -- }
+}
+
+-- Set tags layout
+tag.connect_signal(
+ 'request::default_layouts',
+ function()
+ awful.layout.append_default_layouts({
+ awful.layout.suit.spiral.dwindle,
+ awful.layout.suit.tile,
+ awful.layout.suit.floating,
+ awful.layout.suit.max
+ })
+ end
+)
+
+-- Create tags for each screen
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ for i, tag in pairs(tags) do
+ awful.tag.add(
+ i,
+ {
+ icon = tag.icon,
+ icon_only = true,
+ layout = tag.layout or awful.layout.suit.spiral.dwindle,
+ gap_single_client = true,
+ gap = tag.gap,
+ screen = s,
+ default_app = tag.default_app,
+ selected = i == 1
+ }
+ )
+ end
+ end
+)
+
+local update_gap_and_shape = function(t)
+ -- Get current tag layout
+ local current_layout = awful.tag.getproperty(t, 'layout')
+ -- If the current layout is awful.layout.suit.max
+ if (current_layout == awful.layout.suit.max) then
+ -- Set clients gap to 0 and shape to rectangle if maximized
+ t.gap = 0
+ for _, c in ipairs(t:clients()) do
+ if not c.floating or not c.round_corners or c.maximized or c.fullscreen then
+ c.shape = beautiful.client_shape_rectangle
+ else
+ c.shape = beautiful.client_shape_rounded
+ end
+ end
+ else
+ t.gap = beautiful.useless_gap
+ for _, c in ipairs(t:clients()) do
+ if not c.round_corners or c.maximized or c.fullscreen then
+ c.shape = beautiful.client_shape_rectangle
+ else
+ c.shape = beautiful.client_shape_rounded
+ end
+ end
+ end
+end
+
+-- Change tag's client's shape and gap on change
+tag.connect_signal(
+ 'property::layout',
+ function(t)
+ update_gap_and_shape(t)
+ end
+)
+
+-- Change tag's client's shape and gap on move to tag
+tag.connect_signal(
+ 'tagged',
+ function(t)
+ update_gap_and_shape(t)
+ end
+)
+
+-- Focus on urgent clients
+awful.tag.attached_connect_signal(
+ s,
+ 'property::selected',
+ function()
+ local urgent_clients = function (c)
+ return awful.rules.match(c, {urgent = true})
+ end
+ for c in awful.client.iterate(urgent_clients) do
+ if c.first_tag == mouse.screen.selected_tag then
+ c:emit_signal('request::activate')
+ c:raise()
+ end
+ end
+ end
+)
diff --git a/.config/awesome/configuration/user-profile/default.svg b/.config/awesome/configuration/user-profile/default.svg
new file mode 100644
index 0000000..14f8006
--- /dev/null
+++ b/.config/awesome/configuration/user-profile/default.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/.config/awesome/layout/init.lua b/.config/awesome/layout/init.lua
new file mode 100644
index 0000000..362807c
--- /dev/null
+++ b/.config/awesome/layout/init.lua
@@ -0,0 +1,70 @@
+local awful = require('awful')
+local left_panel = require('layout.left-panel')
+local top_panel = require('layout.top-panel')
+local right_panel = require('layout.right-panel')
+
+-- Create a wibox panel for each screen and add it
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ if s.index == 1 then
+ s.left_panel = left_panel(s)
+ s.top_panel = top_panel(s, true)
+ else
+ s.top_panel = top_panel(s, false)
+ end
+ s.right_panel = right_panel(s)
+ s.right_panel_show_again = false
+ end
+)
+
+
+-- Hide bars when app go fullscreen
+function update_bars_visibility()
+ for s in screen do
+ if s.selected_tag then
+ local fullscreen = s.selected_tag.fullscreen_mode
+ -- Order matter here for shadow
+ s.top_panel.visible = not fullscreen
+ if s.left_panel then
+ s.left_panel.visible = not fullscreen
+ end
+ if s.right_panel then
+ if fullscreen and s.right_panel.visible then
+ s.right_panel:toggle()
+ s.right_panel_show_again = true
+ elseif not fullscreen and not s.right_panel.visible and s.right_panel_show_again then
+ s.right_panel:toggle()
+ s.right_panel_show_again = false
+ end
+ end
+ end
+ end
+end
+
+tag.connect_signal(
+ 'property::selected',
+ function(t)
+ update_bars_visibility()
+ end
+)
+
+client.connect_signal(
+ 'property::fullscreen',
+ function(c)
+ if c.first_tag then
+ c.first_tag.fullscreen_mode = c.fullscreen
+ end
+ update_bars_visibility()
+ end
+)
+
+client.connect_signal(
+ 'unmanage',
+ function(c)
+ if c.fullscreen then
+ c.screen.selected_tag.fullscreen_mode = false
+ update_bars_visibility()
+ end
+ end
+)
diff --git a/.config/awesome/layout/left-panel/action-bar.lua b/.config/awesome/layout/left-panel/action-bar.lua
new file mode 100755
index 0000000..7fd366c
--- /dev/null
+++ b/.config/awesome/layout/left-panel/action-bar.lua
@@ -0,0 +1,72 @@
+local awful = require('awful')
+local beautiful = require('beautiful')
+local wibox = require('wibox')
+local gears = require('gears')
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+local tag_list = require('widget.tag-list')
+local clickable_container = require('widget.clickable-container')
+
+return function(s, panel, action_bar_width)
+
+ local menu_icon = wibox.widget {
+ {
+ id = 'menu_btn',
+ image = icons.menu,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ }
+
+ local open_dashboard_button = wibox.widget {
+ {
+ menu_icon,
+ widget = clickable_container
+ },
+ bg = beautiful.background .. '66',
+ widget = wibox.container.background
+ }
+
+ open_dashboard_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ panel:toggle()
+ end
+ )
+ )
+ )
+
+ panel:connect_signal(
+ 'opened',
+ function()
+ menu_icon.menu_btn:set_image(gears.surface(icons.close_small))
+ end
+ )
+
+ panel:connect_signal(
+ 'closed',
+ function()
+ menu_icon.menu_btn:set_image(gears.surface(icons.menu))
+ end
+ )
+
+ return wibox.widget {
+ id = 'action_bar',
+ layout = wibox.layout.align.vertical,
+ forced_width = action_bar_width,
+ {
+ require('widget.search-apps')(),
+ tag_list(s),
+ require("widget.xdg-folders")(),
+ layout = wibox.layout.fixed.vertical,
+ },
+ nil,
+ open_dashboard_button
+ }
+end
diff --git a/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua b/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua
new file mode 100644
index 0000000..819d6e4
--- /dev/null
+++ b/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua
@@ -0,0 +1,47 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+
+local hardware_header = wibox.widget {
+ text = 'Hardware Monitor',
+ font = 'Inter Regular 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+
+}
+
+return wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ {
+ {
+ hardware_header,
+ left = dpi(24),
+ right = dpi(24),
+ widget = wibox.container.margin
+ },
+ bg = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.groups_radius)
+ end,
+ forced_height = dpi(35),
+ widget = wibox.container.background
+
+ },
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ require('widget.cpu-meter'),
+ require('widget.ram-meter'),
+ require('widget.temperature-meter'),
+ require('widget.harddrive-meter')
+ },
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+
+}
diff --git a/.config/awesome/layout/left-panel/dashboard/init.lua b/.config/awesome/layout/left-panel/dashboard/init.lua
new file mode 100644
index 0000000..2acaa7c
--- /dev/null
+++ b/.config/awesome/layout/left-panel/dashboard/init.lua
@@ -0,0 +1,80 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+return function(_, panel)
+
+ local search_widget = wibox.widget {
+ {
+ {
+ {
+ image = icons.search,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ {
+ text = 'Global Search',
+ font = 'Inter Regular 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+ }
+
+ search_button = wibox.widget {
+ {
+ search_widget,
+ widget = clickable_container
+ },
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+
+ search_button:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ panel:run_rofi()
+ end
+ )
+ )
+ )
+
+ return wibox.widget {
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(7),
+ search_button,
+ require('layout.left-panel.dashboard.hardware-monitor'),
+ require('layout.left-panel.dashboard.quick-settings'),
+
+ },
+ nil,
+ require('widget.end-session')(),
+ layout = wibox.layout.align.vertical
+ },
+ margins = dpi(16),
+ widget = wibox.container.margin
+ }
+end
diff --git a/.config/awesome/layout/left-panel/dashboard/quick-settings.lua b/.config/awesome/layout/left-panel/dashboard/quick-settings.lua
new file mode 100644
index 0000000..f5a1c2d
--- /dev/null
+++ b/.config/awesome/layout/left-panel/dashboard/quick-settings.lua
@@ -0,0 +1,67 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local bar_color = beautiful.groups_bg
+local dpi = beautiful.xresources.apply_dpi
+
+local quick_header = wibox.widget {
+ text = 'Quick Settings',
+ font = 'Inter Regular 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+
+}
+
+return wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(7),
+ {
+ layout = wibox.layout.fixed.vertical,
+ {
+ {
+ quick_header,
+ left = dpi(24),
+ right = dpi(24),
+ widget = wibox.container.margin
+ },
+ forced_height = dpi(35),
+ bg = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ },
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(7),
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ require('widget.brightness-slider'),
+ require('widget.volume-slider'),
+ require('widget.airplane-mode'),
+ require('widget.bluetooth-toggle'),
+ require('widget.blue-light')
+ },
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ },
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ require('widget.blur-slider'),
+ require('widget.blur-toggle')
+ },
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+ }
+ }
+}
diff --git a/.config/awesome/layout/left-panel/init.lua b/.config/awesome/layout/left-panel/init.lua
new file mode 100644
index 0000000..12171e5
--- /dev/null
+++ b/.config/awesome/layout/left-panel/init.lua
@@ -0,0 +1,154 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local apps = require('configuration.apps')
+
+local left_panel = function(screen)
+
+ local action_bar_width = dpi(45)
+ local panel_content_width = dpi(350)
+
+ local panel = wibox {
+ screen = screen,
+ width = action_bar_width,
+ type = 'dock',
+ height = screen.geometry.height,
+ x = screen.geometry.x,
+ y = screen.geometry.y,
+ ontop = true,
+ shape = gears.shape.rectangle,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ }
+
+ panel.opened = false
+
+ panel:struts {
+ left = action_bar_width
+ }
+
+ local backdrop = wibox {
+ ontop = true,
+ screen = screen,
+ bg = beautiful.transparent,
+ type = 'utility',
+ x = screen.geometry.x,
+ y = screen.geometry.y,
+ width = screen.geometry.width,
+ height = screen.geometry.height
+ }
+
+ function panel:run_rofi()
+ awesome.spawn(
+ apps.default.rofi_global,
+ false,
+ false,
+ false,
+ false,
+ function()
+ panel:toggle()
+ end
+ )
+
+ -- Hide panel content if rofi global search is opened
+ panel:get_children_by_id('panel_content')[1].visible = false
+ end
+
+ -- "Punch a hole" on backdrop to show the left dashboard
+ local update_backdrop = function(wibox_backdrop, wibox_panel)
+ local cairo = require('lgi').cairo
+ local geo = wibox_panel.screen.geometry
+
+ wibox_backdrop.x = geo.x
+ wibox_backdrop.y = geo.y
+ wibox_backdrop.width = geo.width
+ wibox_backdrop.height = geo.height
+
+ -- Create an image surface that is as large as the wibox_panel screen
+ local shape = cairo.ImageSurface.create(cairo.Format.A1, geo.width, geo.height)
+ local cr = cairo.Context(shape)
+
+ -- Fill with "completely opaque"
+ cr.operator = 'SOURCE'
+ cr:set_source_rgba(1, 1, 1, 1)
+ cr:paint()
+
+ -- Remove the shape of the client
+ local c_geo = wibox_panel:geometry()
+ local c_shape = gears.surface(wibox_panel.shape_bounding)
+ cr:set_source_rgba(0, 0, 0, 0)
+ cr:mask_surface(c_shape, c_geo.x + wibox_panel.border_width - geo.x, c_geo.y + wibox_panel.border_width - geo.y)
+ c_shape:finish()
+
+ wibox_backdrop.shape_bounding = shape._native
+ shape:finish()
+ wibox_backdrop:draw()
+ end
+
+ local open_panel = function(should_run_rofi)
+ panel.width = action_bar_width + panel_content_width
+ backdrop.visible = true
+ update_backdrop(backdrop, panel)
+ panel:get_children_by_id('panel_content')[1].visible = true
+ if should_run_rofi then
+ panel:run_rofi()
+ end
+ panel:emit_signal('opened')
+ end
+
+ local close_panel = function()
+ panel.width = action_bar_width
+ panel:get_children_by_id('panel_content')[1].visible = false
+ backdrop.visible = false
+ update_backdrop(backdrop, panel)
+ panel:emit_signal('closed')
+ end
+
+ -- Hide this panel when app dashboard is called.
+ function panel:hide_dashboard()
+ close_panel()
+ end
+
+ function panel:toggle(should_run_rofi)
+ self.opened = not self.opened
+ if self.opened then
+ open_panel(should_run_rofi)
+ else
+ close_panel()
+ end
+ end
+
+ backdrop:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ panel:toggle()
+ end
+ )
+ )
+ )
+
+ panel:setup {
+ layout = wibox.layout.align.horizontal,
+ nil,
+ {
+ id = 'panel_content',
+ bg = beautiful.transparent,
+ widget = wibox.container.background,
+ visible = false,
+ forced_width = panel_content_width,
+ {
+ require('layout.left-panel.dashboard')(screen, panel),
+ layout = wibox.layout.stack
+ }
+ },
+ require('layout.left-panel.action-bar')(screen, panel, action_bar_width)
+ }
+ return panel
+end
+
+return left_panel
diff --git a/.config/awesome/layout/right-panel/init.lua b/.config/awesome/layout/right-panel/init.lua
new file mode 100644
index 0000000..92c6f7b
--- /dev/null
+++ b/.config/awesome/layout/right-panel/init.lua
@@ -0,0 +1,166 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+panel_visible = false
+
+local right_panel = function(s)
+
+ -- Set right panel geometry
+ local panel_width = dpi(350)
+ local panel_x = s.geometry.x + s.geometry.width - panel_width
+
+ local panel = wibox {
+ ontop = true,
+ screen = s,
+ visible = false,
+ type = 'dock',
+ width = panel_width,
+ height = s.geometry.height,
+ x = panel_x,
+ y = s.geometry.y,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ }
+
+ panel.opened = false
+
+ s.backdrop_rdb = wibox {
+ ontop = true,
+ screen = s,
+ bg = beautiful.transparent,
+ type = 'utility',
+ x = s.geometry.x,
+ y = s.geometry.y,
+ width = s.geometry.width,
+ height = s.geometry.height
+ }
+
+ panel:struts {
+ right = 0
+ }
+
+ open_panel = function()
+ local focused = awful.screen.focused()
+ panel_visible = true
+
+ focused.backdrop_rdb.visible = true
+ focused.right_panel.visible = true
+
+ panel:emit_signal('opened')
+ end
+
+ close_panel = function()
+ local focused = awful.screen.focused()
+ panel_visible = false
+
+ focused.right_panel.visible = false
+ focused.backdrop_rdb.visible = false
+
+ panel:emit_signal('closed')
+ end
+
+ -- Hide this panel when app dashboard is called.
+ function panel:hide_dashboard()
+ close_panel()
+ end
+
+ function panel:toggle()
+ self.opened = not self.opened
+ if self.opened then
+ open_panel()
+ else
+ close_panel()
+ end
+ end
+
+
+ function panel:switch_pane(mode)
+ if mode == 'notif_mode' then
+ -- Update Content
+ panel:get_children_by_id('notif_id')[1].visible = true
+ panel:get_children_by_id('pane_id')[1].visible = false
+ elseif mode == 'today_mode' then
+ -- Update Content
+ panel:get_children_by_id('notif_id')[1].visible = false
+ panel:get_children_by_id('pane_id')[1].visible = true
+ end
+ end
+
+ s.backdrop_rdb:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ panel:toggle()
+ end
+ )
+ )
+ )
+
+ local separator = wibox.widget {
+ orientation = 'horizontal',
+ opacity = 0.0,
+ forced_height = 15,
+ widget = wibox.widget.separator,
+ }
+
+ local line_separator = wibox.widget {
+ orientation = 'horizontal',
+ forced_height = dpi(1),
+ span_ratio = 1.0,
+ color = beautiful.groups_title_bg,
+ widget = wibox.widget.separator
+ }
+
+ panel : setup {
+ {
+ expand = 'none',
+ layout = wibox.layout.fixed.vertical,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ require('widget.info-center-switch'),
+ nil
+ },
+ separator,
+ line_separator,
+ separator,
+ {
+ layout = wibox.layout.stack,
+ -- Today Pane
+ {
+ id = 'pane_id',
+ visible = true,
+ layout = wibox.layout.fixed.vertical,
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(7),
+ require('widget.user-profile'),
+ require('widget.weather'),
+ require('widget.email'),
+ require('widget.social-media'),
+ require('widget.calculator')
+ },
+
+ },
+ -- Notification Center
+ {
+ id = 'notif_id',
+ visible = false,
+ require('widget.notif-center')(s),
+ layout = wibox.layout.fixed.vertical,
+ }
+ },
+ },
+ margins = dpi(16),
+ widget = wibox.container.margin
+ }
+
+ return panel
+end
+
+return right_panel
+
diff --git a/.config/awesome/layout/right-panel/panel-mode-switcher.lua b/.config/awesome/layout/right-panel/panel-mode-switcher.lua
new file mode 100644
index 0000000..1b6876e
--- /dev/null
+++ b/.config/awesome/layout/right-panel/panel-mode-switcher.lua
@@ -0,0 +1,135 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+-- Variable used for switching panel modes
+right_panel_mode = 'today_mode'
+
+local active_button = beautiful.groups_title_bg
+local inactive_button = beautiful.transparent
+
+local notif_text = wibox.widget
+{
+ text = 'Notifications',
+ font = 'Inter Bold 11',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local notif_button = clickable_container(
+ wibox.container.margin(
+ notif_text, dpi(0), dpi(0), dpi(7), dpi(7)
+ )
+)
+
+local wrap_notif = wibox.widget {
+ notif_button,
+ forced_width = dpi(140),
+ bg = inactive_button,
+ border_width = dpi(1),
+ border_color = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, false, true, true, false, beautiful.groups_radius
+ )
+ end,
+ widget = wibox.container.background
+}
+
+
+local today_text = wibox.widget
+{
+ text = 'Today',
+ font = 'Inter Bold 11',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local today_button = clickable_container(
+ wibox.container.margin(
+ today_text, dpi(0), dpi(0), dpi(7), dpi(7)
+ )
+)
+
+local wrap_today = wibox.widget {
+ today_button,
+ forced_width = dpi(140),
+ bg = active_button,
+ border_width = dpi(1),
+ border_color = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, true, false, false, true, beautiful.groups_radius
+ )
+ end,
+ widget = wibox.container.background
+}
+
+local switcher = wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.fixed.horizontal,
+ wrap_today,
+ wrap_notif
+}
+
+
+function switch_rdb_pane(right_panel_mode)
+
+ local focused = awful.screen.focused()
+
+ if right_panel_mode == 'notif_mode' then
+
+ -- Update button color
+ wrap_notif.bg = active_button
+ wrap_today.bg = inactive_button
+
+ -- Change panel content of right-panel.lua
+ focused.right_panel:switch_pane(right_panel_mode)
+
+ elseif right_panel_mode == 'today_mode' then
+
+ -- Update button color
+ wrap_notif.bg = inactive_button
+ wrap_today.bg = active_button
+
+ -- Change panel content of right-panel.lua
+ focused.right_panel:switch_pane(right_panel_mode)
+ end
+
+end
+
+
+notif_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ switch_rdb_pane('notif_mode')
+ end
+ )
+ )
+)
+
+today_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ switch_rdb_pane('today_mode')
+ end
+ )
+ )
+)
+
+
+return switcher
diff --git a/.config/awesome/layout/top-panel.lua b/.config/awesome/layout/top-panel.lua
new file mode 100755
index 0000000..3c52906
--- /dev/null
+++ b/.config/awesome/layout/top-panel.lua
@@ -0,0 +1,99 @@
+local awful = require('awful')
+local beautiful = require('beautiful')
+local wibox = require('wibox')
+local gears = require('gears')
+local icons = require('theme.icons')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local task_list = require('widget.task-list')
+
+local top_panel = function(s, offset)
+
+ local offsetx = 0
+ if offset == true then
+ offsetx = dpi(45)
+ end
+
+ local panel = wibox
+ {
+ ontop = true,
+ screen = s,
+ type = 'dock',
+ height = dpi(28),
+ width = s.geometry.width - offsetx,
+ x = s.geometry.x + offsetx,
+ y = s.geometry.y,
+ stretch = false,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ }
+
+ panel:struts
+ {
+ top = dpi(28)
+ }
+
+ panel:connect_signal(
+ 'mouse::enter',
+ function()
+ local w = mouse.current_wibox
+ if w then
+ w.cursor = 'left_ptr'
+ end
+ end
+ )
+
+ s.systray = wibox.widget {
+ visible = false,
+ base_size = dpi(20),
+ horizontal = true,
+ screen = 'primary',
+ widget = wibox.widget.systray
+ }
+
+ local clock = require('widget.clock')(s)
+ local layout_box = require('widget.layoutbox')(s)
+ local add_button = require('widget.open-default-app')(s)
+ s.tray_toggler = require('widget.tray-toggle')
+ s.updater = require('widget.package-updater')()
+ s.screen_rec = require('widget.screen-recorder')()
+ s.mpd = require('widget.mpd')()
+ s.bluetooth = require('widget.bluetooth')()
+ s.battery = require('widget.battery')()
+ s.network = require('widget.network')()
+ s.info_center_toggle = require('widget.info-center-toggle')()
+
+ panel : setup {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ {
+ layout = wibox.layout.fixed.horizontal,
+ task_list(s),
+ add_button
+ },
+ clock,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(5),
+ {
+ s.systray,
+ margins = dpi(5),
+ widget = wibox.container.margin
+ },
+ s.tray_toggler,
+ s.updater,
+ s.screen_rec,
+ s.mpd,
+ s.network,
+ s.bluetooth,
+ s.battery,
+ layout_box,
+ s.info_center_toggle
+ }
+ }
+
+ return panel
+end
+
+
+return top_panel
diff --git a/.config/awesome/library/json.lua b/.config/awesome/library/json.lua
new file mode 100644
index 0000000..3fbaea7
--- /dev/null
+++ b/.config/awesome/library/json.lua
@@ -0,0 +1,201 @@
+-- ░▀▀█░█▀▀░█▀█░█▀█░░
+-- ░░░█░▀▀█░█░█░█░█░░
+-- ░▀▀░░▀▀▀░▀▀▀░▀░▀░░
+
+-- This script is from https://gist.github.com/tylerneylon/59f4bcf316be525b30ab
+-- License: None. Public Domain
+
+--[[ json.lua
+
+A compact pure-Lua JSON library.
+The main functions are: json.stringify, json.parse.
+
+## json.stringify:
+
+This expects the following to be true of any tables being encoded:
+ * They only have string or number keys. Number keys must be represented as
+ strings in json; this is part of the json spec.
+ * They are not recursive. Such a structure cannot be specified in json.
+
+A Lua table is considered to be an array if and only if its set of keys is a
+consecutive sequence of positive integers starting at 1. Arrays are encoded like
+so: `[2, 3, false, "hi"]`. Any other type of Lua table is encoded as a json
+object, encoded like so: `{"key1": 2, "key2": false}`.
+
+Because the Lua nil value cannot be a key, and as a table value is considerd
+equivalent to a missing key, there is no way to express the json "null" value in
+a Lua table. The only way this will output "null" is if your entire input obj is
+nil itself.
+
+An empty Lua table, {}, could be considered either a json object or array -
+it's an ambiguous edge case. We choose to treat this as an object as it is the
+more general type.
+
+To be clear, none of the above considerations is a limitation of this code.
+Rather, it is what we get when we completely observe the json specification for
+as arbitrary a Lua object as json is capable of expressing.
+
+## json.parse:
+
+This function parses json, with the exception that it does not pay attention to
+\u-escaped unicode code points in strings.
+
+It is difficult for Lua to return null as a value. In order to prevent the loss
+of keys with a null value in a json string, this function uses the one-off
+table value json.null (which is just an empty table) to indicate null values.
+This way you can check if a value is null with the conditional
+`val == json.null`.
+
+If you have control over the data and are using Lua, I would recommend just
+avoiding null values in your data to begin with.
+
+--]]
+
+
+local json = {}
+
+
+-- Internal functions.
+
+local function kind_of(obj)
+ if type(obj) ~= 'table' then return type(obj) end
+ local i = 1
+ for _ in pairs(obj) do
+ if obj[i] ~= nil then i = i + 1 else return 'table' end
+ end
+ if i == 1 then return 'table' else return 'array' end
+end
+
+local function escape_str(s)
+ local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
+ local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'}
+ for i, c in ipairs(in_char) do
+ s = s:gsub(c, '\\' .. out_char[i])
+ end
+ return s
+end
+
+-- Returns pos, did_find; there are two cases:
+-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true.
+-- 2. Delimiter not found: pos = pos after leading space; did_find = false.
+-- This throws an error if err_if_missing is true and the delim is not found.
+local function skip_delim(str, pos, delim, err_if_missing)
+ pos = pos + #str:match('^%s*', pos)
+ if str:sub(pos, pos) ~= delim then
+ if err_if_missing then
+ error('Expected ' .. delim .. ' near position ' .. pos)
+ end
+ return pos, false
+ end
+ return pos + 1, true
+end
+
+-- Expects the given pos to be the first character after the opening quote.
+-- Returns val, pos; the returned pos is after the closing quote character.
+local function parse_str_val(str, pos, val)
+ val = val or ''
+ local early_end_error = 'End of input found while parsing string.'
+ if pos > #str then error(early_end_error) end
+ local c = str:sub(pos, pos)
+ if c == '"' then return val, pos + 1 end
+ if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end
+ -- We must have a \ character.
+ local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
+ local nextc = str:sub(pos + 1, pos + 1)
+ if not nextc then error(early_end_error) end
+ return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc))
+end
+
+-- Returns val, pos; the returned pos is after the number's final character.
+local function parse_num_val(str, pos)
+ local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
+ local val = tonumber(num_str)
+ if not val then error('Error parsing number at position ' .. pos .. '.') end
+ return val, pos + #num_str
+end
+
+
+-- Public values and functions.
+
+function json.stringify(obj, as_key)
+ local s = {} -- We'll build the string as an array of strings to be concatenated.
+ local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise.
+ if kind == 'array' then
+ if as_key then error('Can\'t encode array as key.') end
+ s[#s + 1] = '['
+ for i, val in ipairs(obj) do
+ if i > 1 then s[#s + 1] = ', ' end
+ s[#s + 1] = json.stringify(val)
+ end
+ s[#s + 1] = ']'
+ elseif kind == 'table' then
+ if as_key then error('Can\'t encode table as key.') end
+ s[#s + 1] = '{'
+ for k, v in pairs(obj) do
+ if #s > 1 then s[#s + 1] = ', ' end
+ s[#s + 1] = json.stringify(k, true)
+ s[#s + 1] = ':'
+ s[#s + 1] = json.stringify(v)
+ end
+ s[#s + 1] = '}'
+ elseif kind == 'string' then
+ return '"' .. escape_str(obj) .. '"'
+ elseif kind == 'number' then
+ if as_key then return '"' .. tostring(obj) .. '"' end
+ return tostring(obj)
+ elseif kind == 'boolean' then
+ return tostring(obj)
+ elseif kind == 'nil' then
+ return 'null'
+ else
+ error('Unjsonifiable type: ' .. kind .. '.')
+ end
+ return table.concat(s)
+end
+
+json.null = {} -- This is a one-off table to represent the null value.
+
+function json.parse(str, pos, end_delim)
+ pos = pos or 1
+ if pos > #str then error('Reached unexpected end of input.') end
+ local pos = pos + #str:match('^%s*', pos) -- Skip whitespace.
+ local first = str:sub(pos, pos)
+ if first == '{' then -- Parse an object.
+ local obj, key, delim_found = {}, true, true
+ pos = pos + 1
+ while true do
+ key, pos = json.parse(str, pos, '}')
+ if key == nil then return obj, pos end
+ if not delim_found then error('Comma missing between object items.') end
+ pos = skip_delim(str, pos, ':', true) -- true -> error if missing.
+ obj[key], pos = json.parse(str, pos)
+ pos, delim_found = skip_delim(str, pos, ',')
+ end
+ elseif first == '[' then -- Parse an array.
+ local arr, val, delim_found = {}, true, true
+ pos = pos + 1
+ while true do
+ val, pos = json.parse(str, pos, ']')
+ if val == nil then return arr, pos end
+ if not delim_found then error('Comma missing between array items.') end
+ arr[#arr + 1] = val
+ pos, delim_found = skip_delim(str, pos, ',')
+ end
+ elseif first == '"' then -- Parse a string.
+ return parse_str_val(str, pos + 1)
+ elseif first == '-' or first:match('%d') then -- Parse a number.
+ return parse_num_val(str, pos)
+ elseif first == end_delim then -- End of an object or array.
+ return nil, pos + 1
+ else -- Parse true, false, or null.
+ local literals = {['true'] = true, ['false'] = false, ['null'] = json.null}
+ for lit_str, lit_val in pairs(literals) do
+ local lit_end = pos + #lit_str - 1
+ if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end
+ end
+ local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10)
+ error('Invalid json syntax starting at ' .. pos_info_str)
+ end
+end
+
+return json
diff --git a/.config/awesome/module/auto-start.lua b/.config/awesome/module/auto-start.lua
new file mode 100644
index 0000000..601bd39
--- /dev/null
+++ b/.config/awesome/module/auto-start.lua
@@ -0,0 +1,36 @@
+-- MODULE AUTO-START
+-- Run all the apps listed in configuration/apps.lua as run_on_start_up only once when awesome start
+
+local awful = require('awful')
+local naughty = require('naughty')
+local apps = require('configuration.apps')
+local config = require('configuration.config')
+local debug_mode = config.module.auto_start.debug_mode or false
+
+local run_once = function(cmd)
+ local findme = cmd
+ local firstspace = cmd:find(' ')
+ if firstspace then
+ findme = cmd:sub(0, firstspace - 1)
+ end
+ awful.spawn.easy_async_with_shell(
+ string.format('pgrep -u $USER -x %s > /dev/null || (%s)', findme, cmd),
+ function(stdout, stderr)
+ -- Debugger
+ if not stderr or stderr == '' or not debug_mode then
+ return
+ end
+ naughty.notification({
+ app_name = 'Start-up Applications',
+ title = 'Oof! Error detected when starting an application!',
+ message = stderr:gsub('%\n', ''),
+ timeout = 20,
+ icon = require('beautiful').awesome_icon
+ })
+ end
+ )
+end
+
+for _, app in ipairs(apps.run_on_start_up) do
+ run_once(app)
+end
diff --git a/.config/awesome/module/brightness-osd.lua b/.config/awesome/module/brightness-osd.lua
new file mode 100644
index 0000000..4538736
--- /dev/null
+++ b/.config/awesome/module/brightness-osd.lua
@@ -0,0 +1,268 @@
+local awful = require("awful")
+local gears = require("gears")
+local wibox = require("wibox")
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+local osd_header = wibox.widget {
+ text = 'Brightness',
+ font = 'Inter Bold 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local osd_value = wibox.widget {
+ text = '0%',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local slider_osd = wibox.widget {
+ nil,
+ {
+ id = 'bri_osd_slider',
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(2),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+local bri_osd_slider = slider_osd.bri_osd_slider
+
+bri_osd_slider:connect_signal(
+ 'property::value',
+ function()
+ local brightness_level = bri_osd_slider:get_value()
+
+ awful.spawn('light -S ' .. math.max(brightness_level, 5), false)
+
+ -- Update textbox widget text
+ osd_value.text = brightness_level .. '%'
+
+ -- Update the brightness slider if values here change
+ awesome.emit_signal('widget::brightness:update', brightness_level)
+
+ if awful.screen.focused().show_bri_osd then
+ awesome.emit_signal(
+ 'module::brightness_osd:show',
+ true
+ )
+ end
+ end
+)
+
+bri_osd_slider:connect_signal(
+ 'button::press',
+ function()
+ awful.screen.focused().show_bri_osd = true
+ end
+)
+
+bri_osd_slider:connect_signal(
+ 'mouse::enter',
+ function()
+ awful.screen.focused().show_bri_osd = true
+ end
+)
+
+-- The emit will come from brightness slider
+awesome.connect_signal(
+ 'module::brightness_osd',
+ function(brightness)
+ bri_osd_slider:set_value(brightness)
+ end
+)
+
+local icon = wibox.widget {
+ {
+ image = icons.brightness,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+}
+
+local brightness_slider_osd = wibox.widget {
+ icon,
+ slider_osd,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+}
+
+local osd_height = dpi(100)
+local osd_width = dpi(300)
+local osd_margin = dpi(10)
+
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ local s = s or {}
+ s.show_bri_osd = false
+
+ s.brightness_osd_overlay = awful.popup {
+ widget = {
+ -- Removing this block will cause an error...
+ },
+ ontop = true,
+ visible = false,
+ type = 'notification',
+ screen = s,
+ height = osd_height,
+ width = osd_width,
+ maximum_height = osd_height,
+ maximum_width = osd_width,
+ offset = dpi(5),
+ shape = gears.shape.rectangle,
+ bg = beautiful.transparent,
+ preferred_anchors = 'middle',
+ preferred_positions = {'left', 'right', 'top', 'bottom'}
+ }
+
+ s.brightness_osd_overlay : setup {
+ {
+ {
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ forced_height = dpi(48),
+ osd_header,
+ nil,
+ osd_value
+ },
+ brightness_slider_osd,
+ layout = wibox.layout.fixed.vertical
+ },
+ left = dpi(24),
+ right = dpi(24),
+ widget = wibox.container.margin
+ },
+ bg = beautiful.background,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background()
+ }
+
+ -- Reset timer on mouse hover
+ s.brightness_osd_overlay:connect_signal(
+ 'mouse::enter',
+ function()
+ awful.screen.focused().show_bri_osd = true
+ awesome.emit_signal('module::brightness_osd:rerun')
+ end
+ )
+ end
+)
+
+local hide_osd = gears.timer {
+ timeout = 2,
+ autostart = true,
+ callback = function()
+ local focused = awful.screen.focused()
+ focused.brightness_osd_overlay.visible = false
+ focused.show_bri_osd = false
+ end
+}
+
+awesome.connect_signal(
+ 'module::brightness_osd:rerun',
+ function()
+ if hide_osd.started then
+ hide_osd:again()
+ else
+ hide_osd:start()
+ end
+ end
+)
+
+local placement_placer = function()
+ local focused = awful.screen.focused()
+
+ local right_panel = focused.right_panel
+ local left_panel = focused.left_panel
+ local brightness_osd = focused.brightness_osd_overlay
+
+ if right_panel and left_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(
+ brightness_osd,
+ {
+ margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin
+ },
+ honor_workarea = true
+ }
+ )
+ return
+ end
+ end
+
+ if right_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(
+ brightness_osd,
+ {
+ margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin
+ },
+ honor_workarea = true
+ }
+ )
+ return
+ end
+ end
+
+ awful.placement.bottom_right(
+ brightness_osd,
+ {
+ margins = {
+ left = 0,
+ right = osd_margin,
+ top = 0,
+ bottom = osd_margin
+ },
+ honor_workarea = true
+ }
+ )
+end
+
+awesome.connect_signal(
+ 'module::brightness_osd:show',
+ function(bool)
+ placement_placer()
+ awful.screen.focused().brightness_osd_overlay.visible = bool
+ if bool then
+ awesome.emit_signal('module::brightness_osd:rerun')
+ awesome.emit_signal(
+ 'module::volume_osd:show',
+ false
+ )
+ else
+ if hide_osd.started then
+ hide_osd:stop()
+ end
+ end
+ end
+)
diff --git a/.config/awesome/module/dynamic-wallpaper.lua b/.config/awesome/module/dynamic-wallpaper.lua
new file mode 100755
index 0000000..72e4406
--- /dev/null
+++ b/.config/awesome/module/dynamic-wallpaper.lua
@@ -0,0 +1,364 @@
+----------------------------------------------------------------------------
+--- Wallpaper changer module
+--
+-- @author Gerome Matilla <gerome.matilla07@gmail.com>
+-- @copyright 2019 Gerome Matilla
+-- @module wallchange
+--
+--- Nevermind this. Do what you want.
+----------------------------------------------------------------------------
+
+-- This module changes wallpaper based on declared time
+-- It checks the difference between the current time and the next scheduled time
+-- Then convert it to seconds to set it as a timeout value
+
+-- Limitations:
+-- Timeout paused when laptop/pc is suspended or in sleep mode, and there's probably some bugs too so whatever
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local filesystem = gears.filesystem
+local config = require('configuration.config')
+
+
+-- ========================================
+-- Configuration
+-- Change your preference here
+-- ========================================
+
+local wall_config = {
+ -- Wallpaper directory. The default is:
+ -- local wall_config.wall_dir = os.getenv('HOME') .. 'Pictures/Wallpapers/'
+ wall_dir = filesystem.get_configuration_dir() .. (config.module.dynamic_wallpaper.wall_dir or 'theme/wallpapers/'),
+
+ -- If there's a picture format that awesome accepts and i missed
+ -- (which i probably did) feel free to add it right here
+ valid_picture_formats = config.module.dynamic_wallpaper.valid_picture_formats or {"jpg", "png", "jpeg"},
+
+ -- Table mapping schedule to wallpaper filename
+ wallpaper_schedule = config.module.dynamic_wallpaper.wallpaper_schedule or {
+ ['00:00:00'] = 'midnight-wallpaper.jpg',
+ ['06:22:00'] = 'morning-wallpaper.jpg',
+ ['12:00:00'] = 'noon-wallpaper.jpg',
+ ['17:58:00'] = 'night-wallpaper.jpg'
+ },
+
+ -- Don't stretch wallpaper on multihead setups if true
+ stretch = config.module.dynamic_wallpaper.stretch or false
+}
+
+-- ========================================
+-- Processes
+-- Don't touch it if it's working
+-- ========================================
+
+-- Get current time
+local current_time = function()
+ return os.date('%H:%M:%S')
+end
+
+-- Countdown variable
+-- In seconds
+local the_countdown = nil
+
+-- Parse seconds to HH:MM:SS
+local function parse_to_time(seconds)
+ -- DST ruined me :(
+ --return os.date("%H:%M:%S", seconds)
+
+ local function format(str)
+ while #str < 2 do
+ str = '0' .. str
+ end
+
+ return str
+ end
+
+ local function convert(num)
+ return format(tostring(num))
+ end
+
+ local hours = convert(math.floor(seconds / 3600))
+ seconds = seconds - (hours * 3600)
+
+ local minutes = convert(math.floor(seconds / 60))
+ seconds = seconds - (minutes * 60)
+
+ local seconds = convert(math.floor(seconds))
+
+ return (hours .. ':' .. minutes .. ':' .. seconds)
+
+end
+
+-- Parse HH:MM:SS to seconds
+local parse_to_seconds = function(time)
+
+ -- Convert HH in HH:MM:SS
+ local hour_sec = tonumber(string.sub(time, 1, 2)) * 3600
+
+ -- Convert MM in HH:MM:SS
+ local min_sec = tonumber(string.sub(time, 4, 5)) * 60
+
+ -- Get SS in HH:MM:SS
+ local get_sec = tonumber(string.sub(time, 7, 8))
+
+ -- Return computed seconds
+ return (hour_sec + min_sec + get_sec)
+end
+
+-- Get time difference
+local time_diff = function(future, past)
+ local diff = parse_to_seconds(future) - parse_to_seconds(past)
+ if diff < 0 then
+ diff = diff + (24 * 3600) --If time difference is negative, the future is meant for tomorrow
+ end
+ return diff
+end
+
+-- Returns a table containing all file paths in a directory
+local function get_dir_contents(dir)
+ -- Command to give list of files in directory
+ local dir_explore = 'find ' .. dir .. ' -printf "%f\\n"'
+ local lines = io.popen(dir_explore):lines() --Done synchronously because we literally can't continue without files
+ local files = {}
+ for line in lines do
+ table.insert(files, line)
+ end
+ return files
+end
+
+-- Returns a table of all the files that were one of the valid file formats
+local function filter_files_by_format(files, valid_file_formats)
+ local valid_files = {}
+ for _, file in ipairs(files) do
+ for _, format in ipairs(valid_file_formats) do
+ if string.match(file, ".+%." .. format) ~= nil then
+ table.insert(valid_files, file)
+ break --No need to check other formats
+ end
+ end
+ end
+
+ return valid_files
+end
+
+-- Returns a table of files that contained any of the keywords, in the same order as the words themselves
+local function find_files_containing_keywords(files, keywords)
+ local found_files = {}
+
+ for _, word in ipairs(keywords) do --Preserves keyword order inherently, conveniently
+ for _, file in ipairs(files) do
+ -- Check if file is word, contains word at beginning or contains word between 2 non-alphanumeric characters
+ if file == word or string.find(file, "^" .. word .. "[^%a]") or string.find(file, "[^%a]" .. word .. "[^%a]") then
+ found_files[word] = file
+ break --Only return 1 file per word
+ end
+ end
+ end
+
+ return found_files
+end
+
+-- Turn an ordered list of files into a scheduled list of files
+local function auto_schedule(wall_list)
+ local sched = {}
+ for index, file in ipairs(wall_list) do
+ local auto_time = parse_to_time(parse_to_seconds("24:00:00") * (index - 1) / #wall_list)
+ sched[auto_time] = file
+ end
+
+ return sched
+end
+
+-- Reformat whatever schedule was specified into an actual schedule
+if #wall_config.wallpaper_schedule == 0 then
+ local count = 0
+ -- Determine if empty or if manual schedule
+ for k, v in pairs(wall_config.wallpaper_schedule) do
+ count = count + 1
+ end
+
+ if count == 0 then --Schedule is actually empty
+ -- Get all pictures
+ local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats)
+
+ --Sort pictures as sanely as possible
+ local function order_pictures(a, b) --Attempts to mimic default sort but numbers aren't compared as strings
+ if tonumber(a) ~= nil and tonumber(b) ~= nil then
+ return tonumber(a) < tonumber(b)
+ else
+ return a < b
+ end
+ end
+ table.sort(pictures, order_pictures)
+
+ wall_config.wallpaper_schedule = auto_schedule(pictures)
+
+ else --Schedule is manually timed
+ -- Get times as list
+ local ordered_times = {}
+ for time, _ in pairs(wall_config.wallpaper_schedule) do
+ table.insert(ordered_times, time)
+ end
+
+ -- Sort times using seconds as comparison
+ local function order_time_asc(a, b)
+ return parse_to_seconds(a) < parse_to_seconds(b)
+ end
+ table.sort(ordered_times, order_time_asc)
+
+ -- Get ordered list of keywords from ordered times
+ local keywords = {}
+ for index, time in ipairs(ordered_times) do
+ keywords[index] = wall_config.wallpaper_schedule[time]
+ end
+
+ -- Get any pictures that match keywords
+ local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats)
+ pictures = find_files_containing_keywords(pictures, keywords)
+
+ -- Replace keywords with files
+ for index, time in ipairs(ordered_times) do
+ local word = wall_config.wallpaper_schedule[time]
+ if pictures[word] ~= nil then
+ wall_config.wallpaper_schedule[time] = pictures[word]
+ else --To avoid crashes, we'll remove entries with invalid keywords
+ wall_config.wallpaper_schedule[time] = nil
+ end
+ end
+ end
+else --Schedule is list of keywords
+ local keywords = wall_config.wallpaper_schedule
+
+ -- Get any pictures that match keywords
+ local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats)
+ pictures = find_files_containing_keywords(pictures, keywords)
+
+ -- Order files by keyword (if a file was found for the keyword)
+ local ordered_pictures = {}
+ for _, word in ipairs(keywords) do
+ local file = pictures[word]
+ if file ~= nil then
+ table.insert(ordered_pictures, file)
+ end
+ end
+
+ wall_config.wallpaper_schedule = auto_schedule(ordered_pictures)
+end
+
+-- Set wallpaper
+local set_wallpaper = function(path)
+ if wall_config.stretch then
+ for s in screen do
+ -- Update wallpaper based on the data in the array
+ gears.wallpaper.maximized (path, s)
+ end
+ else
+ -- Update wallpaper based on the data in the array
+ gears.wallpaper.maximized (path)
+ end
+end
+
+-- Update wallpaper (used by the manage_timer function)
+-- I think the gears.wallpaper.maximized is too fast or being ran asynchronously
+-- So the wallpaper is not being updated on awesome (re)start without this timer
+-- We need some delay.
+-- Hey it's working, so whatever
+local update_wallpaper = function(wall_name)
+ local wall_dir = wall_config.wall_dir .. wall_name
+ set_wallpaper(wall_dir)
+
+ -- Overwrite the default wallpaper
+ -- This is important in case we add an extra monitor
+ beautiful.wallpaper = wall_dir
+end
+
+-- Updates variables
+local manage_timer = function()
+ -- Get current time
+ local time_now = parse_to_seconds(current_time())
+
+ local previous_time = '' --Scheduled time that should activate now
+ local next_time = '' --Time that should activate next
+
+ local first_time = '24:00:00' --First scheduled time registered (to be found)
+ local last_time = '00:00:00' --Last scheduled time registered (to be found)
+
+ -- Find previous_time
+ for time, wallpaper in pairs(wall_config.wallpaper_schedule) do
+ local parsed_time = parse_to_seconds(time)
+ if previous_time == '' or parsed_time > parse_to_seconds(previous_time) then
+ if parsed_time <= time_now then
+ previous_time = time
+ end
+ end
+
+ if parsed_time > parse_to_seconds(last_time) then
+ last_time = time
+ end
+ end
+
+ -- Previous time being blank = no scheduled time today. Therefore
+ -- the last time was yesterday's latest time
+ if previous_time == '' then
+ previous_time = last_time
+ end
+
+ --Find next_time
+ for time, wallpaper in pairs(wall_config.wallpaper_schedule) do
+ local parsed_time = parse_to_seconds(time)
+ if next_time == '' or parsed_time < parse_to_seconds(next_time) then
+ if parsed_time > time_now then
+ next_time = time
+ end
+ end
+
+ if parsed_time < parse_to_seconds(first_time) then
+ first_time = time
+ end
+ end
+
+ -- Next time being blank means that there is no scheduled times left for
+ -- the current day. So next scheduled time is tomorrow's first time
+ if next_time == '' then
+ next_time = first_time
+ end
+
+ -- Update Wallpaper
+ update_wallpaper(wall_config.wallpaper_schedule[previous_time])
+
+ -- Get the time difference to set as timeout for the wall_updater timer below
+ the_countdown = time_diff(next_time, current_time())
+
+end
+
+-- Update values at startup
+manage_timer()
+
+local wall_updater = gears.timer {
+ -- The timeout is the difference of current time and the scheduled time we set above.
+ timeout = the_countdown,
+ autostart = true,
+ call_now = true,
+ callback = function()
+ -- Emit signal to update wallpaper
+ awesome.emit_signal('module::change_wallpaper')
+ end
+}
+
+-- Update wallpaper here and update the timeout for the next schedule
+awesome.connect_signal(
+ 'module::change_wallpaper',
+ function()
+ --set_wallpaper(wall_dir .. wall_data[2])
+
+ -- Update values for the next specified schedule
+ manage_timer()
+
+ -- Update timer timeout for the next specified schedule
+ wall_updater.timeout = the_countdown
+
+ -- Restart timer
+ wall_updater:again()
+ end
+)
diff --git a/.config/awesome/module/exit-screen.lua b/.config/awesome/module/exit-screen.lua
new file mode 100644
index 0000000..ee26849
--- /dev/null
+++ b/.config/awesome/module/exit-screen.lua
@@ -0,0 +1,360 @@
+local awful = require('awful')
+local gears = require('gears')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local filesystem = gears.filesystem
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+local apps = require('configuration.apps')
+local clickable_container = require('widget.clickable-container')
+local config_dir = filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'configuration/user-profile/'
+
+local msg_table = {
+ 'See you later, alligator!',
+ 'After a while, crocodile.',
+ 'Stay out of trouble.',
+ 'I’m out of here.',
+ 'Yamete, onii-chan~. UwU',
+ 'Okay...bye, fry guy!',
+ 'Peace out!',
+ 'Peace out, bitch!',
+ 'Gotta get going.',
+ 'Out to the door, dinosaur.',
+ 'Don\'t forget to come back!',
+ 'Smell ya later!',
+ 'In a while, crocodile.',
+ 'Adios, amigo.',
+ 'Begone!',
+ 'Arrivederci.',
+ 'Never look back!',
+ 'So long, sucker!',
+ 'Au revoir!',
+ 'Later, skater!',
+ 'That\'ll do pig. That\'ll do.',
+ 'Happy trails!',
+ 'Smell ya later!',
+ 'See you soon, baboon!',
+ 'Bye Felicia!',
+ 'Sayonara!',
+ 'Ciao!',
+ 'Well.... bye.',
+ 'Delete your browser history!',
+ 'See you, Space Cowboy!',
+ 'Change da world. My final message. Goodbye.',
+ 'Find out on the next episode of Dragonball Z...',
+ 'Choose wisely!'
+}
+
+local greeter_message = wibox.widget {
+ markup = 'Choose wisely!',
+ font = 'Inter UltraLight 48',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local profile_name = wibox.widget {
+ markup = 'user@hostname',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local profile_imagebox = wibox.widget {
+ image = widget_icon_dir .. 'default.svg',
+ resize = true,
+ forced_height = dpi(140),
+ clip_shape = gears.shape.circle,
+ widget = wibox.widget.imagebox
+}
+
+local update_profile_pic = function()
+ awful.spawn.easy_async_with_shell(
+ apps.utils.update_profile,
+ function(stdout)
+ stdout = stdout:gsub('%\n','')
+ if not stdout:match('default') then
+ profile_imagebox:set_image(stdout)
+ else
+ profile_imagebox:set_image(widget_icon_dir .. 'default.svg')
+ end
+ profile_imagebox:emit_signal('widget::redraw_needed')
+ end
+ )
+end
+
+update_profile_pic()
+
+local update_user_name = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")"
+ if [ -z "$fullname" ];
+ then
+ printf "$(whoami)@$(hostname)"
+ else
+ printf "$fullname"
+ fi
+ ]],
+ function(stdout)
+ stdout = stdout:gsub('%\n','')
+ local first_name = stdout:match('(.*)@') or stdout:match('(.-)%s')
+ first_name = first_name:sub(1, 1):upper() .. first_name:sub(2)
+ profile_name:set_markup(stdout)
+ profile_name:emit_signal('widget::redraw_needed')
+ end
+ )
+end
+
+update_user_name()
+
+local update_greeter_msg = function()
+ greeter_message:set_markup(msg_table[math.random(#msg_table)])
+ greeter_message:emit_signal('widget::redraw_needed')
+end
+
+update_greeter_msg()
+
+local build_power_button = function(name, icon, callback)
+ local power_button_label= wibox.widget {
+ text = name,
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local power_button = wibox.widget {
+ {
+ {
+ {
+ {
+ image = icon,
+ widget = wibox.widget.imagebox
+ },
+ margins = dpi(16),
+ widget = wibox.container.margin
+ },
+ bg = beautiful.groups_bg,
+ widget = wibox.container.background
+ },
+ shape = gears.shape.rounded_rect,
+ forced_width = dpi(90),
+ forced_height = dpi(90),
+ widget = clickable_container
+ },
+ left = dpi(24),
+ right = dpi(24),
+ widget = wibox.container.margin
+ }
+
+ local exit_screen_item = wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ power_button,
+ power_button_label
+ }
+
+ exit_screen_item:connect_signal(
+ 'button::release',
+ function()
+ callback()
+ end
+ )
+ return exit_screen_item
+end
+
+local suspend_command = function()
+ awesome.emit_signal('module::exit_screen:hide')
+ awful.spawn.with_shell(apps.default.lock .. ' & systemctl suspend')
+end
+
+local logout_command = function()
+ awesome.quit()
+end
+
+local lock_command = function()
+ awesome.emit_signal('module::exit_screen:hide')
+ awful.spawn.with_shell(apps.default.lock)
+end
+
+local poweroff_command = function()
+ awful.spawn.with_shell('poweroff')
+ awesome.emit_signal('module::exit_screen:hide')
+end
+
+local reboot_command = function()
+ awful.spawn.with_shell('reboot')
+ awesome.emit_signal('module::exit_screen:hide')
+end
+
+local poweroff = build_power_button('Shutdown', icons.power, poweroff_command)
+local reboot = build_power_button('Restart', icons.restart, reboot_command)
+local suspend = build_power_button('Sleep', icons.sleep, suspend_command)
+local logout = build_power_button('Logout', icons.logout, logout_command)
+local lock = build_power_button('Lock', icons.lock, lock_command)
+
+local create_exit_screen = function(s)
+ s.exit_screen = wibox
+ {
+ screen = s,
+ type = 'splash',
+ visible = false,
+ ontop = true,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal,
+ height = s.geometry.height,
+ width = s.geometry.width,
+ x = s.geometry.x,
+ y = s.geometry.y
+ }
+
+ s.exit_screen:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 2,
+ function()
+ awesome.emit_signal('module::exit_screen:hide')
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ function()
+ awesome.emit_signal('module::exit_screen:hide')
+ end
+ )
+ )
+ )
+
+ s.exit_screen : setup {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.vertical,
+ {
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ profile_imagebox,
+ nil
+ },
+ nil
+ },
+ profile_name
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ widget = wibox.container.margin,
+ margins = dpi(15),
+ greeter_message
+ },
+ nil
+ },
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ {
+ {
+ poweroff,
+ reboot,
+ suspend,
+ logout,
+ lock,
+ layout = wibox.layout.fixed.horizontal
+ },
+ spacing = dpi(30),
+ layout = wibox.layout.fixed.vertical
+ },
+ widget = wibox.container.margin,
+ margins = dpi(15)
+ },
+ nil
+ }
+ },
+ nil
+ }
+end
+
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ create_exit_screen(s)
+ end
+)
+
+screen.connect_signal(
+ 'removed',
+ function(s)
+ create_exit_screen(s)
+ end
+)
+
+local exit_screen_grabber = awful.keygrabber {
+ auto_start = true,
+ stop_event = 'release',
+ keypressed_callback = function(self, mod, key, command)
+ if key == 's' then
+ suspend_command()
+
+ elseif key == 'e' then
+ logout_command()
+
+ elseif key == 'l' then
+ lock_command()
+
+ elseif key == 'p' then
+ poweroff_command()
+
+ elseif key == 'r' then
+ reboot_command()
+
+ elseif key == 'Escape' or key == 'q' or key == 'x' then
+ awesome.emit_signal('module::exit_screen:hide')
+ end
+ end
+}
+
+awesome.connect_signal(
+ 'module::exit_screen:show',
+ function()
+ for s in screen do
+ s.exit_screen.visible = false
+ end
+ awful.screen.focused().exit_screen.visible = true
+ exit_screen_grabber:start()
+ end
+)
+
+awesome.connect_signal(
+ 'module::exit_screen:hide',
+ function()
+ update_greeter_msg()
+ exit_screen_grabber:stop()
+ for s in screen do
+ s.exit_screen.visible = false
+ end
+ end
+)
diff --git a/.config/awesome/module/lockscreen.lua b/.config/awesome/module/lockscreen.lua
new file mode 100755
index 0000000..ed46bbe
--- /dev/null
+++ b/.config/awesome/module/lockscreen.lua
@@ -0,0 +1,849 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local filesystem = gears.filesystem
+local config_dir = filesystem.get_configuration_dir()
+local dpi = beautiful.xresources.apply_dpi
+local apps = require('configuration.apps')
+local widget_icon_dir = config_dir .. 'configuration/user-profile/'
+local config = require('configuration.config')
+
+-- Add paths to package.cpath
+package.cpath = package.cpath .. ';' .. config_dir .. '/library/?.so;' .. '/usr/lib/lua-pam/?.so;'
+
+-- Configuration table
+local locker_config = {
+ -- Clock mode
+ military_clock = config.module.lockscreen.military_clock or false,
+ -- Fallback password
+ fallback_password = function()
+ return config.module.lockscreen.fallback_password or 'toor'
+ end,
+ -- Capture a picture using webcam
+ capture_intruder = config.module.lockscreen.capture_intruder or false,
+ -- Save location, auto creates
+ face_capture_dir = config.module.lockscreen.face_capture_dir or '$(xdg-user-dir PICTURES)/Intruders/',
+ -- Blur background
+ blur_background = config.module.lockscreen.blur_background or false,
+ -- Background directory
+ bg_dir = config.module.lockscreen.bg_dir or (config_dir .. 'theme/wallpapers/'),
+ -- Default background
+ bg_image = config.module.lockscreen.bg_image or 'morning-wallpaper.jpg',
+ -- /tmp directory
+ tmp_wall_dir = config.module.lockscreen.tmp_wall_dir or '/tmp/awesomewm/' .. os.getenv('USER') .. '/'
+}
+
+-- Useful variables (DO NOT TOUCH THESE)
+local input_password = nil
+local lock_again = nil
+local type_again = true
+local capture_now = locker_config.capture_intruder
+local locked_tag = nil
+
+local uname_text = wibox.widget {
+ id = 'uname_text',
+ markup = '$USER',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local caps_text = wibox.widget {
+ id = 'uname_text',
+ markup = 'Caps Lock is on',
+ font = 'Inter Italic 10',
+ align = 'center',
+ valign = 'center',
+ opacity = 0.0,
+ widget = wibox.widget.textbox
+}
+
+local profile_imagebox = wibox.widget {
+ id = 'user_icon',
+ image = widget_icon_dir .. 'default.svg',
+ resize = true,
+ forced_height = dpi(130),
+ forced_width = dpi(130),
+ clip_shape = gears.shape.circle,
+ widget = wibox.widget.imagebox
+}
+
+local clock_format = '%H:%M'
+if not locker_config.military_clock then
+ clock_format = '%I:%M %p'
+end
+
+-- Create clock widget
+local time = wibox.widget.textclock(clock_format, 1)
+
+local wanted_text = wibox.widget {
+ markup = 'INTRUDER ALERT!',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local msg_table = {
+ 'This incident will be reported.',
+ 'We are watching you.',
+ 'We know where you live.',
+ 'RUN!',
+ 'Yamete, Oniichan~ uwu',
+ 'This will self-destruct in 5 seconds!',
+ 'Image successfully sent!',
+ 'You\'re doomed!',
+ 'Authentication failed!',
+ 'I am watching you.',
+ 'I know where you live.',
+ 'RUN!',
+ 'Your parents must be proud of you.'
+}
+
+local wanted_msg = wibox.widget {
+ markup = 'This incident will be reported!',
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local wanted_image = wibox.widget {
+ image = widget_icon_dir .. 'default.svg',
+ resize = true,
+ forced_height = dpi(120),
+ clip_shape = gears.shape.rounded_rect,
+ widget = wibox.widget.imagebox
+}
+
+local date_value = function()
+ local ordinal = nil
+ local date = os.date('%d')
+ local day = os.date('%A')
+ local month = os.date('%B')
+
+ local first_digit = string.sub(date, 0, 1)
+ local last_digit = string.sub(date, -1)
+ if first_digit == '0' then
+ date = last_digit
+ end
+
+ if last_digit == '1' and date ~= '11' then
+ ordinal = 'st'
+ elseif last_digit == '2' and date ~= '12' then
+ ordinal = 'nd'
+ elseif last_digit == '3' and date ~= '13' then
+ ordinal = 'rd'
+ else
+ ordinal = 'th'
+ end
+
+ return date .. ordinal .. ' of ' .. month .. ', ' .. day
+end
+
+local date = wibox.widget {
+ markup = date_value(),
+ font = 'Inter Bold 20',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local circle_container = wibox.widget {
+ bg = beautiful.transparent,
+ forced_width = dpi(140),
+ forced_height = dpi(140),
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local locker_arc = wibox.widget {
+ bg = beautiful.transparent,
+ forced_width = dpi(140),
+ forced_height = dpi(140),
+ shape = function(cr, width, height)
+ gears.shape.arc(cr, width, height, dpi(5), 0, (math.pi / 2), false, false)
+ end,
+ widget = wibox.container.background
+}
+
+local rotate_container = wibox.container.rotate()
+local locker_widget = wibox.widget {
+ {
+ locker_arc,
+ widget = rotate_container
+ },
+ layout = wibox.layout.fixed.vertical
+}
+
+-- Rotation direction table
+local rotation_direction = {'north', 'west', 'south', 'east'}
+
+-- Red, Green, Yellow, Blue
+local red = beautiful.system_red_dark
+local green = beautiful.system_green_dark
+local yellow = beautiful.system_yellow_dark
+local blue = beautiful.system_blue_dark
+
+-- Color table
+local arc_color = {red, green, yellow, blue}
+
+-- Processes
+local locker = function(s)
+
+ local lockscreen = wibox {
+ screen = s,
+ visible = false,
+ ontop = true,
+ type = 'splash',
+ width = s.geometry.width,
+ height = s.geometry.height,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ }
+
+ -- Update username textbox
+ awful.spawn.easy_async_with_shell(
+ [[
+ sh -c '
+ fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")"
+ if [ -z "$fullname" ];
+ then
+ printf "$(whoami)@$(hostname)"
+ else
+ printf "$fullname"
+ fi
+ '
+ ]],
+ function(stdout)
+ stdout = stdout:gsub('%\n','')
+ uname_text:set_markup(stdout)
+ end
+ )
+
+ local update_profile_pic = function()
+ awful.spawn.easy_async_with_shell(
+ apps.utils.update_profile,
+ function(stdout)
+ stdout = stdout:gsub('%\n','')
+ if not stdout:match('default') then
+ profile_imagebox:set_image(stdout)
+ else
+ profile_imagebox:set_image(widget_icon_dir .. 'default.svg')
+ end
+ end
+ )
+ end
+
+ -- Update image
+ gears.timer.start_new(
+ 2,
+ function()
+ update_profile_pic()
+ end
+ )
+
+ local wanted_poster = awful.popup {
+ widget = {
+ {
+ {
+ wanted_text,
+ {
+ nil,
+ wanted_image,
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ wanted_msg,
+ spacing = dpi(5),
+ layout = wibox.layout.fixed.vertical
+ },
+ margins = dpi(20),
+ widget = wibox.container.margin
+ },
+ bg = beautiful.background,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background
+ },
+ bg = beautiful.transparent,
+ type = 'utility',
+ ontop = true,
+ shape = gears.shape.rectangle,
+ maximum_width = dpi(250),
+ maximum_height = dpi(250),
+ hide_on_right_click = false,
+ preferred_anchors = {'middle'},
+ visible = false
+ }
+
+ -- Place wanted poster at the bottom of primary screen
+ awful.placement.top(
+ wanted_poster,
+ {
+ margins = {
+ top = dpi(10)
+ }
+ }
+ )
+
+ -- Check Capslock state
+ local check_caps = function()
+ awful.spawn.easy_async_with_shell(
+ 'xset q | grep Caps | cut -d: -f3 | cut -d0 -f1 | tr -d \' \'',
+ function(stdout)
+ if stdout:match('on') then
+ caps_text.opacity = 1.0
+ else
+ caps_text.opacity = 0.0
+ end
+ caps_text:emit_signal('widget::redraw_needed')
+ end
+ )
+ end
+
+ -- Rotate the color arc on random direction
+ local locker_arc_rotate = function()
+
+ local direction = rotation_direction[math.random(#rotation_direction)]
+ local color = arc_color[math.random(#arc_color)]
+
+ rotate_container.direction = direction
+ locker_arc.bg = color
+
+ rotate_container:emit_signal('widget::redraw_needed')
+ locker_arc:emit_signal('widget::redraw_needed')
+ locker_widget:emit_signal('widget::redraw_needed')
+ end
+
+ -- Check webcam
+ local check_webcam = function()
+ awful.spawn.easy_async_with_shell(
+ 'ls -l /dev/video* | grep /dev/video0',
+ function(stdout)
+ if not locker_config.capture_intruder then
+ capture_now = false
+ return
+ end
+
+ if not stdout:match('/dev/video0') then
+ capture_now = false
+ else
+ capture_now = true
+ end
+ end
+ )
+ end
+
+ check_webcam()
+
+ -- Snap an image of the intruder
+ local intruder_capture = function()
+ local capture_image = [[
+ save_dir="]] .. locker_config.face_capture_dir .. [["
+ date="$(date +%Y%m%d_%H%M%S)"
+ file_loc="${save_dir}SUSPECT-${date}.png"
+
+ if [ ! -d "$save_dir" ]; then
+ mkdir -p "$save_dir";
+ fi
+
+ ffmpeg -f video4linux2 -s 800x600 -i /dev/video0 -ss 0:0:2 -frames 1 "${file_loc}"
+
+ canberra-gtk-play -i camera-shutter &
+ echo "${file_loc}"
+ ]]
+
+ -- Capture the filthy intruder face
+ awful.spawn.easy_async_with_shell(
+ capture_image,
+ function(stdout)
+ circle_container.bg = beautiful.transparent
+
+ -- Humiliate the intruder by showing his/her hideous face
+ wanted_image:set_image(stdout:gsub('%\n',''))
+ wanted_msg:set_markup(msg_table[math.random(#msg_table)])
+ wanted_poster.visible= true
+
+ awful.placement.top(
+ wanted_poster,
+ {
+ margins = {
+ top = dpi(10)
+ }
+ }
+ )
+
+ wanted_image:emit_signal('widget::redraw_needed')
+ type_again = true
+ end
+ )
+ end
+
+ -- Login failed
+ local stoprightthereyoucriminalscum = function()
+ circle_container.bg = red .. 'AA'
+ if capture_now then
+ intruder_capture()
+ else
+ gears.timer.start_new(
+ 1,
+ function()
+ circle_container.bg = beautiful.transparent
+ type_again = true
+ end
+ )
+ end
+ end
+
+ -- Login successful
+ local generalkenobi_ohhellothere = function()
+ circle_container.bg = green .. 'AA'
+
+ -- Add a little delay before unlocking completely
+ gears.timer.start_new(
+ 1,
+ function()
+ if capture_now then
+ -- Hide wanted poster
+ wanted_poster.visible = false
+ end
+
+ -- Hide all the lockscreen on all screen
+ for s in screen do
+ if s.index == 1 then
+ s.lockscreen.visible = false
+ else
+ s.lockscreen_extended.visible = false
+ end
+ end
+
+ circle_container.bg = beautiful.transparent
+ lock_again = true
+ type_again = true
+
+ -- Select old tag
+ -- And restore minimized focused client if there's any
+ if locked_tag then
+ locked_tag.selected = true
+ locked_tag = nil
+ end
+ local c = awful.client.restore()
+ if c then
+ c:emit_signal('request::activate')
+ c:raise()
+ end
+ end
+ )
+ end
+ -- A backdoor.
+ -- Sometimes I'm too lazy to type so I decided to create this.
+ -- Sometimes my genius is... it's almost frightening.
+ local back_door = function()
+ generalkenobi_ohhellothere()
+ end
+
+ -- Check module if valid
+ local module_check = function(name)
+ if package.loaded[name] then
+ return true
+ else
+ for _, searcher in ipairs(package.searchers or package.loaders) do
+ local loader = searcher(name)
+ if type(loader) == 'function' then
+ package.preload[name] = loader
+ return true
+ end
+ end
+ return false
+ end
+ end
+
+ -- Password/key grabber
+ local password_grabber = awful.keygrabber {
+ auto_start = true,
+ stop_event = 'release',
+ mask_event_callback = true,
+ keybindings = {
+ awful.key {
+ modifiers = {'Control'},
+ key = 'u',
+ on_press = function()
+ input_password = nil
+ end
+ },
+ awful.key {
+ modifiers = {'Mod1', 'Mod4', 'Shift', 'Control'},
+ key = 'Return',
+ on_press = function(self)
+ if not type_again then
+ return
+ end
+ self:stop()
+
+ -- Call backdoor
+ back_door()
+ end
+ }
+ },
+ keypressed_callback = function(self, mod, key, command)
+ if not type_again then
+ return
+ end
+
+ -- Clear input string
+ if key == 'Escape' then
+ -- Clear input threshold
+ input_password = nil
+ return
+ end
+
+ -- Accept only the single charactered key
+ -- Ignore 'Shift', 'Control', 'Return', 'F1', 'F2', etc., etc.
+ if #key == 1 then
+ locker_arc_rotate()
+
+ if input_password == nil then
+ input_password = key
+ return
+ end
+ input_password = input_password .. key
+ end
+
+ end,
+ keyreleased_callback = function(self, mod, key, command)
+ locker_arc.bg = beautiful.transparent
+ locker_arc:emit_signal('widget::redraw_needed')
+
+ if key == 'Caps_Lock' then
+ check_caps()
+ return
+ end
+
+ if not type_again then
+ return
+ end
+
+ -- Validation
+ if key == 'Return' then
+ -- Validate password
+ local authenticated = false
+ if input_password ~= nil then
+ -- If lua-pam library is 'okay'
+ if module_check('liblua_pam') then
+ local pam = require('liblua_pam')
+ authenticated = pam:auth_current_user(input_password)
+ else
+ -- Library doesn't exist or returns an error due to some reasons (read the manual)
+ -- Use fallback password data
+ authenticated = input_password == locker_config.fallback_password()
+
+ local rtfm = naughty.action {
+ name = 'Read Wiki',
+ icon_only = false
+ }
+
+ local dismiss = naughty.action {
+ name = 'Dismiss',
+ icon_only = false
+ }
+
+ rtfm:connect_signal(
+ 'invoked',
+ function()
+ awful.spawn(
+ [[sh -c "
+ xdg-open 'https://github.com/manilarome/the-glorious-dotfiles/wiki'
+ "]],
+ false
+ )
+ end
+ )
+
+ naughty.notification({
+ app_name = 'Security',
+ title = 'WARNING',
+ message = 'You\'re using the fallback password! It\'s recommended to use the PAM Integration!',
+ urgency = 'critical',
+ actions = { rtfm, dismiss }
+ })
+ end
+ end
+
+ if authenticated then
+ -- Come in!
+ self:stop()
+ generalkenobi_ohhellothere()
+ else
+ -- F*ck off, you [REDACTED]!
+ stoprightthereyoucriminalscum()
+ end
+
+ -- Allow typing again and empty password container
+ type_again = false
+ input_password = nil
+ end
+ end
+ }
+
+ lockscreen : setup {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ expand = 'none',
+ spacing = dpi(20),
+ {
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ time,
+ nil
+ },
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ date,
+ nil
+ },
+ expand = 'none',
+ layout = wibox.layout.fixed.vertical
+ },
+ {
+ layout = wibox.layout.fixed.vertical,
+ {
+ circle_container,
+ locker_widget,
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ profile_imagebox,
+ nil
+ },
+ nil,
+ },
+ layout = wibox.layout.stack
+ },
+ uname_text,
+ caps_text
+ },
+ },
+ nil
+ },
+ nil
+ }
+
+ local show_lockscreen = function()
+ -- Why is there a lock_again variable?
+ -- It prevents the user to spam locking while in a process of authentication
+ -- Prevents a potential bug/problem
+ if lock_again == true or lock_again == nil then
+ -- Force update clock widget
+ time:emit_signal('widget::redraw_needed')
+
+ -- Check capslock status
+ check_caps()
+
+ -- Check webcam status
+ check_webcam()
+
+ -- Show all the lockscreen on each screen
+ for s in screen do
+ if s.index == 1 then
+ s.lockscreen.visible = true
+ else
+ s.lockscreen_extended.visible = true
+ end
+ end
+
+ -- Start keygrabbing, but with a little delay to
+ -- give some extra time for the free_keygrab function
+ gears.timer.start_new(
+ 0.5,
+ function()
+ -- Start key grabbing for password
+ password_grabber:start()
+ end
+ )
+
+ -- Dont lock again
+ lock_again = false
+ end
+ end
+
+ local free_keygrab = function()
+ -- Kill rofi instance.
+ awful.spawn.with_shell('kill -9 $(pgrep rofi)')
+
+ -- Check if there's a keygrabbing instance.
+ -- If yes, stop it.
+ local keygrabbing_instance = awful.keygrabber.current_instance
+ if keygrabbing_instance then
+ keygrabbing_instance:stop()
+ end
+
+ -- Unselect all tags and minimize the focused client
+ -- These will fix the problem with virtualbox or
+ -- any other program that has keygrabbing enabled
+ if client.focus then
+ client.focus.minimized = true
+ end
+ for _, t in ipairs(mouse.screen.selected_tags) do
+ locked_tag = t
+ t.selected = false
+ end
+ end
+
+ awesome.connect_signal(
+ 'module::lockscreen_show',
+ function()
+ if lock_again == true or lock_again == nil then
+ free_keygrab()
+ show_lockscreen()
+ end
+ end
+ )
+ return lockscreen
+end
+
+-- This lockscreen is for the extra/multi monitor
+local locker_ext = function(s)
+ local extended_lockscreen = wibox {
+ screen = s,
+ visible = false,
+ ontop = true,
+ ontype = 'true',
+ x = s.geometry.x,
+ y = s.geometry.y,
+ width = s.geometry.width,
+ height = s.geometry.height,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ }
+ return extended_lockscreen
+end
+
+-- Create lockscreen for each screen
+local create_lock_screens = function(s)
+ if s.index == 1 then
+ s.lockscreen = locker(s)
+ else
+ s.lockscreen_extended = locker_ext(s)
+ end
+end
+
+-- Don't show notification popups if the screen is locked
+local check_lockscreen_visibility = function()
+ focused = awful.screen.focused()
+ if focused.lockscreen and focused.lockscreen.visible then
+ return true
+ end
+ if focused.lockscreen_extended and focused.lockscreen_extended.visible then
+ return true
+ end
+ return false
+end
+
+-- Notifications signal
+naughty.connect_signal(
+ 'request::display',
+ function(_)
+ if check_lockscreen_visibility() then
+ naughty.destroy_all_notifications(nil, 1)
+ end
+ end
+)
+
+-- Filter background image
+local filter_bg_image = function(wall_name, index, ap, width, height)
+ -- Checks if the blur has to be blurred
+ local blur_filter_param = ''
+ if locker_config.blur_background then
+ blur_filter_param = '-filter Gaussian -blur 0x10'
+ end
+
+ -- Create imagemagick command
+ local magic = [[
+ sh -c "
+ if [ ! -d ]] .. locker_config.tmp_wall_dir ..[[ ];
+ then
+ mkdir -p ]] .. locker_config.tmp_wall_dir .. [[;
+ fi
+ convert -quality 100 -brightness-contrast -20x0 ]] .. ' ' .. blur_filter_param .. ' '.. locker_config.bg_dir .. wall_name ..
+ [[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height ..
+ [[! ]] .. locker_config.tmp_wall_dir .. index .. wall_name .. [[
+ "]]
+ return magic
+end
+
+-- Apply lockscreen background image
+local apply_ls_bg_image = function(wall_name)
+ -- Iterate through all the screens and create a lockscreen for each of it
+ for s in screen do
+ local index = s.index .. '-'
+
+ -- Get screen geometry
+ local screen_width = s.geometry.width
+ local screen_height = s.geometry.height
+
+ -- Get the right resolution/aspect ratio that will be use as the background
+ local aspect_ratio = screen_width / screen_height
+ aspect_ratio = math.floor(aspect_ratio * 100) / 100
+
+ -- Create image filter command
+ local cmd = nil
+ cmd = filter_bg_image(wall_name, index, aspect_ratio, screen_width, screen_height)
+
+ -- Asign lockscreen to each screen
+ if s.index == 1 then
+ -- Primary screen
+ awful.spawn.easy_async_with_shell(
+ cmd,
+ function()
+ s.lockscreen.bgimage = locker_config.tmp_wall_dir .. index .. wall_name
+ end
+ )
+ else
+ -- Multihead screen/s
+ awful.spawn.easy_async_with_shell(
+ cmd,
+ function()
+ s.lockscreen_extended.bgimage = locker_config.tmp_wall_dir .. index .. wall_name
+ end
+ )
+ end
+ end
+end
+
+-- Create a lockscreen and its background for each screen on start-up
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ create_lock_screens(s)
+ apply_ls_bg_image(locker_config.bg_image)
+ end
+)
+
+-- Regenerate lockscreens and its background if a screen was removed to avoid errors
+screen.connect_signal(
+ 'removed',
+ function(s)
+ create_lock_screens(s)
+ apply_ls_bg_image(locker_config.bg_image)
+ end
+)
diff --git a/.config/awesome/module/menu.lua b/.config/awesome/module/menu.lua
new file mode 100644
index 0000000..7843dc2
--- /dev/null
+++ b/.config/awesome/module/menu.lua
@@ -0,0 +1,246 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local apps = require('configuration.apps')
+local menubar = require('menubar')
+local awful_menu = awful.menu
+local menu_gen = menubar.menu_gen
+local menu_utils = menubar.utils
+local icon_theme = require('menubar.icon_theme')
+local hotkeys_popup = require('awful.hotkeys_popup').widget
+
+local terminal = apps.default.terminal
+local web_browser = apps.default.web_browser
+local file_manager = apps.default.file_manager
+local text_editor = apps.default.text_editor
+local editor_cmd = terminal .. ' -e ' .. (os.getenv('EDITOR') or 'nano')
+
+--[[
+
+ Awesome-Freedesktop
+ Freedesktop.org compliant desktop entries and menu
+
+ Menu section
+
+ Licensed under GNU General Public License v2
+ * (c) 2016, Luke Bonham
+ * (c) 2014, Harvey Mittens
+
+--]]
+
+local io, pairs, string, table, os = io, pairs, string, table, os
+
+-- Expecting a wm_name of awesome omits too many applications and tools
+menu_utils.wm_name = ''
+
+-- Menu table
+local menu = {}
+
+-- Determines if a path points to a directory, by checking if it can be read
+-- (which is `nil` also for empty files) and if its size is not 0.
+-- @author blueyed
+-- @param path the path to check
+menu.is_dir = function(path)
+ local f = io.open(path)
+ return f and not f:read(0) and f:seek('end') ~= 0 and f:close()
+end
+
+-- Remove non existent paths in order to avoid issues
+local existent_paths = {}
+for k,v in pairs(menu_gen.all_menu_dirs) do
+ if menu.is_dir(v) then
+ table.insert(existent_paths, v)
+ end
+end
+menu_gen.all_menu_dirs = existent_paths
+
+-- Determines whether an table includes a certain element
+-- @param tab a given table
+-- @param val the element to search for
+-- @return true if the given string is found within the search table; otherwise, false if not
+menu.has_value = function(tab, val)
+ for index, value in pairs(tab) do
+ if val:find(value) then
+ return true
+ end
+ end
+ return false
+end
+
+-- Use MenuBar parsing utils to build a menu for Awesome
+-- @return awful.menu
+menu.build = function(args)
+ local args = args or {}
+ local icon_size = args.icon_size
+ local before = args.before or {}
+ local after = args.after or {}
+ local skip_items = args.skip_items or {}
+ local sub_menu = args.sub_menu or false
+
+ local result = {}
+ local _menu = awful_menu({ items = before })
+
+ menu_gen.generate(function(entries)
+ -- Add category icons
+ for k, v in pairs(menu_gen.all_categories) do
+ table.insert(result, { k, {}, v.icon })
+ end
+
+ -- Get items table
+ for k, v in pairs(entries) do
+ for _, cat in pairs(result) do
+ if cat[1] == v.category then
+ if not menu.has_value(skip_items, v.name) then
+ table.insert(cat[2], { v.name, v.cmdline, v.icon })
+ end
+ break
+ end
+ end
+ end
+
+ -- Cleanup things a bit
+ for i = #result, 1, -1 do
+ local v = result[i]
+ if #v[2] == 0 then
+ -- Remove unused categories
+ table.remove(result, i)
+ else
+ --Sort entries alphabetically (by name)
+ table.sort(v[2], function (a, b) return string.byte(a[1]) < string.byte(b[1]) end)
+ -- Replace category name with nice name
+ v[1] = menu_gen.all_categories[v[1]].name
+ end
+ end
+
+ -- Sort categories alphabetically also
+ table.sort(result, function(a, b) return string.byte(a[1]) < string.byte(b[1]) end)
+
+ -- Add menu item to hold the generated menu
+ if sub_menu then
+ result = {{sub_menu, result}}
+ end
+
+ -- Add items to menu
+ for _, v in pairs(result) do _menu:add(v) end
+ for _, v in pairs(after) do _menu:add(v) end
+ end)
+
+ -- Set icon size
+ if icon_size then
+ for _,v in pairs(menu_gen.all_categories) do
+ v.icon = icon_theme():find_icon_path(v.icon_name, icon_size)
+ end
+ end
+
+ -- Hold the menu in the module
+ menu.menu = _menu
+
+ return _menu
+end
+
+-- Create a launcher widget and a main menu
+awesome_menu = {
+ {
+ 'Hotkeys',
+ function()
+ hotkeys_popup.show_help(nil, awful.screen.focused())
+ end,
+ menubar.utils.lookup_icon('keyboard')
+ },
+ {
+ 'Edit config',
+ editor_cmd .. ' ' .. awesome.conffile,
+ menubar.utils.lookup_icon('accessories-text-editor')
+ },
+ {
+ 'Restart',
+ awesome.restart,
+ menubar.utils.lookup_icon('system-restart')
+ },
+ {
+ 'Quit',
+ function() awesome.quit() end,
+ menubar.utils.lookup_icon('system-log-out')
+ }
+}
+
+local default_app_menu = {
+ {
+ 'Terminal',
+ terminal,
+ menubar.utils.lookup_icon('utilities-terminal')
+ },
+ {
+ 'Web browser',
+ web_browser,
+ menubar.utils.lookup_icon('webbrowser-app')
+ },
+ {
+ 'File Manager',
+ file_manager,
+ menubar.utils.lookup_icon('system-file-manager')
+ },
+ {
+ 'Text Editor',
+ text_editor,
+ menubar.utils.lookup_icon('accessories-text-editor')
+ }
+}
+
+-- Screenshot menu
+local screenshot_menu = {
+ {
+ 'Full',
+ function()
+ gears.timer.start_new(
+ 0.1,
+ function()
+ awful.spawn.easy_async_with_shell(apps.utils.full_screenshot)
+ end
+ )
+ end,
+ menubar.utils.lookup_icon('accessories-screenshot')
+ },
+ {
+ 'Area',
+ function()
+ gears.timer.start_new(
+ 0.1,
+ function()
+ awful.spawn.easy_async_with_shell(apps.utils.area_screenshot)
+ end,
+ menubar.utils.lookup_icon('accessories-screenshot')
+ )
+ end,
+ menubar.utils.lookup_icon('accessories-screenshot')
+ }
+}
+
+local tools_menu = {
+ {
+ 'Awesome',
+ awesome_menu,
+ beautiful.awesome_icon
+ },
+ {
+ 'Take a Screenshot',
+ screenshot_menu,
+ menubar.utils.lookup_icon('accessories-screenshot')
+ },
+ {
+ 'End Session',
+ function()
+ awesome.emit_signal('module::exit_screen:show')
+ end,
+ menubar.utils.lookup_icon('system-shutdown')
+ }
+}
+
+mymainmenu = menu.build({
+ -- Not actually the size, but the quality of the icon
+ icon_size = 48,
+ before = default_app_menu,
+ after = tools_menu
+})
+
+mylauncher = awful.widget.launcher({image = beautiful.awesome_icon, menu = mymainmenu})
diff --git a/.config/awesome/module/notifications.lua b/.config/awesome/module/notifications.lua
new file mode 100644
index 0000000..a7199ce
--- /dev/null
+++ b/.config/awesome/module/notifications.lua
@@ -0,0 +1,257 @@
+local gears = require('gears')
+local wibox = require('wibox')
+local awful = require('awful')
+local ruled = require('ruled')
+local naughty = require('naughty')
+local menubar = require('menubar')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+-- Defaults
+naughty.config.defaults.ontop = true
+naughty.config.defaults.icon_size = dpi(32)
+naughty.config.defaults.timeout = 5
+naughty.config.defaults.title = 'System Notification'
+naughty.config.defaults.margin = dpi(16)
+naughty.config.defaults.border_width = 0
+naughty.config.defaults.position = 'top_right'
+naughty.config.defaults.shape = function(cr, w, h)
+ gears.shape.rounded_rect(cr, w, h, dpi(6))
+end
+
+-- Apply theme variables
+naughty.config.padding = dpi(8)
+naughty.config.spacing = dpi(8)
+naughty.config.icon_dirs = {
+ '/usr/share/icons/Tela',
+ '/usr/share/icons/Tela-blue-dark',
+ '/usr/share/icons/Papirus/',
+ '/usr/share/icons/la-capitaine-icon-theme/',
+ '/usr/share/icons/gnome/',
+ '/usr/share/icons/hicolor/',
+ '/usr/share/pixmaps/'
+}
+naughty.config.icon_formats = { 'svg', 'png', 'jpg', 'gif' }
+
+
+-- Presets / rules
+
+ruled.notification.connect_signal(
+ 'request::rules',
+ function()
+
+ -- Critical notifs
+ ruled.notification.append_rule {
+ rule = { urgency = 'critical' },
+ properties = {
+ font = 'Inter Bold 10',
+ bg = '#ff0000',
+ fg = '#ffffff',
+ margin = dpi(16),
+ position = 'top_right',
+ implicit_timeout = 0
+ }
+ }
+
+ -- Normal notifs
+ ruled.notification.append_rule {
+ rule = { urgency = 'normal' },
+ properties = {
+ font = 'Inter Regular 10',
+ bg = beautiful.transparent,
+ fg = beautiful.fg_normal,
+ margin = dpi(16),
+ position = 'top_right',
+ implicit_timeout = 5
+ }
+ }
+
+ -- Low notifs
+ ruled.notification.append_rule {
+ rule = { urgency = 'low' },
+ properties = {
+ font = 'Inter Regular 10',
+ bg = beautiful.transparent,
+ fg = beautiful.fg_normal,
+ margin = dpi(16),
+ position = 'top_right',
+ implicit_timeout = 5
+ }
+ }
+ end
+ )
+
+-- Error handling
+naughty.connect_signal(
+ 'request::display_error',
+ function(message, startup)
+ naughty.notification {
+ urgency = 'critical',
+ title = 'Oops, an error happened'..(startup and ' during startup!' or '!'),
+ message = message,
+ app_name = 'System Notification',
+ icon = beautiful.awesome_icon
+ }
+ end
+)
+
+-- XDG icon lookup
+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
+)
+
+-- Connect to naughty on display signal
+naughty.connect_signal(
+ 'request::display',
+ function(n)
+
+ -- Actions Blueprint
+ local actions_template = wibox.widget {
+ notification = n,
+ base_layout = wibox.widget {
+ spacing = dpi(0),
+ layout = wibox.layout.flex.horizontal
+ },
+ widget_template = {
+ {
+ {
+ {
+ {
+ id = 'text_role',
+ font = 'Inter Regular 10',
+ widget = wibox.widget.textbox
+ },
+ widget = wibox.container.place
+ },
+ widget = clickable_container
+ },
+ bg = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ forced_height = dpi(30),
+ widget = wibox.container.background
+ },
+ margins = dpi(4),
+ widget = wibox.container.margin
+ },
+ style = { underline_normal = false, underline_selected = true },
+ widget = naughty.list.actions
+ }
+
+ -- Notifbox Blueprint
+ naughty.layout.box {
+ notification = n,
+ type = 'notification',
+ screen = awful.screen.preferred(),
+ shape = gears.shape.rectangle,
+ widget_template = {
+ {
+ {
+ {
+ {
+ {
+ {
+ {
+ {
+ {
+ {
+ markup = n.app_name or 'System Notification',
+ font = 'Inter Bold 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+
+ },
+ margins = beautiful.notification_margin,
+ widget = wibox.container.margin,
+ },
+ bg = beautiful.background,
+ widget = wibox.container.background,
+ },
+ {
+ {
+ {
+ resize_strategy = 'center',
+ widget = naughty.widget.icon,
+ },
+ margins = beautiful.notification_margin,
+ widget = wibox.container.margin,
+ },
+ {
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ {
+ align = 'left',
+ widget = naughty.widget.title
+ },
+ {
+ align = 'left',
+ widget = naughty.widget.message,
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ nil
+ },
+ margins = beautiful.notification_margin,
+ widget = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.horizontal,
+ },
+ fill_space = true,
+ spacing = beautiful.notification_margin,
+ layout = wibox.layout.fixed.vertical,
+ },
+ -- Margin between the fake background
+ -- Set to 0 to preserve the 'titlebar' effect
+ margins = dpi(0),
+ widget = wibox.container.margin,
+ },
+ bg = beautiful.transparent,
+ widget = wibox.container.background,
+ },
+ -- Actions
+ actions_template,
+ spacing = dpi(4),
+ layout = wibox.layout.fixed.vertical,
+ },
+ bg = beautiful.transparent,
+ id = 'background_role',
+ widget = naughty.container.background,
+ },
+ strategy = 'min',
+ width = dpi(160),
+ widget = wibox.container.constraint,
+ },
+ strategy = 'max',
+ width = beautiful.notification_max_width or dpi(500),
+ widget = wibox.container.constraint
+ },
+ bg = beautiful.background,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background
+ }
+ }
+
+ -- Destroy popups if dont_disturb mode is on
+ -- Or if the right_panel is visible
+ local focused = awful.screen.focused()
+ if _G.dont_disturb or
+ (focused.right_panel and focused.right_panel.visible) then
+ naughty.destroy_all_notifications(nil, 1)
+ end
+
+ end
+)
diff --git a/.config/awesome/module/quake-terminal.lua b/.config/awesome/module/quake-terminal.lua
new file mode 100644
index 0000000..4bd2ce7
--- /dev/null
+++ b/.config/awesome/module/quake-terminal.lua
@@ -0,0 +1,112 @@
+local awful = require('awful')
+local ruled = require('ruled')
+local beautiful = require('beautiful')
+local app = require('configuration.apps').default.quake
+local client_keys = require('configuration.client.keys')
+local client_buttons = require('configuration.client.buttons')
+local quake_id = nil
+local quake_client = nil
+local quake_opened = false
+
+local quake_properties = function()
+ return {
+ skip_decoration = true,
+ titlebars_enabled = false,
+ switch_to_tags = false,
+ opacity = 0.95,
+ floating = true,
+ skip_taskbar = true,
+ ontop = true,
+ above = true,
+ sticky = true,
+ hidden = not quake_opened,
+ maximized_horizontal = true,
+ skip_center = true,
+ round_corners = false,
+ keys = client_keys,
+ buttons = client_buttons,
+ placement = awful.placement.top,
+ shape = beautiful.client_shape_rectangle
+ }
+end
+
+ruled.client.connect_signal(
+ 'request::rules',
+ function()
+ ruled.client.append_rule {
+ id = 'quake_terminal',
+ rule_any = {
+ instance = {
+ 'QuakeTerminal'
+ }
+ },
+ properties = quake_properties()
+ }
+ end
+)
+
+local create_quake = function()
+ -- Check if there's already an instance of 'QuakeTerminal'.
+ -- If yes, recover it - use it again.
+ local quake_term = function (c)
+ return ruled.client.match(c, {instance = 'QuakeTerminal'})
+ end
+ for c in awful.client.iterate(quake_term) do
+ -- 'QuakeTerminal' instance detected
+ -- Re-apply its properties
+ ruled.client.execute(c, quake_properties())
+ quake_id = c.pid
+ c:emit_signal('request::activate')
+ return
+ end
+ -- No 'QuakeTerminal' instance, spawn one
+ quake_id = awful.spawn(app, quake_properties())
+end
+
+local quake_open = function()
+ quake_client.hidden = false
+ quake_client:emit_signal('request::activate')
+end
+
+local quake_close = function()
+ quake_client.hidden = true
+end
+
+local quake_toggle = function()
+ quake_opened = not quake_opened
+ if not quake_client then
+ create_quake()
+ else
+ if quake_opened then
+ quake_open()
+ else
+ quake_close()
+ end
+ end
+end
+
+awesome.connect_signal(
+ 'module::quake_terminal:toggle',
+ function()
+ quake_toggle();
+ end
+)
+
+client.connect_signal(
+ 'manage',
+ function(c)
+ if c.pid == quake_id then
+ quake_client = c
+ end
+ end
+)
+
+client.connect_signal(
+ 'unmanage',
+ function(c)
+ if c.pid == quake_id then
+ quake_opened = false
+ quake_client = nil
+ end
+ end
+)
diff --git a/.config/awesome/module/titlebar.lua b/.config/awesome/module/titlebar.lua
new file mode 100644
index 0000000..ebf958d
--- /dev/null
+++ b/.config/awesome/module/titlebar.lua
@@ -0,0 +1,278 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local wibox = require('wibox')
+local dpi = beautiful.xresources.apply_dpi
+awful.titlebar.enable_tooltip = true
+awful.titlebar.fallback_name = 'Client'
+
+local double_click_event_handler = function(double_click_event)
+ if double_click_timer then
+ double_click_timer:stop()
+ double_click_timer = nil
+ double_click_event()
+ return
+ end
+ double_click_timer = gears.timer.start_new(
+ 0.20,
+ function()
+ double_click_timer = nil
+ return false
+ end
+ )
+end
+
+local create_click_events = function(c)
+ -- Titlebar button/click events
+ local buttons = gears.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ double_click_event_handler(function()
+ if c.floating then
+ c.floating = false
+ return
+ end
+ c.maximized = not c.maximized
+ c:raise()
+ return
+ end)
+ c:activate {context = 'titlebar', action = 'mouse_move'}
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ function()
+ c:activate {context = 'titlebar', action = 'mouse_resize'}
+ end
+ )
+ )
+ return buttons
+end
+
+local create_vertical_bar = function(c, pos, bg, size)
+
+ -- Check if passed position is valid
+ if (pos == 'top' or pos == 'bottom') then
+ pos = 'left'
+ bg = '#FF00FF'
+ end
+
+ awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup {
+ {
+ {
+ awful.titlebar.widget.closebutton(c),
+ awful.titlebar.widget.maximizedbutton(c),
+ awful.titlebar.widget.minimizebutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.vertical
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ {
+ buttons = create_click_events(c),
+ layout = wibox.layout.flex.vertical
+ },
+ {
+ {
+ awful.titlebar.widget.ontopbutton(c),
+ awful.titlebar.widget.floatingbutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.vertical
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ layout = wibox.layout.align.vertical
+ }
+end
+
+local create_horizontal_bar = function(c, pos, bg, size)
+
+ -- Check if passed position is valid
+ if (pos == 'left' or pos == 'right') then
+ pos = 'top'
+ bg = '#FF00FF'
+ end
+
+ awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup {
+ {
+ {
+ awful.titlebar.widget.closebutton(c),
+ awful.titlebar.widget.maximizedbutton(c),
+ awful.titlebar.widget.minimizebutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.horizontal
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ {
+ buttons = create_click_events(c),
+ layout = wibox.layout.flex.horizontal
+ },
+ {
+ {
+ awful.titlebar.widget.ontopbutton(c),
+ awful.titlebar.widget.floatingbutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.horizontal
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ layout = wibox.layout.align.horizontal
+ }
+end
+
+local create_vertical_bar_dialog = function(c, pos, bg, size)
+
+ -- Check if passed position is valid
+ if (pos == 'top' or pos == 'bottom') then
+ pos = 'left'
+ bg = '#FF00FF'
+ end
+
+ awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup {
+ {
+ {
+ awful.titlebar.widget.closebutton(c),
+ awful.titlebar.widget.minimizebutton(c),
+ awful.titlebar.widget.ontopbutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.vertical
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ {
+ buttons = create_click_events(c),
+ layout = wibox.layout.flex.vertical
+ },
+ nil,
+ layout = wibox.layout.align.vertical
+ }
+end
+
+local create_horizontal_bar_dialog = function(c, pos, bg, size)
+
+ -- Check if passed position is valid
+ if (pos == 'left' or pos == 'right') then
+ pos = 'top'
+ bg = '#FF00FF'
+ end
+
+ awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup {
+ {
+ {
+ awful.titlebar.widget.closebutton(c),
+ awful.titlebar.widget.ontopbutton(c),
+ awful.titlebar.widget.minimizebutton(c),
+ spacing = dpi(7),
+ layout = wibox.layout.fixed.horizontal
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ {
+ buttons = create_click_events(c),
+ layout = wibox.layout.flex.horizontal
+ },
+ nil,
+ layout = wibox.layout.align.horizontal
+ }
+end
+
+client.connect_signal(
+ 'request::titlebars',
+ function(c)
+
+ -- Customize here
+ if c.type == 'normal' then
+
+ if c.class == 'kitty' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ elseif c.class == 'firefox' then
+ create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size)
+
+ elseif c.class == 'XTerm' or c.class == 'UXTerm' then
+ create_horizontal_bar(c, 'top',
+ beautiful.xresources.get_current_theme().background, beautiful.titlebar_size)
+
+ elseif c.class == 'ark' or c.class == 'dolphin' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ elseif c.instance == 'transmission-qt' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ elseif c.class == 'Gimp-2.10' or c.class == 'Inkscape' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Com.github.johnfactotum.Foliate' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Arandr' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Ettercap' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Google-chrome' or c.class == 'Chromium' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size)
+
+ elseif c.class == 'TelegramDesktop' then
+ create_vertical_bar(c, 'left', '#17212b', beautiful.titlebar_size)
+
+ elseif c.class == 'Kvantum Manager' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ elseif c.class == 'qt5ct' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ elseif c.class == 'Nemo' then
+ create_horizontal_bar(c, 'top',
+ beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size)
+
+ else
+ create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size)
+ end
+
+ elseif c.type == 'dialog' then
+
+ if c.role == 'GtkFileChooserDialog' then
+ create_vertical_bar_dialog(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'firefox' then
+ create_vertical_bar_dialog(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Gimp-2.10' then
+ create_vertical_bar_dialog(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ elseif c.class == 'Arandr' then
+ create_vertical_bar(c, 'left',
+ beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size)
+
+ else
+ create_vertical_bar_dialog(c, 'left', '#00000099', beautiful.titlebar_size)
+ end
+
+ elseif c.type == 'modal' then
+ create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size)
+
+ else
+ create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size)
+ end
+ end
+)
diff --git a/.config/awesome/module/volume-osd.lua b/.config/awesome/module/volume-osd.lua
new file mode 100644
index 0000000..efcaf26
--- /dev/null
+++ b/.config/awesome/module/volume-osd.lua
@@ -0,0 +1,268 @@
+local awful = require('awful')
+local gears = require('gears')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+local osd_header = wibox.widget {
+ text = 'Volume',
+ font = 'Inter Bold 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local osd_value = wibox.widget {
+ text = '0%',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local slider_osd = wibox.widget {
+ nil,
+ {
+ id = 'vol_osd_slider',
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(2),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+local vol_osd_slider = slider_osd.vol_osd_slider
+
+vol_osd_slider:connect_signal(
+ 'property::value',
+ function()
+ local volume_level = vol_osd_slider:get_value()
+ awful.spawn('amixer -D pulse sset Master ' .. volume_level .. '%', false)
+
+ -- Update textbox widget text
+ osd_value.text = volume_level .. '%'
+
+ -- Update the volume slider if values here change
+ awesome.emit_signal('widget::volume:update', volume_level)
+
+ if awful.screen.focused().show_vol_osd then
+ awesome.emit_signal(
+ 'module::volume_osd:show',
+ true
+ )
+ end
+ end
+)
+
+vol_osd_slider:connect_signal(
+ 'button::press',
+ function()
+ awful.screen.focused().show_vol_osd = true
+ end
+)
+
+vol_osd_slider:connect_signal(
+ 'mouse::enter',
+ function()
+ awful.screen.focused().show_vol_osd = true
+ end
+)
+
+-- The emit will come from the volume-slider
+awesome.connect_signal(
+ 'module::volume_osd',
+ function(volume)
+ vol_osd_slider:set_value(volume)
+ end
+)
+
+local icon = wibox.widget {
+ {
+ image = icons.volume,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+}
+
+local volume_slider_osd = wibox.widget {
+ icon,
+ slider_osd,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+}
+
+local osd_height = dpi(100)
+local osd_width = dpi(300)
+local osd_margin = dpi(10)
+
+screen.connect_signal(
+ 'request::desktop_decoration',
+ function(s)
+ local s = s or {}
+ s.show_vol_osd = false
+
+ -- Create the box
+ s.volume_osd_overlay = awful.popup {
+ widget = {
+ -- Removing this block will cause an error...
+ },
+ ontop = true,
+ visible = false,
+ type = 'notification',
+ screen = s,
+ height = osd_height,
+ width = osd_width,
+ maximum_height = osd_height,
+ maximum_width = osd_width,
+ offset = dpi(5),
+ shape = gears.shape.rectangle,
+ bg = beautiful.transparent,
+ preferred_anchors = 'middle',
+ preferred_positions = {'left', 'right', 'top', 'bottom'}
+ }
+
+ s.volume_osd_overlay : setup {
+ {
+ {
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ forced_height = dpi(48),
+ osd_header,
+ nil,
+ osd_value
+ },
+ volume_slider_osd,
+ layout = wibox.layout.fixed.vertical
+ },
+ left = dpi(24),
+ right = dpi(24),
+ widget = wibox.container.margin
+ },
+ bg = beautiful.background,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background()
+ }
+
+ -- Reset timer on mouse hover
+ s.volume_osd_overlay:connect_signal(
+ 'mouse::enter',
+ function()
+ awful.screen.focused().show_vol_osd = true
+ awesome.emit_signal('module::volume_osd:rerun')
+ end
+ )
+ end
+)
+
+local hide_osd = gears.timer {
+ timeout = 2,
+ autostart = true,
+ callback = function()
+ local focused = awful.screen.focused()
+ focused.volume_osd_overlay.visible = false
+ focused.show_vol_osd = false
+ end
+}
+
+awesome.connect_signal(
+ 'module::volume_osd:rerun',
+ function()
+ if hide_osd.started then
+ hide_osd:again()
+ else
+ hide_osd:start()
+ end
+ end
+)
+
+local placement_placer = function()
+ local focused = awful.screen.focused()
+
+ local right_panel = focused.right_panel
+ local left_panel = focused.left_panel
+ local volume_osd = focused.volume_osd_overlay
+
+ if right_panel and left_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(
+ volume_osd,
+ {
+ margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin
+ },
+ honor_workarea = true
+ }
+ )
+ return
+ end
+ end
+
+ if right_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(
+ volume_osd,
+ {
+ margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin
+ },
+ honor_workarea = true
+ }
+ )
+ return
+ end
+ end
+
+ awful.placement.bottom_right(
+ volume_osd,
+ {
+ margins = {
+ left = 0,
+ right = osd_margin,
+ top = 0,
+ bottom = osd_margin,
+ },
+ honor_workarea = true
+ }
+ )
+end
+
+awesome.connect_signal(
+ 'module::volume_osd:show',
+ function(bool)
+ placement_placer()
+ awful.screen.focused().volume_osd_overlay.visible = bool
+ if bool then
+ awesome.emit_signal('module::volume_osd:rerun')
+ awesome.emit_signal(
+ 'module::brightness_osd:show',
+ false
+ )
+ else
+ if hide_osd.started then
+ hide_osd:stop()
+ end
+ end
+ end
+)
diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua
new file mode 100644
index 0000000..8c0ed00
--- /dev/null
+++ b/.config/awesome/rc.lua
@@ -0,0 +1,81 @@
+-- ░█▀▀░█░░░█▀█░█▀█░█▀█░█░█
+-- ░█▀▀░█░░░█░█░█▀▀░█▀▀░░█░
+-- ░▀░░░▀▀▀░▀▀▀░▀░░░▀░░░░▀░
+-- Banner generated using `toilet -f pagga AwesomeWM"
+
+local gears = require('gears')
+local beautiful = require('beautiful')
+local awful = require('awful')
+require('awful.autofocus')
+
+-- ░█▀▀░█░█░█▀▀░█░░░█░░
+-- ░▀▀█░█▀█░█▀▀░█░░░█░░
+-- ░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀
+
+awful.util.shell = 'sh'
+
+-- ░▀█▀░█░█░█▀▀░█▄█░█▀▀
+-- ░░█░░█▀█░█▀▀░█░█░█▀▀
+-- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀
+
+beautiful.init(require('theme'))
+
+-- ░█░░░█▀█░█░█░█▀█░█░█░▀█▀
+-- ░█░░░█▀█░░█░░█░█░█░█░░█░
+-- ░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░
+
+require('layout')
+
+-- ░█▀▀░█▀█░█▀█░█▀▀░▀█▀░█▀▀░█░█░█▀▄░█▀█░▀█▀░▀█▀░█▀█░█▀█░█▀▀
+-- ░█░░░█░█░█░█░█▀▀░░█░░█░█░█░█░█▀▄░█▀█░░█░░░█░░█░█░█░█░▀▀█
+-- ░▀▀▀░▀▀▀░▀░▀░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀
+
+require('configuration.client')
+require('configuration.root')
+require('configuration.tags')
+root.keys(require('configuration.keys.global'))
+
+-- ░█▄█░█▀█░█▀▄░█░█░█░░░█▀▀░█▀▀
+-- ░█░█░█░█░█░█░█░█░█░░░█▀▀░▀▀█
+-- ░▀░▀░▀▀▀░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀
+
+require('module.notifications')
+require('module.auto-start')
+require('module.exit-screen')
+require('module.quake-terminal')
+require('module.menu')
+require('module.titlebar')
+require('module.brightness-osd')
+require('module.volume-osd')
+require('module.lockscreen')
+--require('module.dynamic-wallpaper')
+
+-- ░█░█░█▀█░█░░░█░░░█▀█░█▀█░█▀█░█▀▀░█▀▄
+-- ░█▄█░█▀█░█░░░█░░░█▀▀░█▀█░█▀▀░█▀▀░█▀▄
+-- ░▀░▀░▀░▀░▀▀▀░▀▀▀░▀░░░▀░▀░▀░░░▀▀▀░▀░▀
+
+-- screen.connect_signal(
+-- 'request::wallpaper',
+-- function(s)
+-- -- If wallpaper is a function, call it with the screen
+-- if beautiful.wallpaper then
+-- if type(beautiful.wallpaper) == 'string' then
+
+-- -- Check if beautiful.wallpaper is color/image
+-- if beautiful.wallpaper:sub(1, #'#') == '#' then
+-- -- If beautiful.wallpaper is color
+-- gears.wallpaper.set(beautiful.wallpaper)
+
+-- elseif beautiful.wallpaper:sub(1, #'/') == '/' then
+-- -- If beautiful.wallpaper is path/image
+-- gears.wallpaper.maximized(beautiful.wallpaper, s)
+-- end
+-- else
+-- beautiful.wallpaper(s)
+-- end
+-- end
+-- end
+-- )
+--
+-- #autostart apps
+awful.spawn.with_shell('changebg')
diff --git a/.config/awesome/rc.lua.bak b/.config/awesome/rc.lua.bak
new file mode 100644
index 0000000..eb9d6eb
--- /dev/null
+++ b/.config/awesome/rc.lua.bak
@@ -0,0 +1,78 @@
+-- ░█▀▀░█░░░█▀█░█▀█░█▀█░█░█
+-- ░█▀▀░█░░░█░█░█▀▀░█▀▀░░█░
+-- ░▀░░░▀▀▀░▀▀▀░▀░░░▀░░░░▀░
+-- Banner generated using `toilet -f pagga AwesomeWM"
+
+local gears = require('gears')
+local beautiful = require('beautiful')
+local awful = require('awful')
+require('awful.autofocus')
+
+-- ░█▀▀░█░█░█▀▀░█░░░█░░
+-- ░▀▀█░█▀█░█▀▀░█░░░█░░
+-- ░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀
+
+awful.util.shell = 'sh'
+
+-- ░▀█▀░█░█░█▀▀░█▄█░█▀▀
+-- ░░█░░█▀█░█▀▀░█░█░█▀▀
+-- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀
+
+beautiful.init(require('theme'))
+
+-- ░█░░░█▀█░█░█░█▀█░█░█░▀█▀
+-- ░█░░░█▀█░░█░░█░█░█░█░░█░
+-- ░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░
+
+require('layout')
+
+-- ░█▀▀░█▀█░█▀█░█▀▀░▀█▀░█▀▀░█░█░█▀▄░█▀█░▀█▀░▀█▀░█▀█░█▀█░█▀▀
+-- ░█░░░█░█░█░█░█▀▀░░█░░█░█░█░█░█▀▄░█▀█░░█░░░█░░█░█░█░█░▀▀█
+-- ░▀▀▀░▀▀▀░▀░▀░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀
+
+require('configuration.client')
+require('configuration.root')
+require('configuration.tags')
+root.keys(require('configuration.keys.global'))
+
+-- ░█▄█░█▀█░█▀▄░█░█░█░░░█▀▀░█▀▀
+-- ░█░█░█░█░█░█░█░█░█░░░█▀▀░▀▀█
+-- ░▀░▀░▀▀▀░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀
+
+require('module.notifications')
+require('module.auto-start')
+require('module.exit-screen')
+require('module.quake-terminal')
+require('module.menu')
+require('module.titlebar')
+require('module.brightness-osd')
+require('module.volume-osd')
+require('module.lockscreen')
+--require('module.dynamic-wallpaper')
+
+-- ░█░█░█▀█░█░░░█░░░█▀█░█▀█░█▀█░█▀▀░█▀▄
+-- ░█▄█░█▀█░█░░░█░░░█▀▀░█▀█░█▀▀░█▀▀░█▀▄
+-- ░▀░▀░▀░▀░▀▀▀░▀▀▀░▀░░░▀░▀░▀░░░▀▀▀░▀░▀
+
+screen.connect_signal(
+ 'request::wallpaper',
+ function(s)
+ -- If wallpaper is a function, call it with the screen
+ if beautiful.wallpaper then
+ if type(beautiful.wallpaper) == 'string' then
+
+ -- Check if beautiful.wallpaper is color/image
+ if beautiful.wallpaper:sub(1, #'#') == '#' then
+ -- If beautiful.wallpaper is color
+ gears.wallpaper.set(beautiful.wallpaper)
+
+ elseif beautiful.wallpaper:sub(1, #'/') == '/' then
+ -- If beautiful.wallpaper is path/image
+ gears.wallpaper.maximized(beautiful.wallpaper, s)
+ end
+ else
+ beautiful.wallpaper(s)
+ end
+ end
+ end
+)
diff --git a/.config/awesome/theme/default-theme.lua b/.config/awesome/theme/default-theme.lua
new file mode 100644
index 0000000..35b34e7
--- /dev/null
+++ b/.config/awesome/theme/default-theme.lua
@@ -0,0 +1,219 @@
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local filesystem = gears.filesystem
+local dpi = beautiful.xresources.apply_dpi
+local gtk_variable = beautiful.gtk.get_theme_variables
+
+local theme_dir = filesystem.get_configuration_dir() .. '/theme'
+local titlebar_theme = 'stoplight'
+local titlebar_icon_path = theme_dir .. '/icons/titlebar/' .. titlebar_theme .. '/'
+local tip = titlebar_icon_path
+
+-- Create theme table
+local theme = {}
+
+-- Font
+theme.font = 'Inter Regular 10'
+theme.font_bold = 'Inter Bold 10'
+
+-- Menu icon theme
+theme.icon_theme = 'Tela-blue-dark'
+
+local awesome_overrides = function(theme)
+
+ theme.dir = theme_dir
+ theme.icons = theme_dir .. '/icons/'
+
+ -- Default wallpaper path
+ theme.wallpaper = theme.dir .. '/wallpapers/morning-wallpaper.jpg'
+
+ -- Default font
+ theme.font = 'Inter Regular 10'
+
+ -- Foreground
+ theme.fg_normal = '#ffffffde'
+ theme.fg_focus = '#e4e4e4'
+ theme.fg_urgent = '#CC9393'
+
+ theme.bg_normal = theme.background
+ theme.bg_focus = '#5a5a5a'
+ theme.bg_urgent = '#3F3F3F'
+
+ -- System tray
+ theme.bg_systray = theme.background
+ theme.systray_icon_spacing = dpi(16)
+
+ -- Titlebar
+ theme.titlebar_size = dpi(34)
+ theme.titlebar_bg_focus = gtk_variable().bg_color:sub(1,7) .. '66'
+ theme.titlebar_bg_normal = gtk_variable().base_color:sub(1,7) .. '66'
+ theme.titlebar_fg_focus = gtk_variable().fg_color
+ theme.titlebar_fg_normal = gtk_variable().fg_color
+
+ -- Close Button
+ theme.titlebar_close_button_normal = tip .. 'close_normal.svg'
+ theme.titlebar_close_button_focus = tip .. 'close_focus.svg'
+
+ -- Minimize Button
+ theme.titlebar_minimize_button_normal = tip .. 'minimize_normal.svg'
+ theme.titlebar_minimize_button_focus = tip .. 'minimize_focus.svg'
+
+ -- Ontop Button
+ theme.titlebar_ontop_button_normal_inactive = tip .. 'ontop_normal_inactive.svg'
+ theme.titlebar_ontop_button_focus_inactive = tip .. 'ontop_focus_inactive.svg'
+ theme.titlebar_ontop_button_normal_active = tip .. 'ontop_normal_active.svg'
+ theme.titlebar_ontop_button_focus_active = tip .. 'ontop_focus_active.svg'
+
+ -- Sticky Button
+ theme.titlebar_sticky_button_normal_inactive = tip .. 'sticky_normal_inactive.svg'
+ theme.titlebar_sticky_button_focus_inactive = tip .. 'sticky_focus_inactive.svg'
+ theme.titlebar_sticky_button_normal_active = tip .. 'sticky_normal_active.svg'
+ theme.titlebar_sticky_button_focus_active = tip .. 'sticky_focus_active.svg'
+
+ -- Floating Button
+ theme.titlebar_floating_button_normal_inactive = tip .. 'floating_normal_inactive.svg'
+ theme.titlebar_floating_button_focus_inactive = tip .. 'floating_focus_inactive.svg'
+ theme.titlebar_floating_button_normal_active = tip .. 'floating_normal_active.svg'
+ theme.titlebar_floating_button_focus_active = tip .. 'floating_focus_active.svg'
+
+ -- Maximized Button
+ theme.titlebar_maximized_button_normal_inactive = tip .. 'maximized_normal_inactive.svg'
+ theme.titlebar_maximized_button_focus_inactive = tip .. 'maximized_focus_inactive.svg'
+ theme.titlebar_maximized_button_normal_active = tip .. 'maximized_normal_active.svg'
+ theme.titlebar_maximized_button_focus_active = tip .. 'maximized_focus_active.svg'
+
+ -- Hovered Close Button
+ theme.titlebar_close_button_normal_hover = tip .. 'close_normal_hover.svg'
+ theme.titlebar_close_button_focus_hover = tip .. 'close_focus_hover.svg'
+
+ -- Hovered Minimize Buttin
+ theme.titlebar_minimize_button_normal_hover = tip .. 'minimize_normal_hover.svg'
+ theme.titlebar_minimize_button_focus_hover = tip .. 'minimize_focus_hover.svg'
+
+ -- Hovered Ontop Button
+ theme.titlebar_ontop_button_normal_inactive_hover = tip .. 'ontop_normal_inactive_hover.svg'
+ theme.titlebar_ontop_button_focus_inactive_hover = tip .. 'ontop_focus_inactive_hover.svg'
+ theme.titlebar_ontop_button_normal_active_hover = tip .. 'ontop_normal_active_hover.svg'
+ theme.titlebar_ontop_button_focus_active_hover = tip .. 'ontop_focus_active_hover.svg'
+
+ -- Hovered Sticky Button
+ theme.titlebar_sticky_button_normal_inactive_hover = tip .. 'sticky_normal_inactive_hover.svg'
+ theme.titlebar_sticky_button_focus_inactive_hover = tip .. 'sticky_focus_inactive_hover.svg'
+ theme.titlebar_sticky_button_normal_active_hover = tip .. 'sticky_normal_active_hover.svg'
+ theme.titlebar_sticky_button_focus_active_hover = tip .. 'sticky_focus_active_hover.svg'
+
+ -- Hovered Floating Button
+ theme.titlebar_floating_button_normal_inactive_hover = tip .. 'floating_normal_inactive_hover.svg'
+ theme.titlebar_floating_button_focus_inactive_hover = tip .. 'floating_focus_inactive_hover.svg'
+ theme.titlebar_floating_button_normal_active_hover = tip .. 'floating_normal_active_hover.svg'
+ theme.titlebar_floating_button_focus_active_hover = tip .. 'floating_focus_active_hover.svg'
+
+ -- Hovered Maximized Button
+ theme.titlebar_maximized_button_normal_inactive_hover = tip .. 'maximized_normal_inactive_hover.svg'
+ theme.titlebar_maximized_button_focus_inactive_hover = tip .. 'maximized_focus_inactive_hover.svg'
+ theme.titlebar_maximized_button_normal_active_hover = tip .. 'maximized_normal_active_hover.svg'
+ theme.titlebar_maximized_button_focus_active_hover = tip .. 'maximized_focus_active_hover.svg'
+
+ -- UI Groups
+ theme.groups_title_bg = '#ffffff' .. '15'
+ theme.groups_bg = '#ffffff' .. '10'
+ theme.groups_radius = dpi(9)
+
+ -- UI events
+ theme.leave_event = transparent
+ theme.enter_event = '#ffffff' .. '10'
+ theme.press_event = '#ffffff' .. '15'
+ theme.release_event = '#ffffff' .. '10'
+
+ -- Client Decorations
+
+ -- Borders
+ theme.border_focus = gtk_variable().bg_color
+ theme.border_normal = gtk_variable().base_color
+ theme.border_marked = '#CC9393'
+ theme.border_width = dpi(0)
+ theme.border_radius = dpi(9)
+
+ -- Decorations
+ theme.useless_gap = dpi(4)
+ theme.client_shape_rectangle = gears.shape.rectangle
+ theme.client_shape_rounded = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, dpi(6))
+ end
+
+ -- Menu
+ theme.menu_font = 'Inter Regular 11'
+ theme.menu_submenu = '' -- ➤
+
+ theme.menu_height = dpi(34)
+ theme.menu_width = dpi(200)
+ theme.menu_border_width = dpi(20)
+ theme.menu_bg_focus = theme.accent .. 'CC'
+
+ theme.menu_bg_normal = theme.background:sub(1,7) .. '33'
+ theme.menu_fg_normal = '#ffffff'
+ theme.menu_fg_focus = '#ffffff'
+ theme.menu_border_color = theme.background:sub(1,7) .. '5C'
+
+ -- Tooltips
+
+ theme.tooltip_bg = theme.background
+ theme.tooltip_border_color = theme.transparent
+ theme.tooltip_border_width = 0
+ theme.tooltip_gaps = dpi(5)
+ theme.tooltip_shape = function(cr, w, h)
+ gears.shape.rounded_rect(cr, w, h, dpi(6))
+ end
+
+ -- Separators
+ theme.separator_color = '#f2f2f244'
+
+ -- Layoutbox icons
+ theme.layout_max = theme.icons .. 'layouts/max.svg'
+ theme.layout_tile = theme.icons .. 'layouts/tile.svg'
+ theme.layout_dwindle = theme.icons .. 'layouts/dwindle.svg'
+ theme.layout_floating = theme.icons .. 'layouts/floating.svg'
+
+ -- Taglist
+ theme.taglist_bg_empty = theme.background .. '99'
+ theme.taglist_bg_occupied = '#ffffff' .. '1A'
+ theme.taglist_bg_urgent = '#E91E63' .. '99'
+ theme.taglist_bg_focus = theme.background
+ theme.taglist_spacing = dpi(0)
+
+ -- Tasklist
+ theme.tasklist_font = 'Inter Regular 10'
+ theme.tasklist_bg_normal = theme.background .. '99'
+ theme.tasklist_bg_focus = theme.background
+ theme.tasklist_bg_urgent = '#E91E63' .. '99'
+ theme.tasklist_fg_focus = '#DDDDDD'
+ theme.tasklist_fg_urgent = '#ffffff'
+ theme.tasklist_fg_normal = '#AAAAAA'
+
+ -- Notification
+ theme.notification_position = 'top_right'
+ theme.notification_bg = theme.transparent
+ theme.notification_margin = dpi(5)
+ theme.notification_border_width = dpi(0)
+ theme.notification_border_color = theme.transparent
+ theme.notification_spacing = dpi(5)
+ theme.notification_icon_resize_strategy = 'center'
+ theme.notification_icon_size = dpi(32)
+
+ -- Client Snap Theme
+ theme.snap_bg = theme.background
+ theme.snap_shape = gears.shape.rectangle
+ theme.snap_border_width = dpi(15)
+
+ -- Hotkey popup
+ theme.hotkeys_font = 'Inter Bold'
+ theme.hotkeys_description_font = 'Inter Regular Regular'
+ theme.hotkeys_bg = theme.background
+ theme.hotkeys_group_margin = dpi(20)
+end
+
+return {
+ theme = theme,
+ awesome_overrides = awesome_overrides
+}
diff --git a/.config/awesome/theme/floppy-theme/init.lua b/.config/awesome/theme/floppy-theme/init.lua
new file mode 100644
index 0000000..7124c97
--- /dev/null
+++ b/.config/awesome/theme/floppy-theme/init.lua
@@ -0,0 +1,52 @@
+local filesystem = require('gears.filesystem')
+local theme_dir = filesystem.get_configuration_dir() .. '/theme'
+
+local theme = {}
+
+theme.icons = theme_dir .. '/icons/'
+theme.font = 'Inter Regular 10'
+theme.font_bold = 'Inter Bold 10'
+
+-- Colorscheme
+theme.system_black_dark = '#3D4C5F'
+theme.system_black_light = '#56687E'
+
+theme.system_red_dark = '#EE4F84'
+theme.system_red_light = '#F48FB1'
+
+theme.system_green_dark = '#53E2AE'
+theme.system_green_light = '#A1EFD3'
+
+theme.system_yellow_dark = '#F1FF52'
+theme.system_yellow_light = '#F1FA8C'
+
+theme.system_blue_dark = '#6498EF'
+theme.system_blue_light = '#92B6F4'
+
+theme.system_magenta_dark = '#985EFF'
+theme.system_magenta_light = '#BD99FF'
+
+theme.system_cyan_dark = '#24D1E7'
+theme.system_cyan_light = '#87DFEB'
+
+theme.system_white_dark = '#E5E5E5'
+theme.system_white_light = '#F8F8F2'
+
+-- Accent color
+theme.accent = theme.system_blue_dark
+
+-- Background color
+theme.background = '#000000' .. '66'
+
+-- Transparent
+theme.transparent = '#00000000'
+
+-- Awesome icon
+theme.awesome_icon = theme.icons .. 'awesome.svg'
+
+local awesome_overrides = function(theme) end
+
+return {
+ theme = theme,
+ awesome_overrides = awesome_overrides
+}
diff --git a/.config/awesome/theme/icons/awesome.svg b/.config/awesome/theme/icons/awesome.svg
new file mode 100644
index 0000000..31d715c
--- /dev/null
+++ b/.config/awesome/theme/icons/awesome.svg
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/battery-charge.svg b/.config/awesome/theme/icons/battery-charge.svg
new file mode 100644
index 0000000..f8efe9c
--- /dev/null
+++ b/.config/awesome/theme/icons/battery-charge.svg
@@ -0,0 +1,58 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/theme/icons/battery-discharge.svg b/.config/awesome/theme/icons/battery-discharge.svg
new file mode 100644
index 0000000..908ce15
--- /dev/null
+++ b/.config/awesome/theme/icons/battery-discharge.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/brightness-7.svg b/.config/awesome/theme/icons/brightness-7.svg
new file mode 100644
index 0000000..862549e
--- /dev/null
+++ b/.config/awesome/theme/icons/brightness-7.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/chart-areaspline.svg b/.config/awesome/theme/icons/chart-areaspline.svg
new file mode 100644
index 0000000..58bf0d3
--- /dev/null
+++ b/.config/awesome/theme/icons/chart-areaspline.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/close.svg b/.config/awesome/theme/icons/close.svg
new file mode 100644
index 0000000..bd89d79
--- /dev/null
+++ b/.config/awesome/theme/icons/close.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/effects.svg b/.config/awesome/theme/icons/effects.svg
new file mode 100644
index 0000000..e6c514b
--- /dev/null
+++ b/.config/awesome/theme/icons/effects.svg
@@ -0,0 +1,91 @@
+
+
diff --git a/.config/awesome/theme/icons/harddisk.svg b/.config/awesome/theme/icons/harddisk.svg
new file mode 100644
index 0000000..4c23f54
--- /dev/null
+++ b/.config/awesome/theme/icons/harddisk.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/init.lua b/.config/awesome/theme/icons/init.lua
new file mode 100644
index 0000000..5cf636b
--- /dev/null
+++ b/.config/awesome/theme/icons/init.lua
@@ -0,0 +1,42 @@
+-- Icons directory
+local dir = os.getenv('HOME') .. '/.config/awesome/theme/icons/'
+
+
+return {
+
+ -- Action Bar
+ web_browser = dir .. 'tag-list/' .. 'web-browser.svg',
+ text_editor = dir .. 'tag-list/' .. 'text-editor.svg',
+ social = dir .. 'tag-list/' .. 'social.svg',
+ file_manager = dir .. 'tag-list/' .. 'file-manager.svg',
+ multimedia = dir .. 'tag-list/' .. 'multimedia.svg',
+ games = dir .. 'tag-list/' .. 'games.svg',
+ development = dir .. 'tag-list/' .. 'development.svg',
+ sandbox = dir .. 'tag-list/' .. 'sandbox.svg',
+ terminal = dir .. 'tag-list/' .. 'terminal.svg',
+ graphics = dir .. 'tag-list/' .. 'graphics.svg',
+ menu = dir .. 'tag-list/' .. 'menu.svg',
+ close_small = dir .. 'tag-list/' .. 'close-small.svg',
+
+ -- Others/System UI
+ close = dir .. 'close.svg',
+ logout = dir .. 'logout.svg',
+ sleep = dir .. 'power-sleep.svg',
+ power = dir .. 'power.svg',
+ lock = dir .. 'lock.svg',
+ restart = dir .. 'restart.svg',
+ search = dir .. 'magnify.svg',
+ volume = dir .. 'volume-high.svg',
+ brightness = dir .. 'brightness-7.svg',
+ effects = dir .. 'effects.svg',
+ chart = dir .. 'chart-areaspline.svg',
+ memory = dir .. 'memory.svg',
+ harddisk = dir .. 'harddisk.svg',
+ thermometer = dir .. 'thermometer.svg',
+ plus = dir .. 'plus.svg',
+ batt_charging = dir .. 'battery-charge.svg',
+ batt_discharging = dir .. 'battery-discharge.svg',
+ toggled_on = dir .. 'toggled-on.svg',
+ toggled_off = dir .. 'toggled-off.svg'
+
+}
diff --git a/.config/awesome/theme/icons/layouts/dwindle.svg b/.config/awesome/theme/icons/layouts/dwindle.svg
new file mode 100644
index 0000000..9e59058
--- /dev/null
+++ b/.config/awesome/theme/icons/layouts/dwindle.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/layouts/floating.svg b/.config/awesome/theme/icons/layouts/floating.svg
new file mode 100644
index 0000000..5dcd846
--- /dev/null
+++ b/.config/awesome/theme/icons/layouts/floating.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/layouts/fullscreen.svg b/.config/awesome/theme/icons/layouts/fullscreen.svg
new file mode 100644
index 0000000..6ba320b
--- /dev/null
+++ b/.config/awesome/theme/icons/layouts/fullscreen.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/theme/icons/layouts/max.svg b/.config/awesome/theme/icons/layouts/max.svg
new file mode 100644
index 0000000..f1b2b2d
--- /dev/null
+++ b/.config/awesome/theme/icons/layouts/max.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/theme/icons/layouts/tile.svg b/.config/awesome/theme/icons/layouts/tile.svg
new file mode 100644
index 0000000..ea62c5d
--- /dev/null
+++ b/.config/awesome/theme/icons/layouts/tile.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/lock.svg b/.config/awesome/theme/icons/lock.svg
new file mode 100644
index 0000000..ac383ed
--- /dev/null
+++ b/.config/awesome/theme/icons/lock.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/logout.svg b/.config/awesome/theme/icons/logout.svg
new file mode 100644
index 0000000..4689c49
--- /dev/null
+++ b/.config/awesome/theme/icons/logout.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/magnify.svg b/.config/awesome/theme/icons/magnify.svg
new file mode 100644
index 0000000..40d9c1a
--- /dev/null
+++ b/.config/awesome/theme/icons/magnify.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/memory.svg b/.config/awesome/theme/icons/memory.svg
new file mode 100644
index 0000000..0cf4b10
--- /dev/null
+++ b/.config/awesome/theme/icons/memory.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/plus.svg b/.config/awesome/theme/icons/plus.svg
new file mode 100644
index 0000000..737cad4
--- /dev/null
+++ b/.config/awesome/theme/icons/plus.svg
@@ -0,0 +1,58 @@
+
+
diff --git a/.config/awesome/theme/icons/power-sleep.svg b/.config/awesome/theme/icons/power-sleep.svg
new file mode 100644
index 0000000..a4dbfc0
--- /dev/null
+++ b/.config/awesome/theme/icons/power-sleep.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/power.svg b/.config/awesome/theme/icons/power.svg
new file mode 100644
index 0000000..770943b
--- /dev/null
+++ b/.config/awesome/theme/icons/power.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/restart.svg b/.config/awesome/theme/icons/restart.svg
new file mode 100644
index 0000000..f0c3367
--- /dev/null
+++ b/.config/awesome/theme/icons/restart.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/ship-wheel.svg b/.config/awesome/theme/icons/ship-wheel.svg
new file mode 100644
index 0000000..5237ed3
--- /dev/null
+++ b/.config/awesome/theme/icons/ship-wheel.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/close-small.svg b/.config/awesome/theme/icons/tag-list/close-small.svg
new file mode 100644
index 0000000..f244bae
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/close-small.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/development.svg b/.config/awesome/theme/icons/tag-list/development.svg
new file mode 100644
index 0000000..773a538
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/development.svg
@@ -0,0 +1,174 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/file-manager.svg b/.config/awesome/theme/icons/tag-list/file-manager.svg
new file mode 100644
index 0000000..ba04747
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/file-manager.svg
@@ -0,0 +1,138 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/games.svg b/.config/awesome/theme/icons/tag-list/games.svg
new file mode 100644
index 0000000..6314387
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/games.svg
@@ -0,0 +1,103 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/graphics.svg b/.config/awesome/theme/icons/tag-list/graphics.svg
new file mode 100644
index 0000000..caefefb
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/graphics.svg
@@ -0,0 +1,150 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/menu.svg b/.config/awesome/theme/icons/tag-list/menu.svg
new file mode 100644
index 0000000..c95ecd7
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/menu.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/menu2.svg b/.config/awesome/theme/icons/tag-list/menu2.svg
new file mode 100644
index 0000000..3e82e3d
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/menu2.svg
@@ -0,0 +1,123 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/multimedia.svg b/.config/awesome/theme/icons/tag-list/multimedia.svg
new file mode 100644
index 0000000..ff5f5b0
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/multimedia.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/sandbox.svg b/.config/awesome/theme/icons/tag-list/sandbox.svg
new file mode 100644
index 0000000..67c1921
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/sandbox.svg
@@ -0,0 +1,80 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/social.svg b/.config/awesome/theme/icons/tag-list/social.svg
new file mode 100644
index 0000000..7217709
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/social.svg
@@ -0,0 +1,92 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/terminal.svg b/.config/awesome/theme/icons/tag-list/terminal.svg
new file mode 100644
index 0000000..3c4fc1f
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/terminal.svg
@@ -0,0 +1,101 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/text-editor.svg b/.config/awesome/theme/icons/tag-list/text-editor.svg
new file mode 100644
index 0000000..4aa63b8
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/text-editor.svg
@@ -0,0 +1,76 @@
+
+
diff --git a/.config/awesome/theme/icons/tag-list/web-browser.svg b/.config/awesome/theme/icons/tag-list/web-browser.svg
new file mode 100644
index 0000000..4b97514
--- /dev/null
+++ b/.config/awesome/theme/icons/tag-list/web-browser.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/.config/awesome/theme/icons/thermometer.svg b/.config/awesome/theme/icons/thermometer.svg
new file mode 100644
index 0000000..5c25a1e
--- /dev/null
+++ b/.config/awesome/theme/icons/thermometer.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg b/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg
new file mode 100644
index 0000000..a245e7d
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg
new file mode 100644
index 0000000..fa1eddd
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg b/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg
new file mode 100644
index 0000000..fa1eddd
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg
new file mode 100644
index 0000000..262337e
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg
new file mode 100644
index 0000000..944a695
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg
new file mode 100644
index 0000000..262337e
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..944a695
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg
new file mode 100644
index 0000000..944a695
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..944a695
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg
new file mode 100644
index 0000000..8d22f56
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..fbfb447
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg
new file mode 100644
index 0000000..8d22f56
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..fbfb447
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..fbfb447
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..fbfb447
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg
new file mode 100644
index 0000000..0e5bebc
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg
new file mode 100644
index 0000000..1414c2b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg
new file mode 100644
index 0000000..1414c2b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg
new file mode 100644
index 0000000..7493249
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg
new file mode 100644
index 0000000..94e2ac7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg
new file mode 100644
index 0000000..7493249
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg
new file mode 100644
index 0000000..94e2ac7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg
new file mode 100644
index 0000000..94e2ac7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg
new file mode 100644
index 0000000..94e2ac7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg
new file mode 100644
index 0000000..321d316
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg
new file mode 100644
index 0000000..ad33389
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg
new file mode 100644
index 0000000..321d316
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg
new file mode 100644
index 0000000..ad33389
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg
new file mode 100644
index 0000000..ad33389
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg
new file mode 100644
index 0000000..c2337bb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg
new file mode 100644
index 0000000..ad33389
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/close_focus.svg b/.config/awesome/theme/icons/titlebar/lines/close_focus.svg
new file mode 100644
index 0000000..85b31ec
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/close_focus.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg
new file mode 100644
index 0000000..40aa9e1
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/close_normal.svg b/.config/awesome/theme/icons/titlebar/lines/close_normal.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/close_normal.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg
new file mode 100644
index 0000000..40aa9e1
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg
new file mode 100644
index 0000000..11b9bac
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg
new file mode 100644
index 0000000..325c24a
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg
new file mode 100644
index 0000000..11b9bac
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..779539e
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg
new file mode 100644
index 0000000..7286450
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..1441ea4
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg
new file mode 100644
index 0000000..6891963
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..77f0650
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg
new file mode 100644
index 0000000..6891963
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..77f0650
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..77f0650
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..77f0650
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg
new file mode 100644
index 0000000..abe6ebb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg
new file mode 100644
index 0000000..49619d8
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg
new file mode 100644
index 0000000..49619d8
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg
new file mode 100644
index 0000000..ed4ecfd
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg
new file mode 100644
index 0000000..81e15d9
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg
new file mode 100644
index 0000000..ed4ecfd
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg
new file mode 100644
index 0000000..81e15d9
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg
new file mode 100644
index 0000000..81e15d9
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg
new file mode 100644
index 0000000..81e15d9
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg
new file mode 100644
index 0000000..2945c0f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg
new file mode 100644
index 0000000..2cef61b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg
new file mode 100644
index 0000000..2945c0f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg
new file mode 100644
index 0000000..2cef61b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg
new file mode 100644
index 0000000..2cef61b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg
new file mode 100644
index 0000000..972d88f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg
new file mode 100644
index 0000000..2cef61b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg
new file mode 100644
index 0000000..8b63331
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg
new file mode 100644
index 0000000..2d77a2f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg
new file mode 100644
index 0000000..2d77a2f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg
new file mode 100644
index 0000000..ae9727f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg
new file mode 100644
index 0000000..ae9727f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg
new file mode 100644
index 0000000..e522d74
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg
new file mode 100644
index 0000000..e522d74
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg
new file mode 100644
index 0000000..215d91c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg
new file mode 100644
index 0000000..282d8b0
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg
new file mode 100644
index 0000000..282d8b0
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg
new file mode 100644
index 0000000..432f74f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg
new file mode 100644
index 0000000..432f74f
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg
new file mode 100644
index 0000000..47248cb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg
new file mode 100644
index 0000000..47248cb
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/close_focus.svg b/.config/awesome/theme/icons/titlebar/win10/close_focus.svg
new file mode 100644
index 0000000..d1bc232
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/close_focus.svg
@@ -0,0 +1,116 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/close_normal.svg b/.config/awesome/theme/icons/titlebar/win10/close_normal.svg
new file mode 100644
index 0000000..d013ac8
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/close_normal.svg
@@ -0,0 +1,114 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg
new file mode 100644
index 0000000..d1bc232
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg
@@ -0,0 +1,116 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg
new file mode 100644
index 0000000..6f0faf1
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg
@@ -0,0 +1,108 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg
new file mode 100644
index 0000000..6f0faf1
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg
@@ -0,0 +1,108 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg
new file mode 100644
index 0000000..d9dea80
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg
@@ -0,0 +1,113 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg
new file mode 100644
index 0000000..d9dea80
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg
@@ -0,0 +1,113 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg
new file mode 100644
index 0000000..a3efb9b
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg
@@ -0,0 +1,119 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/toggled-off.svg b/.config/awesome/theme/icons/toggled-off.svg
new file mode 100644
index 0000000..a73de49
--- /dev/null
+++ b/.config/awesome/theme/icons/toggled-off.svg
@@ -0,0 +1,74 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/toggled-on.svg b/.config/awesome/theme/icons/toggled-on.svg
new file mode 100644
index 0000000..a75ef1c
--- /dev/null
+++ b/.config/awesome/theme/icons/toggled-on.svg
@@ -0,0 +1,74 @@
+
+
+
+
diff --git a/.config/awesome/theme/icons/volume-high.svg b/.config/awesome/theme/icons/volume-high.svg
new file mode 100644
index 0000000..7a59aa1
--- /dev/null
+++ b/.config/awesome/theme/icons/volume-high.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/theme/init.lua b/.config/awesome/theme/init.lua
new file mode 100644
index 0000000..23b0af5
--- /dev/null
+++ b/.config/awesome/theme/init.lua
@@ -0,0 +1,12 @@
+local gtable = require('gears.table')
+local default_theme = require('theme.default-theme')
+-- PICK THEME HERE
+local theme = require('theme.floppy-theme')
+
+local final_theme = {}
+gtable.crush(final_theme, default_theme.theme)
+gtable.crush(final_theme, theme.theme)
+default_theme.awesome_overrides(final_theme)
+theme.awesome_overrides(final_theme)
+
+return final_theme
diff --git a/.config/awesome/theme/wallpapers/AUTHORS b/.config/awesome/theme/wallpapers/AUTHORS
new file mode 100644
index 0000000..7de152e
--- /dev/null
+++ b/.config/awesome/theme/wallpapers/AUTHORS
@@ -0,0 +1,9 @@
+The images are not mine. Links here:
+
+https://wall.alphacoders.com/big.php?i=988615
+https://wall.alphacoders.com/big.php?i=725593
+https://wall.alphacoders.com/big.php?i=863809
+https://wall.alphacoders.com/big.php?i=743289
+https://wall.alphacoders.com/big.php?i=805656
+https://hdqwalls.com/wallpaper/2560x1440/no-mans-sky-game-2019-4k
+https://www.pinterest.ph/pin/216313588332943910/
diff --git a/.config/awesome/theme/wallpapers/locksreen-bg.jpg b/.config/awesome/theme/wallpapers/locksreen-bg.jpg
new file mode 100644
index 0000000..b0c4d57
Binary files /dev/null and b/.config/awesome/theme/wallpapers/locksreen-bg.jpg differ
diff --git a/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg b/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg
new file mode 100644
index 0000000..0a50832
Binary files /dev/null and b/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg differ
diff --git a/.config/awesome/theme/wallpapers/morning-wallpaper.jpg b/.config/awesome/theme/wallpapers/morning-wallpaper.jpg
new file mode 100644
index 0000000..f9063dd
Binary files /dev/null and b/.config/awesome/theme/wallpapers/morning-wallpaper.jpg differ
diff --git a/.config/awesome/theme/wallpapers/night-wallpaper.jpg b/.config/awesome/theme/wallpapers/night-wallpaper.jpg
new file mode 100644
index 0000000..95408ec
Binary files /dev/null and b/.config/awesome/theme/wallpapers/night-wallpaper.jpg differ
diff --git a/.config/awesome/theme/wallpapers/noon-wallpaper.jpg b/.config/awesome/theme/wallpapers/noon-wallpaper.jpg
new file mode 100644
index 0000000..81382cb
Binary files /dev/null and b/.config/awesome/theme/wallpapers/noon-wallpaper.jpg differ
diff --git a/.config/awesome/utilities/profile-image b/.config/awesome/utilities/profile-image
new file mode 100755
index 0000000..350c9ea
--- /dev/null
+++ b/.config/awesome/utilities/profile-image
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# Depends: Mugshot
+# Written by manilarome
+
+awesome_dir="${HOME}/.config/awesome/"
+user_profile_dir="${awesome_dir}/configuration/user-profile/"
+
+accountsservice_user_icons="/var/lib/AccountsService/icons/${USER}"
+
+# Check if user image exists
+if [ -f "${user_profile_dir}${USER}.png" ];
+then
+ if [ -f "${accountsservice_user_icons}" ];
+ then
+ if ! cmp --silent "${user_profile_dir}${USER}.png" "${accountsservice_user_icons}";
+ then
+ cp "${accountsservice_user_icons}" "${user_profile_dir}${USER}.png"
+ fi
+ printf "${user_profile_dir}${USER}.png"
+ else
+ printf "${user_profile_dir}${USER}.png"
+ fi
+ exit;
+else
+ if [ -f "${accountsservice_user_icons}" ];
+ then
+ cp "${accountsservice_user_icons}" "${user_profile_dir}${USER}.png"
+ printf "${user_profile_dir}${USER}.png"
+ exit;
+ else
+ printf "default"
+ exit;
+ fi
+fi
\ No newline at end of file
diff --git a/.config/awesome/utilities/snap b/.config/awesome/utilities/snap
new file mode 100755
index 0000000..970cee2
--- /dev/null
+++ b/.config/awesome/utilities/snap
@@ -0,0 +1,120 @@
+#!/usr/bin/env bash
+
+# ----------------------------------------------------------------------------
+# --- Simple screenshot script using maim and AwesomeWM API
+# --
+# -- Accepts `area` and `full` string args
+# --
+# -- For more details check `man maim`
+# --
+# -- @author manilarome <gerome.matilla07@gmail.com>
+# -- @copyright 2020 manilarome
+# -- @script snap
+# ----------------------------------------------------------------------------
+
+screenshot_dir=$(xdg-user-dir PICTURES)/Screenshots/
+
+# Check save directory
+# Create it if it doesn't exist
+function check_dir() {
+ if [ ! -d "$screenshot_dir" ];
+ then
+ mkdir -p "$screenshot_dir"
+ fi
+}
+
+# Main function
+function shot() {
+
+ check_dir
+
+ file_loc="${screenshot_dir}$(date +%Y%m%d_%H%M%S).png"
+
+ maim_command="$1"
+ notif_message="$2"
+
+ # Execute maim command
+ ${maim_command} "${file_loc}"
+
+ # Exit if the user cancels the screenshot
+ # So it means there's no new screenshot image file
+ if [ ! -f "${file_loc}" ];
+ then
+ exit;
+ fi
+
+ # Copy to clipboard
+ xclip -selection clipboard -t image/png -i "${screenshot_dir}"/`ls -1 -t "${screenshot_dir}" | head -1` &
+
+ awesome-client "
+
+ -- IMPORTANT NOTE: THIS PART OF THE SCRIPT IS LUA!
+ naughty = require('naughty')
+ awful = require('awful')
+ beautiful = require('beautiful')
+ dpi = beautiful.xresources.apply_dpi
+
+ local open_image = naughty.action {
+ name = 'Open',
+ icon_only = false,
+ }
+
+ local open_folder = naughty.action {
+ name = 'Open Folder',
+ icon_only = false,
+ }
+
+ local delete_image = naughty.action {
+ name = 'Delete',
+ icon_only = false,
+ }
+
+ -- Execute the callback when 'Open' is pressed
+ open_image:connect_signal('invoked', function()
+ awful.spawn('xdg-open ' .. '${file_loc}', false)
+ end)
+
+ open_folder:connect_signal('invoked', function()
+ awful.spawn('xdg-open ' .. '${screenshot_dir}', false)
+ end)
+
+ -- Execute the callback when 'Delete' is pressed
+ delete_image:connect_signal('invoked', function()
+ awful.spawn('gio trash ' .. '${file_loc}', false)
+ end)
+
+ -- Show notification
+ naughty.notification ({
+ app_name = 'Screenshot Tool',
+ icon = '${file_loc}',
+ timeout = 10,
+ title = 'Snap!',
+ message = '${notif_message}',
+ actions = { open_image, open_folder, delete_image }
+ })
+ "
+
+}
+
+# Check the args passed
+if [ -z "$1" ] || ([ "$1" != 'full' ] && [ "$1" != 'area' ]);
+then
+ echo "
+ Requires an argument:
+ area - Area screenshot
+ full - Fullscreen screenshot
+
+ Example:
+ ./snap area
+ ./snap full
+ "
+elif [ "$1" = 'full' ];
+then
+ msg="Full screenshot saved and copied to clipboard!"
+ shot 'maim -u -m 1' "${msg}"
+elif [ "$1" = 'area' ];
+then
+ msg='Area screenshot saved and copied to clipboard!'
+ shot 'maim -u -s -n -m 1' "${msg}"
+fi
+
diff --git a/.config/awesome/widget/airplane-mode/airplane_mode b/.config/awesome/widget/airplane-mode/airplane_mode
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/.config/awesome/widget/airplane-mode/airplane_mode
@@ -0,0 +1 @@
+false
diff --git a/.config/awesome/widget/airplane-mode/clickable-container.lua b/.config/awesome/widget/airplane-mode/clickable-container.lua
new file mode 100755
index 0000000..f531740
--- /dev/null
+++ b/.config/awesome/widget/airplane-mode/clickable-container.lua
@@ -0,0 +1,35 @@
+local wibox = require('wibox')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background,
+ }
+ local old_cursor, old_wibox
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg b/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg
new file mode 100644
index 0000000..7a4c91c
--- /dev/null
+++ b/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg b/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg
new file mode 100644
index 0000000..70fc89d
--- /dev/null
+++ b/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/widget/airplane-mode/init.lua b/.config/awesome/widget/airplane-mode/init.lua
new file mode 100755
index 0000000..1a15c86
--- /dev/null
+++ b/.config/awesome/widget/airplane-mode/init.lua
@@ -0,0 +1,169 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local watch = awful.widget.watch
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.airplane-mode.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_dir = config_dir .. 'widget/airplane-mode/'
+local widget_icon_dir = widget_dir .. 'icons/'
+local icons = require('theme.icons')
+local ap_state = false
+
+local action_name = wibox.widget {
+ text = 'Airplane Mode',
+ font = 'Inter Regular 11',
+ align = 'left',
+ widget = wibox.widget.textbox
+}
+
+local button_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = icons.toggled_off,
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+local widget_button = wibox.widget {
+ {
+ button_widget,
+ top = dpi(7),
+ bottom = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+local update_imagebox = function()
+ if ap_state then
+ button_widget.icon:set_image(icons.toggled_on)
+ else
+ button_widget.icon:set_image(icons.toggled_off)
+ end
+end
+
+local check_airplane_mode_state = function()
+
+ local cmd = 'cat ' .. widget_dir .. 'airplane_mode'
+
+ awful.spawn.easy_async_with_shell(
+ cmd,
+ function(stdout)
+ local status = stdout
+
+ if status:match("true") then
+ ap_state = true
+ elseif status:match("false") then
+ ap_state = false
+ else
+ ap_state = false
+ awful.spawn.easy_async_with_shell(
+ 'echo "false" > ' .. widget_dir .. 'airplane_mode',
+ function(stdout)
+ end
+ )
+ end
+
+ update_imagebox()
+ end
+ )
+end
+
+check_airplane_mode_state()
+
+local ap_off_cmd = [[
+
+ rfkill unblock wlan
+
+ # Create an AwesomeWM Notification
+ awesome-client "
+ naughty = require('naughty')
+ naughty.notification({
+ app_name = 'Network Manager',
+ title = 'Airplane mode disabled!',
+ message = 'Initializing network devices',
+ icon = ']] .. widget_icon_dir .. 'airplane-mode-off' .. '.svg' .. [['
+ })
+ "
+ ]] .. "echo false > " .. widget_dir .. "airplane_mode" .. [[
+]]
+
+local ap_on_cmd = [[
+
+ rfkill block wlan
+
+ # Create an AwesomeWM Notification
+ awesome-client "
+ naughty = require('naughty')
+ naughty.notification({
+ app_name = 'Network Manager',
+ title = 'Airplane mode enabled!',
+ message = 'Disabling radio devices',
+ icon = ']] .. widget_icon_dir .. 'airplane-mode' .. '.svg' .. [['
+ })
+ "
+ ]] .. "echo true > " .. widget_dir .. "airplane_mode" .. [[
+]]
+
+
+local toggle_action = function()
+ if ap_state then
+ awful.spawn.easy_async_with_shell(
+ ap_off_cmd,
+ function(stdout)
+ ap_state = false
+ update_imagebox()
+ end
+ )
+ else
+ awful.spawn.easy_async_with_shell(
+ ap_on_cmd,
+ function(stdout)
+ ap_state = true
+ update_imagebox()
+ end
+ )
+ end
+end
+
+widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_action()
+ end
+ )
+ )
+)
+
+gears.timer {
+ timeout = 5,
+ autostart = true,
+ callback = function()
+ check_airplane_mode_state()
+ end
+}
+
+local action_widget = wibox.widget {
+ {
+ action_name,
+ nil,
+ {
+ widget_button,
+ layout = wibox.layout.fixed.horizontal,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return action_widget
diff --git a/.config/awesome/widget/battery/icons/battery-alert-red.svg b/.config/awesome/widget/battery/icons/battery-alert-red.svg
new file mode 100644
index 0000000..469b0ba
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-alert-red.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-alert.svg b/.config/awesome/widget/battery/icons/battery-alert.svg
new file mode 100644
index 0000000..6ec71c1
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-alert.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-10.svg b/.config/awesome/widget/battery/icons/battery-charging-10.svg
new file mode 100644
index 0000000..4de288a
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-10.svg
@@ -0,0 +1,75 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-20.svg b/.config/awesome/widget/battery/icons/battery-charging-20.svg
new file mode 100644
index 0000000..af759b5
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-20.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-30.svg b/.config/awesome/widget/battery/icons/battery-charging-30.svg
new file mode 100644
index 0000000..f721545
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-30.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-50.svg b/.config/awesome/widget/battery/icons/battery-charging-50.svg
new file mode 100644
index 0000000..42bb375
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-50.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-60.svg b/.config/awesome/widget/battery/icons/battery-charging-60.svg
new file mode 100644
index 0000000..4057d33
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-60.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-80.svg b/.config/awesome/widget/battery/icons/battery-charging-80.svg
new file mode 100644
index 0000000..5febc30
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-80.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-charging-90.svg b/.config/awesome/widget/battery/icons/battery-charging-90.svg
new file mode 100644
index 0000000..544aa5d
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-charging-90.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-100.svg b/.config/awesome/widget/battery/icons/battery-discharging-100.svg
new file mode 100644
index 0000000..b3d3337
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-100.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-20.svg b/.config/awesome/widget/battery/icons/battery-discharging-20.svg
new file mode 100644
index 0000000..116a7f9
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-20.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-30.svg b/.config/awesome/widget/battery/icons/battery-discharging-30.svg
new file mode 100644
index 0000000..d1f4463
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-30.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-50.svg b/.config/awesome/widget/battery/icons/battery-discharging-50.svg
new file mode 100644
index 0000000..8dca81e
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-50.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-60.svg b/.config/awesome/widget/battery/icons/battery-discharging-60.svg
new file mode 100644
index 0000000..25eaca0
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-60.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-80.svg b/.config/awesome/widget/battery/icons/battery-discharging-80.svg
new file mode 100644
index 0000000..5612658
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-80.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-discharging-90.svg b/.config/awesome/widget/battery/icons/battery-discharging-90.svg
new file mode 100644
index 0000000..d11ab44
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-discharging-90.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-fully-charged.svg b/.config/awesome/widget/battery/icons/battery-fully-charged.svg
new file mode 100644
index 0000000..7e923fc
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-fully-charged.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery-unknown.svg b/.config/awesome/widget/battery/icons/battery-unknown.svg
new file mode 100644
index 0000000..ad67bdf
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery-unknown.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/icons/battery.svg b/.config/awesome/widget/battery/icons/battery.svg
new file mode 100644
index 0000000..adba7ac
--- /dev/null
+++ b/.config/awesome/widget/battery/icons/battery.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/battery/init.lua b/.config/awesome/widget/battery/init.lua
new file mode 100644
index 0000000..ca0c3de
--- /dev/null
+++ b/.config/awesome/widget/battery/init.lua
@@ -0,0 +1,209 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local naughty = require('naughty')
+local watch = awful.widget.watch
+local apps = require('configuration.apps')
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/battery/icons/'
+
+local return_button = function()
+
+ local battery_imagebox = wibox.widget {
+ nil,
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'battery' .. '.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+ }
+
+ local battery_percentage_text = wibox.widget {
+ id = 'percent_text',
+ text = '100%',
+ font = 'Inter Bold 11',
+ align = 'center',
+ valign = 'center',
+ visible = false,
+ widget = wibox.widget.textbox
+ }
+
+
+ local battery_widget = wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(0),
+ battery_imagebox,
+ battery_percentage_text
+ }
+
+
+ local battery_button = wibox.widget {
+ {
+ battery_widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ battery_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn(apps.default.power_manager , false)
+ end
+ )
+ )
+ )
+
+ local battery_tooltip = awful.tooltip {
+ objects = {battery_button},
+ text = 'None',
+ mode = 'outside',
+ align = 'right',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'right', 'left', 'top', 'bottom'}
+ }
+
+
+ local get_battery_info = function()
+ awful.spawn.easy_async_with_shell(
+ 'upower -i $(upower -e | grep BAT)',
+ function(stdout)
+ if stdout == nil or stdout == '' then
+ battery_tooltip:set_text('No battery detected!')
+ return
+ end
+
+ -- Remove new line from the last line
+ battery_tooltip:set_text(stdout:sub(1, -2))
+ end
+ )
+ end
+ get_battery_info()
+
+ battery_widget:connect_signal(
+ 'mouse::enter',
+ function()
+ get_battery_info()
+ end
+ )
+
+ local last_battery_check = os.time()
+ local notify_critcal_battery = true
+
+ local show_battery_warning = function()
+ naughty.notification ({
+ icon = widget_icon_dir .. 'battery-alert.svg',
+ app_name = 'System notification',
+ title = 'Battery is dying!',
+ message = 'Hey, I think we have a problem here. Save your work before reaching the oblivion.',
+ urgency = 'critical'
+ })
+ end
+
+ local update_battery = function(status)
+
+ awful.spawn.easy_async_with_shell(
+ [[sh -c "
+ upower -i $(upower -e | grep BAT) | grep percentage | awk '{print \$2}' | tr -d '\n%'
+ "]],
+ function(stdout)
+ local battery_percentage = tonumber(stdout)
+
+ -- Stop if null
+ if not battery_percentage then
+ return
+ end
+
+ battery_widget.spacing = dpi(5)
+ battery_percentage_text.visible = true
+ battery_percentage_text:set_text(battery_percentage .. '%')
+
+ local icon_name = 'battery'
+
+ -- Fully charged
+ if (status == 'fully-charged' or status == 'charging') and battery_percentage == 100 then
+ icon_name = icon_name .. '-' .. 'fully-charged'
+ battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg'))
+ return
+ end
+
+ -- Critical level warning message
+ if (battery_percentage > 0 and battery_percentage < 10) and status == 'discharging' then
+ icon_name = icon_name .. '-' .. 'alert-red'
+
+ if os.difftime(os.time(), last_battery_check) > 300 or notify_critcal_battery then
+ last_battery_check = os.time()
+ notify_critcal_battery = false
+ show_battery_warning()
+ end
+ battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg'))
+ return
+ end
+
+ -- Discharging
+ if battery_percentage > 0 and battery_percentage < 20 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '10'
+
+ elseif battery_percentage >= 20 and battery_percentage < 30 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '20'
+
+ elseif battery_percentage >= 30 and battery_percentage < 50 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '30'
+
+ elseif battery_percentage >= 50 and battery_percentage < 60 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '50'
+
+ elseif battery_percentage >= 60 and battery_percentage < 80 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '60'
+
+ elseif battery_percentage >= 80 and battery_percentage < 90 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '80'
+
+ elseif battery_percentage >= 90 and battery_percentage < 100 then
+ icon_name = icon_name .. '-' .. status .. '-' .. '90'
+ end
+
+ battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg'))
+ end
+ )
+ end
+
+ -- Watch status if charging, discharging, fully-charged
+ watch(
+ [[sh -c "
+ upower -i $(upower -e | grep BAT) | grep state | awk '{print \$2}' | tr -d '\n'
+ "]],
+ 5,
+ function(widget, stdout)
+ local status = stdout:gsub('%\n', '')
+
+ -- If no output or no battery detected
+ if status == nil or status == '' then
+ battery_widget.spacing = dpi(0)
+ battery_percentage_text.visible = false
+ battery_tooltip:set_text('No battery detected!')
+ battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'battery-unknown' .. '.svg'))
+ return
+ end
+
+ update_battery(status)
+ end
+ )
+
+ return battery_button
+end
+
+return return_button
diff --git a/.config/awesome/widget/blue-light/clickable-container.lua b/.config/awesome/widget/blue-light/clickable-container.lua
new file mode 100755
index 0000000..f531740
--- /dev/null
+++ b/.config/awesome/widget/blue-light/clickable-container.lua
@@ -0,0 +1,35 @@
+local wibox = require('wibox')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background,
+ }
+ local old_cursor, old_wibox
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/.config/awesome/widget/blue-light/init.lua b/.config/awesome/widget/blue-light/init.lua
new file mode 100644
index 0000000..093fcb0
--- /dev/null
+++ b/.config/awesome/widget/blue-light/init.lua
@@ -0,0 +1,124 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.blue-light.clickable-container')
+local icons = require('theme.icons')
+local blue_light_state = nil
+
+local action_name = wibox.widget {
+ text = 'Blue Light',
+ font = 'Inter Regular 11',
+ align = 'left',
+ widget = wibox.widget.textbox
+}
+
+local button_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = icons.toggled_off,
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+local widget_button = wibox.widget {
+ {
+ button_widget,
+ top = dpi(7),
+ bottom = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+
+local update_imagebox = function()
+ local button_icon = button_widget.icon
+ if blue_light_state then
+ button_icon:set_image(icons.toggled_on)
+ else
+ button_icon:set_image(icons.toggled_off)
+ end
+end
+
+local kill_state = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ redshift -x
+ kill -9 $(pgrep redshift)
+ ]],
+ function(stdout)
+ stdout = tonumber(stdout)
+ if stdout then
+ blue_light_state = false
+ update_imagebox()
+ end
+ end
+ )
+end
+
+kill_state()
+
+local toggle_action = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ if [ ! -z $(pgrep redshift) ];
+ then
+ redshift -x && pkill redshift && killall redshift
+ echo 'OFF'
+ else
+ redshift -l 0:0 -t 4500:4500 -r &>/dev/null &
+ echo 'ON'
+ fi
+ ]],
+ function(stdout)
+ if stdout:match('ON') then
+ blue_light_state = true
+ else
+ blue_light_state = false
+ end
+ update_imagebox()
+ end
+ )
+
+end
+
+widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_action()
+ end
+ )
+ )
+)
+
+local action_widget = wibox.widget {
+ {
+ action_name,
+ nil,
+ {
+ widget_button,
+ layout = wibox.layout.fixed.horizontal,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+awesome.connect_signal(
+ 'widget::blue_light:toggle',
+ function()
+ toggle_action()
+ end
+)
+
+return action_widget
diff --git a/.config/awesome/widget/bluetooth-toggle/clickable-container.lua b/.config/awesome/widget/bluetooth-toggle/clickable-container.lua
new file mode 100644
index 0000000..f531740
--- /dev/null
+++ b/.config/awesome/widget/bluetooth-toggle/clickable-container.lua
@@ -0,0 +1,35 @@
+local wibox = require('wibox')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background,
+ }
+ local old_cursor, old_wibox
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg b/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg
new file mode 100644
index 0000000..f3e52ab
--- /dev/null
+++ b/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/bluetooth-toggle/icons/loading.svg b/.config/awesome/widget/bluetooth-toggle/icons/loading.svg
new file mode 100644
index 0000000..cd7bc0e
--- /dev/null
+++ b/.config/awesome/widget/bluetooth-toggle/icons/loading.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/bluetooth-toggle/init.lua b/.config/awesome/widget/bluetooth-toggle/init.lua
new file mode 100644
index 0000000..a4d7016
--- /dev/null
+++ b/.config/awesome/widget/bluetooth-toggle/init.lua
@@ -0,0 +1,164 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local naughty = require('naughty')
+local watch = awful.widget.watch
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.bluetooth-toggle.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/bluetooth-toggle/icons/'
+local icons = require('theme.icons')
+local device_state = false
+
+local action_name = wibox.widget {
+ text = 'Bluetooth Connection',
+ font = 'Inter Regular 11',
+ align = 'left',
+ widget = wibox.widget.textbox
+}
+
+local button_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = icons.toggled_off,
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+local widget_button = wibox.widget {
+ {
+ button_widget,
+ top = dpi(7),
+ bottom = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+local action_widget = wibox.widget {
+ {
+ action_name,
+ nil,
+ {
+ widget_button,
+ layout = wibox.layout.fixed.horizontal,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+
+local update_imagebox = function()
+ if device_state then
+ button_widget.icon:set_image(icons.toggled_on)
+ else
+ button_widget.icon:set_image(icons.toggled_off)
+ end
+end
+
+
+local check_device_state = function()
+ awful.spawn.easy_async_with_shell(
+ 'rfkill list bluetooth',
+ function(stdout)
+ if stdout:match('Soft blocked: yes') then
+ device_state = false
+ else
+ device_state = true
+ end
+ update_imagebox()
+ end
+ )
+end
+
+check_device_state()
+
+
+local power_on_cmd = [[
+ rfkill unblock bluetooth
+
+ # Create an AwesomeWM Notification
+ awesome-client "
+ naughty = require('naughty')
+ naughty.notification({
+ app_name = 'Bluetooth Manager',
+ title = 'System Notification',
+ message = 'Initializing bluetooth device...',
+ icon = ']] .. widget_icon_dir .. 'loading' .. '.svg' .. [['
+ })
+ "
+
+ # Add a delay here so we can enable the bluetooth
+ sleep 1
+
+ bluetoothctl power on
+]]
+
+local power_off_cmd = [[
+ bluetoothctl power off
+ rfkill block bluetooth
+
+ # Create an AwesomeWM Notification
+ awesome-client "
+ naughty = require('naughty')
+ naughty.notification({
+ app_name = 'Bluetooth Manager',
+ title = 'System Notification',
+ message = 'The bluetooth device has been disabled.',
+ icon = ']] .. widget_icon_dir .. 'bluetooth-off' .. '.svg' .. [['
+ })
+ "
+]]
+
+
+local toggle_action = function()
+ if device_state then
+ device_state = false
+ awful.spawn.easy_async_with_shell(
+ power_off_cmd,
+ function(stdout)
+ update_imagebox()
+ end
+ )
+ else
+ device_state = true
+ awful.spawn.easy_async_with_shell(
+ power_on_cmd,
+ function(stdout)
+ update_imagebox()
+ end
+ )
+ end
+end
+
+
+widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_action()
+ end
+ )
+ )
+)
+
+watch(
+ 'rfkill list bluetooth',
+ 5,
+ function(_, stdout)
+ check_device_state()
+ collectgarbage('collect')
+ end
+)
+
+
+return action_widget
diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg
new file mode 100644
index 0000000..bbda6ad
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg
new file mode 100644
index 0000000..f3e52ab
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg
new file mode 100644
index 0000000..029f145
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth.svg b/.config/awesome/widget/bluetooth/icons/bluetooth.svg
new file mode 100644
index 0000000..32fbc3e
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/icons/bluetooth.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/bluetooth/icons/loading.svg b/.config/awesome/widget/bluetooth/icons/loading.svg
new file mode 100644
index 0000000..cd7bc0e
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/icons/loading.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/bluetooth/init.lua b/.config/awesome/widget/bluetooth/init.lua
new file mode 100644
index 0000000..153ef3b
--- /dev/null
+++ b/.config/awesome/widget/bluetooth/init.lua
@@ -0,0 +1,83 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local naughty = require('naughty')
+local watch = awful.widget.watch
+local dpi = require('beautiful').xresources.apply_dpi
+
+local apps = require('configuration.apps')
+
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+
+local widget_icon_dir = config_dir .. 'widget/bluetooth/icons/'
+
+local return_button = function()
+
+ local widget =
+ wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'bluetooth-off' .. '.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn(apps.default.bluetooth_manager, false)
+ end
+ )
+ )
+ )
+
+ local bluetooth_tooltip = awful.tooltip
+ {
+ objects = {widget_button},
+ mode = 'outside',
+ align = 'right',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'right', 'left', 'top', 'bottom'}
+ }
+
+ watch(
+ 'rfkill list bluetooth',
+ 5,
+ function(_, stdout)
+ local widget_icon_name = nil
+ if stdout:match('Soft blocked: yes') then
+ widget_icon_name = 'bluetooth-off'
+ bluetooth_tooltip.markup = 'Bluetooth is off'
+ else
+ widget_icon_name = 'bluetooth'
+ bluetooth_tooltip.markup = 'Bluetooth is on'
+ end
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ collectgarbage('collect')
+ end,
+ widget
+ )
+
+ return widget_button
+
+end
+
+return return_button
\ No newline at end of file
diff --git a/.config/awesome/widget/blur-slider/clickable-container.lua b/.config/awesome/widget/blur-slider/clickable-container.lua
new file mode 100644
index 0000000..f531740
--- /dev/null
+++ b/.config/awesome/widget/blur-slider/clickable-container.lua
@@ -0,0 +1,35 @@
+local wibox = require('wibox')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background,
+ }
+ local old_cursor, old_wibox
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/.config/awesome/widget/blur-slider/init.lua b/.config/awesome/widget/blur-slider/init.lua
new file mode 100644
index 0000000..4d7275b
--- /dev/null
+++ b/.config/awesome/widget/blur-slider/init.lua
@@ -0,0 +1,194 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+local spawn = awful.spawn
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+local clickable_container = require('widget.clickable-container')
+
+local action_name = wibox.widget {
+ text = 'Blur Strength',
+ font = 'Inter Bold 10',
+ align = 'left',
+ widget = wibox.widget.textbox
+}
+
+local icon = wibox.widget {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ image = icons.effects,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ nil
+}
+
+local action_level = wibox.widget {
+ {
+ icon,
+ widget = clickable_container,
+ },
+ bg = beautiful.transparent,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'blur_strength_slider',
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(2),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider,
+ },
+ nil,
+ expand = 'none',
+ forced_height = dpi(24),
+ layout = wibox.layout.align.vertical
+}
+
+local blur_slider = slider.blur_strength_slider
+
+local update_slider_value = function()
+
+ awful.spawn.easy_async_with_shell(
+ [[bash -c "
+ grep -F 'strength =' $HOME/.config/awesome/configuration/picom.conf |
+ awk 'NR==1 {print $3}' | tr -d ';'
+ "]],
+ function(stdout, stderr)
+ local strength = stdout:match('%d+')
+ blur_strength = tonumber(strength) / 20 * 100
+ blur_slider:set_value(tonumber(blur_strength))
+ start_up = false
+ end
+ )
+end
+
+-- Update on startup
+update_slider_value()
+
+local action_jump = function()
+ local sli_value = blur_slider:get_value()
+ local new_value = 0
+
+ if sli_value >= 0 and sli_value < 25 then
+ new_value = 25
+ elseif sli_value >= 25 and sli_value < 50 then
+ new_value = 50
+ elseif sli_value >= 50 and sli_value < 100 then
+ new_value = 100
+ else
+ new_value = 0
+ end
+ blur_slider:set_value(new_value)
+end
+
+action_level:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ action_jump()
+ end
+ )
+ )
+)
+
+local adjust_blur = function(power)
+
+ awful.spawn.with_shell(
+ [[bash -c "
+ sed -i 's/.*strength = .*/ strength = ]] .. power .. [[;/g' \
+ $HOME/.config/awesome/configuration/picom.conf
+ "]]
+ )
+end
+
+blur_slider:connect_signal(
+ 'property::value',
+ function()
+ if not start_up then
+ strength = blur_slider:get_value() / 50 * 10
+ adjust_blur(strength)
+ end
+ end
+)
+
+-- Adjust slider value to change blur strength
+awesome.connect_signal(
+ 'widget::blur:increase',
+ function()
+
+ -- On startup, the slider.value returns nil so...
+ if blur_slider:get_value() == nil then
+ return
+ end
+
+ local blur_value = blur_slider:get_value() + 10
+
+ -- No more than 100!
+ if blur_value > 100 then
+ blur_slider:set_value(100)
+ return
+ end
+
+ blur_slider:set_value(blur_value)
+ end
+)
+
+-- Decrease blur
+awesome.connect_signal(
+ 'widget::blur:decrease',
+ function()
+
+ -- On startup, the slider.value returns nil so...
+ if blur_slider:get_value() == nil then
+ return
+ end
+
+ local blur_value = blur_slider:get_value() - 10
+
+ -- No negatives!
+ if blur_value < 0 then
+ blur_slider:set_value(0)
+ return
+ end
+
+ blur_slider:set_value(blur_value)
+ end
+)
+
+local volume_setting = wibox.widget {
+ {
+ {
+ action_level,
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return volume_setting
diff --git a/.config/awesome/widget/blur-toggle/clickable-container.lua b/.config/awesome/widget/blur-toggle/clickable-container.lua
new file mode 100644
index 0000000..f531740
--- /dev/null
+++ b/.config/awesome/widget/blur-toggle/clickable-container.lua
@@ -0,0 +1,35 @@
+local wibox = require('wibox')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background,
+ }
+ local old_cursor, old_wibox
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/.config/awesome/widget/blur-toggle/init.lua b/.config/awesome/widget/blur-toggle/init.lua
new file mode 100644
index 0000000..fe30b3f
--- /dev/null
+++ b/.config/awesome/widget/blur-toggle/init.lua
@@ -0,0 +1,139 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local clickable_container = require('widget.blur-toggle.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+local filesystem = gears.filesystem
+local config_dir = filesystem.get_configuration_dir()
+local icons = require('theme.icons')
+local apps = require('configuration.apps')
+local frame_status = nil
+
+local action_name = wibox.widget {
+ text = 'Blur Effects',
+ font = 'Inter Regular 11',
+ align = 'left',
+ widget = wibox.widget.textbox
+}
+
+local button_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = icons.toggled_off,
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+local widget_button = wibox.widget {
+ {
+ button_widget,
+ top = dpi(7),
+ bottom = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+local update_imagebox = function()
+ if action_status then
+ button_widget.icon:set_image(icons.toggled_on)
+ else
+ button_widget.icon:set_image(icons.toggled_off)
+ end
+end
+
+local check_blur_status = function()
+ awful.spawn.easy_async_with_shell(
+ [[bash -c "
+ grep -F 'method = \"none\";' ]] .. config_dir .. [[/configuration/picom.conf | tr -d '[\"\;\=\ ]'
+ "]],
+ function(stdout, stderr)
+ if stdout:match('methodnone') then
+ action_status = false
+ else
+ action_status = true
+ end
+
+ update_imagebox()
+ end
+ )
+end
+
+check_blur_status()
+
+local toggle_blur = function(togglemode)
+
+ local toggle_blur_script = [[bash -c "
+ # Check picom if it's not running then start it
+ if [ -z $(pgrep picom) ]; then
+ picom -b --experimental-backends --dbus --config ]] .. config_dir .. [[configuration/picom.conf
+ fi
+
+ case ]] .. togglemode .. [[ in
+ 'enable')
+ sed -i -e 's/method = \"none\"/method = \"dual_kawase\"/g' \"]] .. config_dir .. [[configuration/picom.conf\"
+ ;;
+ 'disable')
+ sed -i -e 's/method = \"dual_kawase\"/method = \"none\"/g' \"]] .. config_dir .. [[configuration/picom.conf\"
+ ;;
+ esac
+ "]]
+
+ -- Run the script
+ awful.spawn.with_shell(toggle_blur_script)
+
+end
+
+local toggle_blur_fx = function()
+ local state = nil
+ if action_status then
+ action_status = false
+ state = 'disable'
+ else
+ action_status = true
+ state = 'enable'
+ end
+ toggle_blur(state)
+ update_imagebox()
+end
+
+widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_blur_fx()
+ end
+ )
+ )
+)
+
+local action_widget = wibox.widget {
+ {
+ action_name,
+ nil,
+ {
+ widget_button,
+ layout = wibox.layout.fixed.horizontal,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+awesome.connect_signal(
+ 'widget::blur:toggle',
+ function()
+ toggle_blur_fx()
+ end
+)
+
+
+return action_widget
diff --git a/.config/awesome/widget/brightness-slider/init.lua b/.config/awesome/widget/brightness-slider/init.lua
new file mode 100644
index 0000000..aa53692
--- /dev/null
+++ b/.config/awesome/widget/brightness-slider/init.lua
@@ -0,0 +1,180 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+local spawn = awful.spawn
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+local clickable_container = require('widget.clickable-container')
+
+local icon = wibox.widget {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ image = icons.brightness,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ nil
+}
+
+local action_level = wibox.widget {
+ {
+ icon,
+ widget = clickable_container
+ },
+ bg = beautiful.transparent,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'brightness_slider',
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(2),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider,
+ },
+ nil,
+ expand = 'none',
+ forced_height = dpi(24),
+ layout = wibox.layout.align.vertical
+}
+
+
+local brightness_slider = slider.brightness_slider
+
+brightness_slider:connect_signal(
+ 'property::value',
+ function()
+ local brightness_level = brightness_slider:get_value()
+
+ spawn('light -S ' ..
+ math.max(brightness_level, 5),
+ false
+ )
+
+ -- Update brightness osd
+ awesome.emit_signal(
+ 'module::brightness_osd',
+ brightness_level
+ )
+ end
+)
+
+brightness_slider:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 4,
+ nil,
+ function()
+ if brightness_slider:get_value() > 100 then
+ brightness_slider:set_value(100)
+ return
+ end
+ brightness_slider:set_value(brightness_slider:get_value() + 5)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ nil,
+ function()
+ if brightness_slider:get_value() < 0 then
+ brightness_slider:set_value(0)
+ return
+ end
+ brightness_slider:set_value(brightness_slider:get_value() - 5)
+ end
+ )
+ )
+)
+
+
+local update_slider = function()
+ awful.spawn.easy_async_with_shell(
+ 'light -G',
+ function(stdout)
+ local brightness = string.match(stdout, '(%d+)')
+ brightness_slider:set_value(tonumber(brightness))
+ end
+ )
+end
+
+-- Update on startup
+update_slider()
+
+local action_jump = function()
+ local sli_value = brightness_slider:get_value()
+ local new_value = 0
+
+ if sli_value >= 0 and sli_value < 50 then
+ new_value = 50
+ elseif sli_value >= 50 and sli_value < 100 then
+ new_value = 100
+ else
+ new_value = 0
+ end
+ brightness_slider:set_value(new_value)
+end
+
+action_level:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ action_jump()
+ end
+ )
+ )
+)
+
+-- The emit will come from the global keybind
+awesome.connect_signal(
+ 'widget::brightness',
+ function()
+ update_slider()
+ end
+)
+
+-- The emit will come from the OSD
+awesome.connect_signal(
+ 'widget::brightness:update',
+ function(value)
+ brightness_slider:set_value(tonumber(value))
+ end
+)
+
+local brightness_setting = wibox.widget {
+ {
+ {
+ action_level,
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return brightness_setting
diff --git a/.config/awesome/widget/calculator/icons/kb-off.svg b/.config/awesome/widget/calculator/icons/kb-off.svg
new file mode 100644
index 0000000..0bcea86
--- /dev/null
+++ b/.config/awesome/widget/calculator/icons/kb-off.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/.config/awesome/widget/calculator/icons/kb.svg b/.config/awesome/widget/calculator/icons/kb.svg
new file mode 100644
index 0000000..edccdc8
--- /dev/null
+++ b/.config/awesome/widget/calculator/icons/kb.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/.config/awesome/widget/calculator/init.lua b/.config/awesome/widget/calculator/init.lua
new file mode 100644
index 0000000..ff3e279
--- /dev/null
+++ b/.config/awesome/widget/calculator/init.lua
@@ -0,0 +1,476 @@
+----------------------------------------------------------------------------
+--- Basic Calculator Widget
+--
+--
+-- For more details check my repos README.md
+--
+--
+-- @author manilarome <gerome.matilla07@gmail.com>
+-- @copyright 2019 manilarome
+-- @widget calculator
+----------------------------------------------------------------------------
+
+-- A basic calculator widget
+-- Supports keyboard input!
+-- Just hover your cursor above the calculator widget and start typing
+-- Stop keygrabbing by leaving the calculator
+
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/calculator/icons/'
+
+local calculator_screen = wibox.widget {
+ {
+ id = 'calcu_screen',
+ text = '0',
+ font = 'Inter Regular 20',
+ align = 'right',
+ valign = 'center',
+ widget = wibox.widget.textbox,
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+}
+
+-- Evaluate
+local calculate = function ()
+
+ local calcu_screen = calculator_screen.calcu_screen
+
+ local string_expression = calcu_screen:get_text()
+
+ if string_expression:sub(-1):match('[%+%-%/%*%^%.]') then
+ return
+ end
+
+
+ local func = assert(load('return ' .. string_expression))
+ local ans = tostring(func())
+
+ -- Convert -nan to undefined
+ if ans == '-nan' then
+ calcu_screen:set_text('undefined')
+ return
+ end
+
+ -- Set the answer in textbox
+ calcu_screen:set_text(ans)
+
+end
+
+local txt_on_screen = function()
+
+ screen_text = calculator_screen.calcu_screen:get_text()
+
+ return screen_text == 'inf' or screen_text == 'undefined' or screen_text == 'SYNTAX ERROR' or #screen_text == 1
+end
+
+-- Delete the last digit in screen
+
+local delete_value = function()
+
+ calcu_screen = calculator_screen.calcu_screen
+
+ -- Set the screen text to 0 if conditions met
+ if txt_on_screen() then
+ calcu_screen:set_text('0')
+ else
+ -- Delete the last digit
+ calcu_screen:set_text(calcu_screen:get_text():sub(1, -2))
+ end
+end
+
+-- Clear screen
+local clear_screen = function()
+
+ calculator_screen.calcu_screen:set_text('0')
+end
+
+-- The one that filters and checks the user input to avoid errors and bugs
+local format_screen = function(value)
+
+ local calcu_screen = calculator_screen.calcu_screen
+
+ -- If the screen has only 0
+ if calcu_screen:get_text() == '0' then
+
+ -- Check if the button pressed sends a value of either +, -, /, *, ^, .
+
+ if value:sub(-1):match('[%+%/%*%^%.]') then
+
+ calcu_screen:set_text(calcu_screen:get_text() .. tostring(value))
+
+ else
+
+ calcu_screen:set_text(value)
+
+ end
+
+ elseif calcu_screen:get_text() == 'inf' or
+ calcu_screen:get_text() == 'undefined' or
+ calcu_screen:get_text() == 'SYNTAX ERROR' then
+
+ -- Clear screen if an operator is selected
+ if value:sub(-1):match('[%+%/%*%^%.]') then
+ clear_screen()
+
+ else
+ -- Replace screen txt with the number value pressed
+ clear_screen()
+ calcu_screen:set_text(tostring(value))
+ end
+
+ else
+
+ -- Don't let the user to input two or more consecutive arithmetic operators and decimals
+ if calcu_screen:get_text():sub(-1):match('[%+%-%/%*%^%.]') and value:sub(-1):match('[%+%-%/%*%^%.%%]') then
+
+ -- Get the operator from button pressed
+ local string_eval = calcu_screen:get_text():sub(-1):gsub('[%+%-%/%*%^%.]', value)
+
+ -- This will prevent the user to input consecutive operators and decimals
+ -- It will replace the previous operator with the value of input
+ calcu_screen:set_text(calcu_screen:get_text():sub(1, -2))
+
+ -- Concatenate the value operator to the screen string to replace the deleted operator
+ calcu_screen:set_text(calcu_screen:get_text() .. tostring(string_eval))
+
+ else
+ -- Concatenate the value to screen string
+ calcu_screen:set_text(calcu_screen:get_text() .. tostring(value))
+
+ end
+ end
+
+end
+
+-- Shape generator
+local build_shape = function (position, radius)
+
+ -- Position represents the position of rounded corners
+ if position == 'top' then
+ return function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, radius)
+ end
+
+ elseif position == 'top_left' then
+ return function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, false, false, false, radius)
+ end
+
+ elseif position == 'top_right' then
+ return function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, true, false, false, radius)
+ end
+
+ elseif position == 'bottom_right' then
+ return function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, true, false, radius)
+ end
+
+ elseif position == 'bottom_left' then
+ return function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, true, radius)
+ end
+
+ else
+ return function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, radius)
+ end
+
+ end
+end
+
+-- Themes widgets
+local decorate_widget = function(widget_arg, pos, rad)
+ return wibox.widget {
+ widget_arg,
+ bg = beautiful.groups_bg,
+ shape = build_shape(pos, rad),
+ widget = wibox.container.background
+ }
+end
+
+-- Build a button
+local build_button_widget = function(text, rcp, rad)
+
+ local value = text
+
+ local build_textbox = wibox.widget {
+ {
+ id = 'btn_name',
+ text = value,
+ font = 'Inter 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox,
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+ }
+
+ local build_button = wibox.widget {
+ {
+ build_textbox,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ build_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function ()
+
+ if value == 'C' then
+ clear_screen()
+
+ elseif value == '=' then
+ -- Calculate and error handling
+ if not pcall(calculate) then
+ calculator_screen.calcu_screen:set_text('SYNTAX ERROR')
+ end
+
+ elseif value == 'DEL' then
+ delete_value()
+
+ else
+ format_screen(value)
+
+ end
+ end
+ )
+ )
+ )
+
+ return decorate_widget(build_button, rcp, rad)
+
+end
+
+local keygrab_running = false
+
+local kb_imagebox = wibox.widget {
+
+ id = 'kb_icon',
+ image = widget_icon_dir .. 'kb-off' .. '.svg',
+ resize = true,
+ forced_height = dpi(15),
+ widget = wibox.widget.imagebox
+}
+
+local kb_button_widget = wibox.widget {
+ {
+ {
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ kb_imagebox,
+ nil
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ bg = beautiful.groups_bg,
+ shape = build_shape('bottom_left', beautiful.groups_radius),
+ widget = wibox.container.background
+}
+
+local toggle_btn_keygrab = function()
+
+ if keygrab_running then
+ kb_imagebox:set_image(widget_icon_dir .. 'kb-off' .. '.svg')
+ awesome.emit_signal('widget::calc_stop_keygrab')
+ keygrab_running = false
+ else
+ kb_imagebox:set_image(widget_icon_dir .. 'kb' .. '.svg')
+ awesome.emit_signal('widget::calc_start_keygrab')
+ keygrab_running = true
+ end
+
+end
+
+local kb_button = kb_button_widget
+
+kb_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_btn_keygrab()
+ end
+ )
+ )
+)
+
+local calcu_keygrabber = awful.keygrabber {
+
+ auto_start = true,
+ stop_event = 'release',
+ start_callback = function()
+
+ keygrab_running = true
+ kb_imagebox:set_image(widget_icon_dir .. 'kb' .. '.svg')
+
+ end,
+ stop_callback = function()
+
+ keygrab_running = false
+ kb_imagebox:set_image(widget_icon_dir .. 'kb-off' .. '.svg')
+
+ end,
+ keypressed_callback = function(self, mod, key, command)
+
+ if #key == 1 and (key:match('%d+') or key:match('[%+%-%/%*%^%.]')) then
+ format_screen(key)
+
+ elseif key == 'BackSpace' then
+ delete_value()
+
+ elseif key == 'Escape' then
+ clear_screen()
+
+ elseif key == 'x' then
+ awesome.emit_signal('widget::calc_stop_keygrab')
+
+ elseif key == '=' or key == 'Return' then
+ -- Calculate
+ if not pcall(calculate) then
+ calculator_screen.calcu_screen:set_text('SYNTAX ERROR')
+ end
+
+ end
+
+ end,
+}
+
+local calculator_body = wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(1),
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ decorate_widget(calculator_screen, 'top', beautiful.groups_radius),
+ },
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ build_button_widget('C', 'flat' , 0),
+ build_button_widget('^', 'flat', 0),
+ build_button_widget('/', 'flat', 0),
+ build_button_widget('DEL', 'flat', 0),
+ },
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ build_button_widget('7', 'flat', 0),
+ build_button_widget('8', 'flat', 0),
+ build_button_widget('9', 'flat', 0),
+ build_button_widget('*', 'flat', 0),
+ },
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ build_button_widget('4', 'flat', 0),
+ build_button_widget('5', 'flat', 0),
+ build_button_widget('6', 'flat', 0),
+ build_button_widget('-', 'flat', 0),
+ },
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ build_button_widget('1', 'flat', 0),
+ build_button_widget('2', 'flat', 0),
+ build_button_widget('3', 'flat', 0),
+ build_button_widget('+', 'flat', 0),
+ },
+ {
+ spacing = dpi(1),
+ layout = wibox.layout.flex.horizontal,
+ kb_button,
+ build_button_widget('0', 'flat', 0),
+ build_button_widget('.', 'flat', 0),
+ build_button_widget('=', 'bottom_right', beautiful.groups_radius)
+ },
+}
+
+calculator_body:connect_signal(
+ 'mouse::enter',
+ function()
+ -- Start keygrabbing
+ calcu_keygrabber:start()
+ end
+)
+
+calculator_body:connect_signal(
+ 'mouse::leave',
+ function()
+ -- Stop keygrabbing
+ calcu_keygrabber:stop()
+ end
+)
+
+awesome.connect_signal(
+ 'widget::calc_start_keygrab',
+ function()
+ -- Stop keygrabbing
+ calcu_keygrabber:start()
+ end
+)
+
+awesome.connect_signal(
+ 'widget::calc_stop_keygrab',
+ function()
+ -- Stop keygrabbing
+ calcu_keygrabber:stop()
+ end
+)
+
+local calcu_tooltip = awful.tooltip {
+
+ objects = {kb_button},
+ mode = 'outside',
+ align = 'right',
+ delay_show = 1,
+ preferred_positions = {'right', 'left', 'top', 'bottom'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ markup = [[
+ Tips:
+ Enable keyboard support by hovering your mouse above the calculator.
+ Or toggle it on/off by pressing the keyboard button.
+ Only numbers, arithmetic operators, and decimal point is accepted.
+
+ Keyboard bindings:
+ = and Return to get the answer.
+ BackSpace to delete the last digit.
+ Escape clears the screen.
+ x stops keygrabbing.
+
+ Note:
+ While in keygrabbing mode, your keyboard's focus will be on the calculator.
+ So you're AwesomeWM keybinding will stop working.
+
+ Stopping the keygrabbing mode:
+ * Move away your cursor from the calculator.
+ * Toggle it off using the keyboard button.
+ * Press x.
+ ]]
+}
+
+return calculator_body
diff --git a/.config/awesome/widget/clickable-container/init.lua b/.config/awesome/widget/clickable-container/init.lua
new file mode 100644
index 0000000..6b57aa2
--- /dev/null
+++ b/.config/awesome/widget/clickable-container/init.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+
+local create_click_events = function(widget)
+
+ local container = wibox.widget {
+ widget,
+ widget = wibox.container.background
+ }
+
+ -- Old and new widget
+ local old_cursor, old_wibox
+
+ -- Mouse hovers on the widget
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ container.bg = beautiful.groups_bg
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ -- Mouse leaves the widget
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ container.bg = beautiful.leave_event
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ -- Mouse pressed the widget
+ container:connect_signal(
+ 'button::press',
+ function()
+ container.bg = beautiful.press_event
+ end
+ )
+
+ -- Mouse releases the widget
+ container:connect_signal(
+ 'button::release',
+ function()
+ container.bg = beautiful.release_event
+ end
+ )
+
+ return container
+end
+
+return create_click_events
diff --git a/.config/awesome/widget/clock/init.lua b/.config/awesome/widget/clock/init.lua
new file mode 100644
index 0000000..809fb1f
--- /dev/null
+++ b/.config/awesome/widget/clock/init.lua
@@ -0,0 +1,158 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local config = require('configuration.config')
+local military_mode = config.widget.clock.military_mode or false
+
+local create_clock = function(s)
+
+ local clock_format = nil
+ if not military_mode then
+ clock_format = '%I:%M %p'
+ else
+ clock_format = '%H:%M'
+ end
+
+ s.clock_widget = wibox.widget.textclock(
+ clock_format,
+ 1
+ )
+
+ s.clock_widget = wibox.widget {
+ {
+ s.clock_widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ s.clock_widget:connect_signal(
+ 'mouse::enter',
+ function()
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ s.clock_widget:connect_signal(
+ 'mouse::leave',
+ function()
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ s.clock_tooltip = awful.tooltip
+ {
+ objects = {s.clock_widget},
+ mode = 'outside',
+ delay_show = 1,
+ preferred_positions = {'right', 'left', 'top', 'bottom'},
+ preferred_alignments = {'middle', 'front', 'back'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ timer_function = function()
+ local ordinal = nil
+
+ local day = os.date('%d')
+ local month = os.date('%B')
+
+ local first_digit = string.sub(day, 0, 1)
+ local last_digit = string.sub(day, -1)
+
+ if first_digit == '0' then
+ day = last_digit
+ end
+
+ if last_digit == '1' and day ~= '11' then
+ ordinal = 'st'
+ elseif last_digit == '2' and day ~= '12' then
+ ordinal = 'nd'
+ elseif last_digit == '3' and day ~= '13' then
+ ordinal = 'rd'
+ else
+ ordinal = 'th'
+ end
+
+ local date_str = 'Today is the ' ..
+ '' .. day .. ordinal ..
+ ' of ' .. month .. '.\n' ..
+ 'And it\'s fucking ' .. os.date('%A')
+
+ return date_str
+ end,
+ }
+
+ s.clock_widget:connect_signal(
+ 'button::press',
+ function(self, lx, ly, button)
+ -- Hide the tooltip when you press the clock widget
+ if s.clock_tooltip.visible and button == 1 then
+ s.clock_tooltip.visible = false
+ end
+ end
+ )
+
+ s.month_calendar = awful.widget.calendar_popup.month({
+ start_sunday = true,
+ spacing = dpi(5),
+ font = 'Inter Regular 10',
+ long_weekdays = true,
+ margin = dpi(5),
+ screen = s,
+ style_month = {
+ border_width = dpi(0),
+ bg_color = beautiful.background,
+ padding = dpi(20),
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, true, true, true, true, beautiful.groups_radius
+ )
+ end
+ },
+ style_header = {
+ border_width = 0,
+ bg_color = beautiful.transparent
+ },
+ style_weekday = {
+ border_width = 0,
+ bg_color = beautiful.transparent
+ },
+ style_normal = {
+ border_width = 0,
+ bg_color = beautiful.transparent
+ },
+ style_focus = {
+ border_width = dpi(0),
+ border_color = beautiful.fg_normal,
+ bg_color = beautiful.accent,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, true, true, true, true, dpi(4)
+ )
+ end,
+ },
+ })
+
+ s.month_calendar:attach(
+ s.clock_widget,
+ 'tc',
+ {
+ on_pressed = true,
+ on_hover = false
+ }
+ )
+
+ return s.clock_widget
+end
+
+return create_clock
diff --git a/.config/awesome/widget/cpu-meter/init.lua b/.config/awesome/widget/cpu-meter/init.lua
new file mode 100644
index 0000000..b68f44b
--- /dev/null
+++ b/.config/awesome/widget/cpu-meter/init.lua
@@ -0,0 +1,74 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local watch = require('awful.widget.watch')
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+
+local total_prev = 0
+local idle_prev = 0
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'cpu_usage',
+ max_value = 100,
+ value = 29,
+ forced_height = dpi(2),
+ color = beautiful.fg_normal,
+ background_color = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.widget.progressbar
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+watch(
+ [[bash -c "
+ cat /proc/stat | grep '^cpu '
+ "]],
+ 10,
+ function(_, stdout)
+ local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice =
+ stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s')
+
+ local total = user + nice + system + idle + iowait + irq + softirq + steal
+
+ local diff_idle = idle - idle_prev
+ local diff_total = total - total_prev
+ local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
+
+ slider.cpu_usage:set_value(diff_usage)
+
+ total_prev = total
+ idle_prev = idle
+ collectgarbage('collect')
+ end
+)
+
+local cpu_meter = wibox.widget {
+ {
+ {
+ {
+ image = icons.chart,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return cpu_meter
diff --git a/.config/awesome/widget/email/icons/email-1.svg b/.config/awesome/widget/email/icons/email-1.svg
new file mode 100644
index 0000000..9170d0b
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-1.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-2.svg b/.config/awesome/widget/email/icons/email-2.svg
new file mode 100644
index 0000000..58406a7
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-2.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-3.svg b/.config/awesome/widget/email/icons/email-3.svg
new file mode 100644
index 0000000..597b144
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-3.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-4.svg b/.config/awesome/widget/email/icons/email-4.svg
new file mode 100644
index 0000000..dc915fb
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-4.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-5.svg b/.config/awesome/widget/email/icons/email-5.svg
new file mode 100644
index 0000000..935140c
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-5.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-6.svg b/.config/awesome/widget/email/icons/email-6.svg
new file mode 100644
index 0000000..edf1298
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-6.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-7.svg b/.config/awesome/widget/email/icons/email-7.svg
new file mode 100644
index 0000000..980d79c
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-7.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-8.svg b/.config/awesome/widget/email/icons/email-8.svg
new file mode 100644
index 0000000..4c6618a
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-8.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-9+.svg b/.config/awesome/widget/email/icons/email-9+.svg
new file mode 100644
index 0000000..53a0a68
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-9+.svg
@@ -0,0 +1,104 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-9.svg b/.config/awesome/widget/email/icons/email-9.svg
new file mode 100644
index 0000000..9c65b74
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-9.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email-unread.svg b/.config/awesome/widget/email/icons/email-unread.svg
new file mode 100644
index 0000000..829d3a9
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email-unread.svg
@@ -0,0 +1,117 @@
+
+
diff --git a/.config/awesome/widget/email/icons/email.svg b/.config/awesome/widget/email/icons/email.svg
new file mode 100644
index 0000000..a8860b4
--- /dev/null
+++ b/.config/awesome/widget/email/icons/email.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/email/init.lua b/.config/awesome/widget/email/init.lua
new file mode 100644
index 0000000..7116158
--- /dev/null
+++ b/.config/awesome/widget/email/init.lua
@@ -0,0 +1,410 @@
+local awful = require('awful')
+local gears = require('gears')
+local wibox = require('wibox')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/email/icons/'
+
+local config = require('configuration.config')
+local secrets = {
+ email_address = config.widget.email.address,
+ app_password = config.widget.email.app_password,
+ imap_server = config.widget.email.imap_server,
+ port = config.widget.email.port
+}
+
+local unread_email_count = 0
+local startup_show = true
+
+local scroll_container = function(widget)
+ return wibox.widget {
+ widget,
+ id = 'scroll_container',
+ max_size = 345,
+ speed = 75,
+ expand = true,
+ direction = 'h',
+ step_function = wibox.container.scroll
+ .step_functions.waiting_nonlinear_back_and_forth,
+ fps = 30,
+ layout = wibox.container.scroll.horizontal,
+ }
+end
+
+local email_icon_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'email.svg',
+ resize = true,
+ forced_height = dpi(45),
+ forced_width = dpi(45),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local email_from_text = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'From:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_recent_from = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'loading@stdout.sh',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_subject_text = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'Subject:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_recent_subject = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'Loading data',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_date_text = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'Local Date:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_recent_date = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'Loading date...',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_report = wibox.widget{
+ {
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(10),
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ email_icon_widget,
+ nil
+ },
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ {
+ email_from_text,
+ scroll_container(email_recent_from),
+ spacing = dpi(5),
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ email_subject_text,
+ scroll_container(email_recent_subject),
+ spacing = dpi(5),
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ email_date_text,
+ scroll_container(email_recent_date),
+ spacing = dpi(5),
+ layout = wibox.layout.fixed.horizontal
+ }
+ },
+ nil
+ }
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ forced_height = dpi(92),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius)
+end,
+widget = wibox.container.background
+}
+
+local email_details_tooltip = awful.tooltip
+{
+ text = 'Loading...',
+ objects = {email_icon_widget},
+ mode = 'outside',
+ align = 'right',
+ preferred_positions = {'left', 'right', 'top', 'bottom'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8)
+}
+
+local fetch_email_command = [[
+python3 - < 1 then
+ title = 'You have ' .. unread_counter .. ' unread emails!'
+ else
+ title = 'You have ' .. unread_counter .. ' unread email!'
+ end
+
+ naughty.notification ({
+ app_name = 'Email',
+ title = title,
+ message = email_data,
+ timeout = 30,
+ icon = widget_icon_dir .. 'email-unread.svg'
+ })
+end
+
+local notify_new_email = function(count, from, subject)
+ if not startup_show and (tonumber(count) > tonumber(unread_email_count)) then
+ unread_email_count = tonumber(count)
+
+ local message = "From: " .. from ..
+ "\nSubject: " .. subject
+
+ naughty.notification ({
+ app_name = 'Email',
+ title = 'You have a new unread email!',
+ message = message,
+ timeout = 10,
+ icon = widget_icon_dir .. 'email-unread.svg'
+ })
+ else
+ unread_email_count = tonumber(count)
+ end
+
+end
+
+local set_email_data_tooltip = function(email_data)
+ local email_data = email_data:match('(From:.*)')
+ local counter = "Unread Count: " .. unread_email_count
+ email_details_tooltip:set_markup(counter .. '\n\n' .. email_data)
+end
+
+local set_widget_markup = function(from, subject, date, tooltip)
+
+ email_recent_from:set_markup(from:gsub('%\n', ''))
+ email_recent_subject:set_markup(subject:gsub('%\n', ''))
+ email_recent_date:set_markup(date:gsub('%\n', ''))
+
+ if tooltip then
+ email_details_tooltip:set_markup(tooltip)
+ end
+end
+
+local set_no_connection_msg = function()
+ set_widget_markup(
+ 'message@stderr.sh',
+ 'Check network connection!',
+ os.date('%d-%m-%Y %H:%M:%S'),
+ 'No internet connection!'
+ )
+end
+
+local set_invalid_credentials_msg = function()
+ set_widget_markup(
+ 'message@stderr.sh',
+ 'Invalid Credentials!',
+ os.date('%d-%m-%Y %H:%M:%S'),
+ 'You have an invalid credentials!'
+ )
+end
+
+local set_latest_email_data = function(email_data)
+
+ local unread_count = email_data:match('Unread Count: (.-)From:'):sub(1, -2)
+ local recent_from = email_data:match('From: (.-)Subject:'):sub(1, -2)
+ local recent_subject = email_data:match('Subject: (.-)Local Date:'):sub(1, -2)
+ local recent_date = email_data:match('Local Date: (.-)\n')
+
+ recent_from = recent_from:match('<(.*)>') or recent_from:match('<(.*)>') or recent_from
+
+ local count = tonumber(unread_count)
+ if count > 0 and count <= 9 then
+ email_icon_widget.icon:set_image(widget_icon_dir .. 'email-'.. tostring(count) .. '.svg')
+ elseif count > 9 then
+ email_icon_widget.icon:set_image(widget_icon_dir .. 'email-9+.svg')
+ end
+
+ set_widget_markup(
+ recent_from,
+ recent_subject,
+ recent_date
+ )
+
+ notify_new_email(unread_count, recent_from, recent_subject)
+end
+
+local set_empty_inbox_msg = function()
+ set_widget_markup(
+ 'empty@stdout.sh',
+ 'Empty inbox',
+ os.date('%d-%m-%Y %H:%M:%S'),
+ 'Empty inbox.'
+ )
+end
+
+local fetch_email_data = function()
+ awful.spawn.easy_async_with_shell(
+ fetch_email_command,
+ function(stdout)
+ stdout = gears.string.xml_escape(stdout:sub(1, -2))
+
+ if stdout:match('Temporary failure in name resolution') then
+ set_no_connection_msg()
+ return
+ elseif stdout:match('Invalid credentials') then
+ set_invalid_credentials_msg()
+ return
+ elseif stdout:match('Unread Count: 0') then
+ email_icon_widget.icon:set_image(widget_icon_dir .. 'email.svg')
+ set_empty_inbox_msg()
+ return
+ elseif not stdout:match('Unread Count: (.-)From:') then
+ return
+ elseif not stdout or stdout == '' then
+ return
+ end
+
+ set_latest_email_data(stdout)
+ set_email_data_tooltip(stdout)
+
+ if startup_show then
+ notify_all_unread_email(stdout)
+ startup_show = false
+ end
+ end
+ )
+end
+
+local set_missing_secrets_msg = function()
+ set_widget_markup(
+ 'message@stderr.sh',
+ 'Credentials are missing!',
+ os.date('%d-%m-%Y %H:%M:%S'),
+ 'Missing credentials!'
+ )
+end
+
+local check_secrets = function()
+ if secrets.email_address == '' or secrets.app_password == '' or secrets.imap_server == '' or secrets.port == '' then
+ set_missing_secrets_msg()
+ return
+ else
+ fetch_email_data()
+ end
+end
+
+check_secrets()
+
+local update_widget_timer = gears.timer {
+ timeout = 30,
+ autostart = true,
+ call_now = true,
+ callback = function()
+ check_secrets()
+ end
+}
+
+email_report:connect_signal(
+ 'mouse::enter',
+ function()
+ check_secrets()
+ end
+)
+
+awesome.connect_signal(
+ 'system::network_connected',
+ function()
+ gears.timer.start_new(
+ 5,
+ function()
+ check_secrets()
+ end
+ )
+ end
+)
+
+return email_report
diff --git a/.config/awesome/widget/end-session/init.lua b/.config/awesome/widget/end-session/init.lua
new file mode 100644
index 0000000..4914848
--- /dev/null
+++ b/.config/awesome/widget/end-session/init.lua
@@ -0,0 +1,68 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+local create_widget = function()
+ local exit_widget = {
+ {
+ {
+ {
+ image = icons.logout,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ {
+ text = 'End work session',
+ font = 'Inter Regular 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+ }
+
+ local exit_button = wibox.widget {
+ {
+ exit_widget,
+ widget = clickable_container
+
+ },
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+
+ exit_button:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ screen.primary.left_panel:toggle()
+ awesome.emit_signal('module::exit_screen:show')
+ end
+ )
+ )
+ )
+
+ return exit_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/harddrive-meter/init.lua b/.config/awesome/widget/harddrive-meter/init.lua
new file mode 100644
index 0000000..b3972c3
--- /dev/null
+++ b/.config/awesome/widget/harddrive-meter/init.lua
@@ -0,0 +1,61 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local watch = require('awful.widget.watch')
+local icons = require('theme.icons')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'hdd_usage',
+ max_value = 100,
+ value = 29,
+ forced_height = dpi(2),
+ color = beautiful.fg_normal,
+ background_color = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.widget.progressbar
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+watch(
+ [[bash -c "df -h /home|grep '^/' | awk '{print $5}'"]],
+ 10,
+ function(_, stdout)
+ local space_consumed = stdout:match('(%d+)')
+ slider.hdd_usage:set_value(tonumber(space_consumed))
+ collectgarbage('collect')
+ end
+)
+
+
+local harddrive_meter = wibox.widget {
+ {
+ {
+ {
+ image = icons.harddisk,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return harddrive_meter
diff --git a/.config/awesome/widget/info-center-switch/init.lua b/.config/awesome/widget/info-center-switch/init.lua
new file mode 100644
index 0000000..7583439
--- /dev/null
+++ b/.config/awesome/widget/info-center-switch/init.lua
@@ -0,0 +1,128 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+-- Variable used for switching panel modes
+right_panel_mode = 'today_mode'
+
+local active_button = beautiful.groups_title_bg
+local inactive_button = beautiful.transparent
+
+local notif_text = wibox.widget
+{
+ text = 'Notifications',
+ font = 'Inter Bold 11',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local notif_button = clickable_container(
+ wibox.container.margin(
+ notif_text, dpi(0), dpi(0), dpi(7), dpi(7)
+ )
+)
+
+local wrap_notif = wibox.widget {
+ notif_button,
+ forced_width = dpi(140),
+ bg = inactive_button,
+ border_width = dpi(1),
+ border_color = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, false, true, true, false, beautiful.groups_radius
+ )
+ end,
+ widget = wibox.container.background
+}
+
+local today_text = wibox.widget {
+ text = 'Today',
+ font = 'Inter Bold 11',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local today_button = clickable_container(
+ wibox.container.margin(
+ today_text, dpi(0), dpi(0), dpi(7), dpi(7)
+ )
+)
+
+local wrap_today = wibox.widget {
+ today_button,
+ forced_width = dpi(140),
+ bg = active_button,
+ border_width = dpi(1),
+ border_color = beautiful.groups_title_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, true, false, false, true, beautiful.groups_radius
+ )
+ end,
+ widget = wibox.container.background
+}
+
+local switcher = wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.fixed.horizontal,
+ wrap_today,
+ wrap_notif
+}
+
+function switch_rdb_pane(right_panel_mode)
+
+ local focused = awful.screen.focused()
+
+ if right_panel_mode == 'notif_mode' then
+
+ -- Update button color
+ wrap_notif.bg = active_button
+ wrap_today.bg = inactive_button
+
+ -- Change panel content of right-panel.lua
+ focused.right_panel:switch_pane(right_panel_mode)
+
+ elseif right_panel_mode == 'today_mode' then
+
+ -- Update button color
+ wrap_notif.bg = inactive_button
+ wrap_today.bg = active_button
+
+ -- Change panel content of right-panel.lua
+ focused.right_panel:switch_pane(right_panel_mode)
+ end
+end
+
+notif_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ switch_rdb_pane('notif_mode')
+ end
+ )
+ )
+)
+
+today_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ switch_rdb_pane('today_mode')
+ end
+ )
+ )
+)
+
+return switcher
diff --git a/.config/awesome/widget/info-center-toggle/icons/info-center.svg b/.config/awesome/widget/info-center-toggle/icons/info-center.svg
new file mode 100644
index 0000000..c60cf96
--- /dev/null
+++ b/.config/awesome/widget/info-center-toggle/icons/info-center.svg
@@ -0,0 +1,111 @@
+
+
diff --git a/.config/awesome/widget/info-center-toggle/init.lua b/.config/awesome/widget/info-center-toggle/init.lua
new file mode 100644
index 0000000..cad8656
--- /dev/null
+++ b/.config/awesome/widget/info-center-toggle/init.lua
@@ -0,0 +1,47 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local dpi = require('beautiful').xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/info-center-toggle/icons/'
+local clickable_container = require('widget.clickable-container')
+
+local return_button = function()
+
+ local widget =
+ wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'info-center.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.screen.focused().right_panel:toggle()
+ end
+ )
+ )
+ )
+
+ return widget_button
+end
+
+return return_button
diff --git a/.config/awesome/widget/layoutbox/init.lua b/.config/awesome/widget/layoutbox/init.lua
new file mode 100644
index 0000000..1171f84
--- /dev/null
+++ b/.config/awesome/widget/layoutbox/init.lua
@@ -0,0 +1,51 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+local layout_box = function(s)
+ local layoutbox = wibox.widget {
+ {
+ awful.widget.layoutbox(s),
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+ layoutbox:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ awful.layout.inc(1)
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ function()
+ awful.layout.inc(-1)
+ end
+ ),
+ awful.button(
+ {},
+ 4,
+ function()
+ awful.layout.inc(1)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ function()
+ awful.layout.inc(-1)
+ end
+ )
+ )
+ )
+ return layoutbox
+end
+
+return layout_box
\ No newline at end of file
diff --git a/.config/awesome/widget/mpd/content/album-cover.lua b/.config/awesome/widget/mpd/content/album-cover.lua
new file mode 100755
index 0000000..54bd42b
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/album-cover.lua
@@ -0,0 +1,19 @@
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/mpd/icons/'
+
+local album_cover_img = wibox.widget {
+ {
+ id = 'cover',
+ image = widget_icon_dir .. 'vinyl.svg',
+ resize = true,
+ clip_shape = gears.shape.rounded_rect,
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.vertical
+}
+
+return album_cover_img
diff --git a/.config/awesome/widget/mpd/content/init.lua b/.config/awesome/widget/mpd/content/init.lua
new file mode 100644
index 0000000..9ab0ffd
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/init.lua
@@ -0,0 +1,9 @@
+-- Return UI Table
+return {
+ album_cover = require('widget.mpd.content.album-cover'),
+ progress_bar = require('widget.mpd.content.progress-bar'),
+ track_time = require('widget.mpd.content.track-time'),
+ song_info = require('widget.mpd.content.song-info'),
+ media_buttons = require('widget.mpd.content.media-buttons'),
+ volume_slider = require('widget.mpd.content.volume-slider'),
+}
\ No newline at end of file
diff --git a/.config/awesome/widget/mpd/content/media-buttons.lua b/.config/awesome/widget/mpd/content/media-buttons.lua
new file mode 100755
index 0000000..dc460dd
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/media-buttons.lua
@@ -0,0 +1,121 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/mpd/icons/'
+local media_buttons = {}
+
+media_buttons.play_button_image = wibox.widget {
+ {
+ id = 'play',
+ image = widget_icon_dir .. 'play.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+media_buttons.next_button_image = wibox.widget {
+ {
+ id = 'next',
+ image = widget_icon_dir .. 'next.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+media_buttons.prev_button_image = wibox.widget {
+ {
+ id = 'prev',
+ image = widget_icon_dir .. 'prev.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+media_buttons.repeat_button_image = wibox.widget {
+ {
+ id = 'rep',
+ image = widget_icon_dir .. 'repeat-on.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+media_buttons.random_button_image = wibox.widget {
+ {
+ id = 'rand',
+ image = widget_icon_dir .. 'random-on.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+media_buttons.play_button = wibox.widget {
+ {
+ media_buttons.play_button_image,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+media_buttons.next_button = wibox.widget {
+ {
+ media_buttons.next_button_image,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+media_buttons.prev_button = wibox.widget {
+ {
+ media_buttons.prev_button_image,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+media_buttons.repeat_button = wibox.widget {
+ {
+ media_buttons.repeat_button_image,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+media_buttons.random_button = wibox.widget {
+ {
+ media_buttons.random_button_image,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+media_buttons.navigate_buttons = wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ media_buttons.repeat_button,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ media_buttons.prev_button,
+ media_buttons.play_button,
+ media_buttons.next_button,
+ forced_height = dpi(35),
+ },
+ media_buttons.random_button,
+ forced_height = dpi(35),
+}
+
+return media_buttons
\ No newline at end of file
diff --git a/.config/awesome/widget/mpd/content/progress-bar.lua b/.config/awesome/widget/mpd/content/progress-bar.lua
new file mode 100755
index 0000000..a103340
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/progress-bar.lua
@@ -0,0 +1,21 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+
+local progressbar = wibox.widget {
+ {
+ id = 'music_bar',
+ max_value = 100,
+ forced_height = dpi(3),
+ forced_width = dpi(100),
+ color = '#ffffff',
+ background_color = '#ffffff20',
+ shape = gears.shape.rounded_bar,
+ widget = wibox.widget.progressbar
+ },
+ layout = wibox.layout.stack
+}
+
+return progressbar
diff --git a/.config/awesome/widget/mpd/content/song-info.lua b/.config/awesome/widget/mpd/content/song-info.lua
new file mode 100755
index 0000000..5264780
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/song-info.lua
@@ -0,0 +1,64 @@
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local song_info = {}
+
+song_info.music_title = wibox.widget {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ {
+ id = 'title',
+ text = 'The song title is here',
+ font = 'Inter Bold 12',
+ align = 'center',
+ valign = 'center',
+ ellipsize = 'end',
+ widget = wibox.widget.textbox
+ },
+ id = 'scroll_container',
+ max_size = 345,
+ speed = 75,
+ expand = true,
+ direction = 'h',
+ step_function = wibox.container.scroll
+ .step_functions.waiting_nonlinear_back_and_forth,
+ fps = 60,
+ layout = wibox.container.scroll.horizontal
+ },
+ nil
+}
+
+song_info.music_artist = wibox.widget {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ {
+ id = 'artist',
+ text = 'The artist name is here',
+ font = 'Inter 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ id = 'scroll_container',
+ max_size = 345,
+ speed = 75,
+ expand = true,
+ direction = 'h',
+ step_function = wibox.container.scroll
+ .step_functions.waiting_nonlinear_back_and_forth,
+ layout = wibox.container.scroll.horizontal,
+ fps = 60
+ },
+ nil
+}
+
+song_info.music_info = wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ song_info.music_title,
+ song_info.music_artist
+}
+
+return song_info
diff --git a/.config/awesome/widget/mpd/content/track-time.lua b/.config/awesome/widget/mpd/content/track-time.lua
new file mode 100755
index 0000000..6ffb565
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/track-time.lua
@@ -0,0 +1,37 @@
+local beautiful = require('beautiful')
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = beautiful.xresources.apply_dpi
+
+local time_info = {}
+
+time_info.time_status = wibox.widget {
+ id = 'statustime',
+ text = '00:00',
+ font = 'Inter 8',
+ align = 'center',
+ valign = 'center',
+ forced_height = dpi(10),
+ widget = wibox.widget.textbox
+}
+
+time_info.time_duration = wibox.widget {
+ id = 'durationtime',
+ text = '00:00',
+ font = 'Inter 8',
+ align = 'center',
+ valign = 'center',
+ forced_height = dpi(10),
+ widget = wibox.widget.textbox
+}
+
+time_info.time_track = wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ time_info.time_status,
+ nil,
+ time_info.time_duration
+}
+
+return time_info
diff --git a/.config/awesome/widget/mpd/content/volume-slider.lua b/.config/awesome/widget/mpd/content/volume-slider.lua
new file mode 100755
index 0000000..70151d8
--- /dev/null
+++ b/.config/awesome/widget/mpd/content/volume-slider.lua
@@ -0,0 +1,23 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+
+local slider = {}
+
+slider.vol_slider = wibox.widget {
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(5),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider,
+}
+
+return slider
diff --git a/.config/awesome/widget/mpd/icons/music.svg b/.config/awesome/widget/mpd/icons/music.svg
new file mode 100755
index 0000000..a2aa04e
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/music.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/next.svg b/.config/awesome/widget/mpd/icons/next.svg
new file mode 100644
index 0000000..7df5063
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/next.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/pause.svg b/.config/awesome/widget/mpd/icons/pause.svg
new file mode 100644
index 0000000..9fc7767
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/pause.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/play.svg b/.config/awesome/widget/mpd/icons/play.svg
new file mode 100755
index 0000000..3a56779
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/play.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/prev.svg b/.config/awesome/widget/mpd/icons/prev.svg
new file mode 100644
index 0000000..0e39d34
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/prev.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/random-off.svg b/.config/awesome/widget/mpd/icons/random-off.svg
new file mode 100755
index 0000000..76f2e06
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/random-off.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/mpd/icons/random-on.svg b/.config/awesome/widget/mpd/icons/random-on.svg
new file mode 100755
index 0000000..3baf2ed
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/random-on.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/mpd/icons/repeat-off.svg b/.config/awesome/widget/mpd/icons/repeat-off.svg
new file mode 100644
index 0000000..00a4c06
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/repeat-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/repeat-on.svg b/.config/awesome/widget/mpd/icons/repeat-on.svg
new file mode 100644
index 0000000..6917ca6
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/repeat-on.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/mpd/icons/vinyl.svg b/.config/awesome/widget/mpd/icons/vinyl.svg
new file mode 100755
index 0000000..d26a4a8
--- /dev/null
+++ b/.config/awesome/widget/mpd/icons/vinyl.svg
@@ -0,0 +1,5698 @@
+
+
+
+
diff --git a/.config/awesome/widget/mpd/init.lua b/.config/awesome/widget/mpd/init.lua
new file mode 100755
index 0000000..eb4d25b
--- /dev/null
+++ b/.config/awesome/widget/mpd/init.lua
@@ -0,0 +1,73 @@
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/mpd/icons/'
+local clickable_container = require('widget.clickable-container')
+local music_box = require('widget.mpd.music-box')
+local toggle_music_box = music_box.toggle_music_box
+
+local return_button = function()
+ local widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'music.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ local music_tooltip = awful.tooltip
+ {
+ objects = {widget_button},
+ text = 'None',
+ mode = 'outside',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ align = 'right',
+ preferred_positions = {'right', 'left', 'top', 'bottom'}
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ music_tooltip.visible = false
+ awesome.emit_signal('widget::music', 'mouse')
+ end
+ )
+ )
+ )
+
+ widget_button:connect_signal(
+ "mouse::enter",
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'mpc status',
+ function(stdout)
+ music_tooltip.text = string.gsub(stdout, '\n$', '')
+ end
+ )
+ end
+ )
+
+
+ return widget_button
+
+end
+
+return return_button
diff --git a/.config/awesome/widget/mpd/mpd-music-updater.lua b/.config/awesome/widget/mpd/mpd-music-updater.lua
new file mode 100755
index 0000000..c155caf
--- /dev/null
+++ b/.config/awesome/widget/mpd/mpd-music-updater.lua
@@ -0,0 +1,460 @@
+local gears = require('gears')
+local awful = require('awful')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/mpd/icons/'
+local ui_content = require('widget.mpd.content')
+
+local album_cover = ui_content.album_cover
+local prog_bar = ui_content.progress_bar
+local track_time = ui_content.track_time
+local song_info = ui_content.song_info
+local vol_slider = ui_content.volume_slider
+local media_buttons = ui_content.media_buttons
+
+local apps = require('configuration.apps')
+
+local update_cover = function()
+
+ local extract_script = [=[
+ MUSIC_DIR="$(xdg-user-dir MUSIC)"
+ TMP_DIR="/tmp/awesomewm/${USER}/"
+ TMP_COVER_PATH=${TMP_DIR}"cover.jpg"
+ TMP_SONG="${TMP_DIR}current-song"
+
+ CHECK_EXIFTOOL=$(command -v exiftool)
+
+ if [ ! -d "${TMP_DIR}" ]; then
+ mkdir -p "${TMP_DIR}";
+ fi
+
+ if [ ! -z "$CHECK_EXIFTOOL" ]; then
+
+ SONG="$MUSIC_DIR/$(mpc -p 6600 --format "%file%" current)"
+ PICTURE_TAG="-Picture"
+
+ if [[ "$SONG" == *".m4a" ]]; then
+ PICTURE_TAG="-CoverArt"
+ fi
+
+ # Extract album cover using perl-image-exiftool
+ exiftool -b "$PICTURE_TAG" "$SONG" > "$TMP_COVER_PATH"
+
+ else
+
+ #Extract image using ffmpeg
+ cp "$MUSIC_DIR/$(mpc --format %file% current)" "$TMP_SONG"
+
+ ffmpeg \
+ -hide_banner \
+ -loglevel 0 \
+ -y \
+ -i "$TMP_SONG" \
+ -vf scale=300:-1 \
+ "$TMP_COVER_PATH" > /dev/null 2>&1
+
+ rm "$TMP_SONG"
+ fi
+
+ img_data=$(identify $TMP_COVER_PATH 2>&1)
+
+ # Delete the cover.jpg if it's not a valid image
+ if [[ $img_data == *"insufficient"* ]]; then
+ rm $TMP_COVER_PATH
+ fi
+
+ if [ -f $TMP_COVER_PATH ]; then
+ echo $TMP_COVER_PATH;
+ fi
+ ]=]
+
+ awful.spawn.easy_async_with_shell(
+ extract_script,
+ function(stdout)
+ local album_icon = widget_icon_dir .. 'vinyl.svg'
+
+ if not (stdout == nil or stdout == '') then
+ album_icon = stdout:gsub('%\n', '')
+ end
+
+ album_cover.cover:set_image(gears.surface.load_uncached(album_icon))
+
+ album_cover:emit_signal('widget::redraw_needed')
+ album_cover:emit_signal('widget::layout_changed')
+
+ collectgarbage('collect')
+ end
+ )
+end
+
+local update_progress_bar = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc status | awk 'NR==2 { split($4, a); print a[1]}' | tr -d '[\%\(\)]'
+ ]],
+ function(stdout)
+ local progress_bar = prog_bar.music_bar
+ if stdout ~= nil then
+ progress_bar:set_value(tonumber(stdout))
+ else
+ progress_bar:set_value(0)
+ end
+ end
+ )
+end
+
+local update_time_progress = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc status | awk 'NR==2 { split($3, a, "/"); print a[1]}' | tr -d '[\%\(\)]'
+ ]],
+ function(stdout)
+ local time_status = track_time.time_status
+ if stdout ~= nil then
+ time_status:set_text(tostring(stdout))
+ else
+ time_status:set_text('00:00')
+ end
+ end
+ )
+
+end
+
+local update_time_duration = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc --format %time% current
+ ]],
+ function(stdout)
+ local time_duration = track_time.time_duration
+ if stdout ~= nil then
+ time_duration:set_text(tostring(stdout))
+ else
+ time_duration:set_text('99:59')
+ end
+ end
+ )
+end
+
+local update_file = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc -f %file% current
+ ]],
+ function(stdout)
+ file_name = stdout:gsub('%\n','')
+ end
+ )
+ return file_name
+end
+
+local update_title = function()
+
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc -f %title% current
+ ]],
+ function(stdout)
+
+ -- Remove new lines
+ local title = stdout:gsub('%\n', '')
+
+ local title_widget = song_info.music_title
+ local title_text = song_info.music_title:get_children_by_id('title')[1]
+
+ -- Make sure it's not null
+ if not (title == nil or title == '') then
+ title_text:set_text(title)
+ else
+
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc -f %file% current
+ ]],
+ function(stdout)
+
+ if not (stdout == nil or stdout == '') then
+
+ file_name = stdout:gsub('%\n','')
+
+ file_name = file_name:sub(1, title:len() - 5) .. ''
+
+ title_text:set_text(file_name)
+
+ else
+ -- Set title
+ title_text:set_text('Play some music!')
+
+ end
+ title_widget:emit_signal('widget::redraw_needed')
+ title_widget:emit_signal('widget::layout_changed')
+ end
+ )
+
+ end
+
+ title_widget:emit_signal('widget::redraw_needed')
+ title_widget:emit_signal('widget::layout_changed')
+
+ collectgarbage('collect')
+ end
+ )
+end
+
+local update_artist = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc -f %artist% current
+ ]],
+ function(stdout)
+
+ -- Remove new lines
+ local artist = stdout:gsub('%\n', '')
+
+ local artist_widget = song_info.music_artist
+
+ local artist_text = artist_widget:get_children_by_id('artist')[1]
+
+ if not (artist == nil or artist == '') then
+
+ artist_text:set_text(artist)
+
+ else
+
+
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc -f %file% current
+ ]],
+ function(stdout)
+ if not (stdout == nil or stdout == '') then
+
+ artist_text:set_text('unknown artist')
+
+ else
+ artist_text:set_text('or play some porn?')
+
+ end
+ artist_widget:emit_signal('widget::redraw_needed')
+ artist_widget:emit_signal('widget::layout_changed')
+ end
+ )
+ end
+
+ artist_widget:emit_signal('widget::redraw_needed')
+ artist_widget:emit_signal('widget::layout_changed')
+ end
+ )
+end
+
+local update_volume_slider = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc volume
+ ]],
+ function(stdout)
+ local volume_slider = vol_slider.vol_slider
+ if stdout:match('n/a') then
+ return
+ end
+ volume_slider:set_value(tonumber(stdout:match('%d+')))
+ end
+ )
+end
+
+local check_if_playing = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc status | awk 'NR==2' | grep -o playing
+ ]],
+ function(stdout)
+ local play_button_img = media_buttons.play_button_image.play
+ if not (stdout == nil or stdout == '') then
+ play_button_img:set_image(widget_icon_dir .. 'pause.svg')
+ update_volume_slider()
+ else
+ play_button_img:set_image(widget_icon_dir .. 'play.svg')
+ end
+ end
+ )
+end
+
+local check_repeat_status = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc status | sed -n '/random/p' | cut -c23-24 | sed 's/^[ \t]*//'
+ ]],
+ function(stdout)
+ local repeat_button_img = media_buttons.repeat_button_image.rep
+ if stdout:match('on') then
+ repeat_button_img:set_image(widget_icon_dir .. 'repeat-on.svg')
+ else
+ repeat_button_img:set_image(widget_icon_dir .. 'repeat-off.svg')
+ end
+ end
+ )
+end
+
+local check_random_status = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ mpc status | sed -n '/random/p' | cut -c37-38 | sed 's/^[ \t]*//'
+ ]],
+ function(stdout)
+
+ local random_button_image = media_buttons.random_button_image.rand
+
+ if stdout:match("on") then
+ random_button_image:set_image(widget_icon_dir .. 'random-on.svg')
+ else
+ random_button_image:set_image(widget_icon_dir .. 'random-off.svg')
+ end
+ end
+ )
+end
+
+vol_slider.vol_slider:connect_signal(
+ 'property::value',
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'mpc volume ' .. vol_slider.vol_slider:get_value(),
+ function() end
+ )
+ end
+)
+
+local update_all_content = function()
+ update_progress_bar()
+ update_time_progress()
+ update_time_duration()
+ update_title()
+ update_artist()
+ update_cover()
+ check_if_playing()
+ check_repeat_status()
+ check_random_status()
+ update_volume_slider()
+end
+
+-- Update progress bar and time every N seconds
+gears.timer.start_new(
+ 10,
+ function()
+ update_progress_bar()
+ update_time_progress()
+ return true
+ end
+)
+
+local mpd_startup = [[
+# Let's make sure that MPD is running.
+if [ -z $(pgrep mpd) ]; then mpd; fi
+]]
+
+local mpd_change_event_listener = [[
+sh -c '
+mpc idleloop player
+'
+]]
+
+local kill_mpd_change_event_listener = [[
+ps x |
+grep "mpc idleloop player" |
+grep -v grep |
+awk '{print $1}' |
+xargs kill
+]]
+
+awful.spawn.easy_async_with_shell(
+ mpd_startup,
+ function ()
+ awful.spawn.easy_async_with_shell(
+ kill_mpd_change_event_listener,
+ function ()
+ update_all_content()
+ awful.spawn.with_line_callback(
+ mpd_change_event_listener,
+ {
+ stdout = function(line)
+ update_all_content()
+ end
+ }
+ )
+ end
+ )
+ end
+)
+
+media_buttons.play_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('mpc toggle')
+ end
+ )
+ )
+)
+
+media_buttons.next_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('mpc next')
+ end
+ )
+ )
+)
+
+media_buttons.prev_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('mpc prev')
+ end
+ )
+ )
+)
+
+media_buttons.repeat_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'mpc repeat',
+ function ()
+ check_repeat_status()
+ end
+ )
+ end
+ )
+ )
+)
+
+media_buttons.random_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'mpc random',
+ function ()
+ check_random_status()
+ end
+ )
+ end
+ )
+ )
+)
diff --git a/.config/awesome/widget/mpd/music-box.lua b/.config/awesome/widget/mpd/music-box.lua
new file mode 100755
index 0000000..150ded8
--- /dev/null
+++ b/.config/awesome/widget/mpd/music-box.lua
@@ -0,0 +1,158 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local music_func = {}
+
+screen.connect_signal('request::desktop_decoration', function(s)
+
+ -- Set music box geometry
+ local music_box_margin = dpi(5)
+ local music_box_height = dpi(375)
+ local music_box_width = dpi(260)
+ local music_box_x = nil
+
+
+ s.musicpop = awful.popup {
+ widget = {
+ -- Removing this block will cause an error...
+ },
+ ontop = true,
+ visible = false,
+ type = 'dock',
+ screen = s,
+ width = music_box_width,
+ height = music_box_height,
+ maximum_width = music_box_width,
+ maximum_height = music_box_height,
+ offset = dpi(5),
+ shape = gears.shape.rectangle,
+ bg = beautiful.transparent,
+ preferred_anchors = {'middle', 'back', 'front'},
+ preferred_positions = {'left', 'right', 'top', 'bottom'},
+
+ }
+
+ local ui_content = require('widget.mpd.content')
+
+ s.album = ui_content.album_cover
+ s.progress_bar = ui_content.progress_bar
+ s.time_track = ui_content.track_time.time_track
+ s.song_info = ui_content.song_info.music_info
+ s.media_buttons = ui_content.media_buttons.navigate_buttons
+ s.volume_slider = ui_content.volume_slider.vol_slider
+
+ s.musicpop : setup {
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ expand = 'none',
+ spacing = dpi(8),
+ {
+ s.album,
+ bottom = dpi(5),
+ widget = wibox.container.margin,
+ },
+ {
+ layout = wibox.layout.fixed.vertical,
+ {
+ spacing = dpi(4),
+ layout = wibox.layout.fixed.vertical,
+ s.progress_bar,
+ s.time_track,
+ },
+ s.song_info,
+ s.media_buttons,
+ s.volume_slider,
+ },
+ },
+ top = dpi(15),
+ left = dpi(15),
+ right = dpi(15),
+ widget = wibox.container.margin
+
+ },
+ bg = beautiful.background,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(
+ cr, width, height, true, true, true, true, beautiful.groups_radius
+ )
+ end,
+ widget = wibox.container.background()
+ }
+
+ s.backdrop_music = wibox {
+ ontop = true,
+ visible = false,
+ screen = s,
+ type = 'utility',
+ input_passthrough = false,
+ bg = beautiful.transparent,
+ x = s.geometry.x,
+ y = s.geometry.y,
+ width = s.geometry.width,
+ height = s.geometry.height
+ }
+
+ local toggle_music_box = function(type)
+
+ local focused = awful.screen.focused()
+ local music_box = focused.musicpop
+ local music_backdrop = focused.backdrop_music
+
+ if music_box.visible then
+ music_backdrop.visible = not music_backdrop.visible
+ music_box.visible = not music_box.visible
+
+ else
+
+ if type == 'keyboard' then
+ music_backdrop.visible = true
+ music_box.visible = true
+ awful.placement.top_right(
+ music_box,
+ {
+ margins = {
+ top = dpi(5),
+ right = dpi(music_box_x or 5)
+ },
+ honor_workarea = true
+ })
+ else
+ local widget_button = mouse.current_widget_geometry
+
+ music_backdrop.visible = true
+ music_box:move_next_to(widget_button)
+ music_box_x = (focused.geometry.width - music_box.x) - music_box_width
+ end
+ end
+ end
+
+ awesome.connect_signal(
+ 'widget::music',
+ function(type)
+ toggle_music_box(type)
+ end
+ )
+
+ s.backdrop_music:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_music_box()
+ end
+ )
+ )
+ )
+end)
+
+
+music_func.toggle_music_box = toggle_music_box
+
+local mpd_updater = require('widget.mpd.mpd-music-updater')
+
+return music_func
diff --git a/.config/awesome/widget/mpd/spotify-music-updater.lua b/.config/awesome/widget/mpd/spotify-music-updater.lua
new file mode 100644
index 0000000..40331f6
--- /dev/null
+++ b/.config/awesome/widget/mpd/spotify-music-updater.lua
@@ -0,0 +1,324 @@
+local gears = require('gears')
+local awful = require('awful')
+local naughty = require('naughty')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/music/icons/'
+
+local ui_content = require('widget.music.content')
+
+local album_cover = ui_content.album_cover
+local prog_bar = ui_content.progress_bar
+local track_time = ui_content.track_time
+local song_info = ui_content.song_info
+local vol_slider = ui_content.volume_slider
+local media_buttons = ui_content.media_buttons
+
+-- We can't set/get the data for these
+-- So let's hide them
+
+prog_bar.visible = false
+track_time.time_status.visible = false
+track_time.time_duration.visible = false
+media_buttons.repeat_button.visible = false
+media_buttons.random_button.visible = false
+
+
+local update_cover = function()
+ local get_art_url = [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
+ string:'org.mpris.MediaPlayer2.Player' string:'Metadata' |
+ egrep -A 1 "artUrl"| egrep -v "artUrl" | awk -F '"' '{print $2}' |
+ sed -e 's/open.spotify.com/i.scdn.co/g'
+ ]]
+
+ awful.spawn.easy_async_with_shell(
+ get_art_url,
+ function(link)
+
+ local download_art = [[
+ tmp_dir="/tmp/awesomewm/${USER}/"
+ tmp_cover_path=${tmp_dir}"cover.jpg"
+
+ if [ ! -d $tmp_dir ]; then
+ mkdir -p $tmp_dir;
+ fi
+
+ if [ -f $tmp_cover_path]; then
+ rm $tmp_cover_path
+ fi
+
+ wget -O $tmp_cover_path ]] ..link .. [[
+
+ echo $tmp_cover_path
+ ]]
+
+ awful.spawn.easy_async_with_shell(
+ download_art,
+ function(stdout)
+
+ local album_icon = stdout:gsub('%\n', '')
+
+ album_cover.cover:set_image(gears.surface.load_uncached(album_icon))
+
+ album_cover:emit_signal("widget::redraw_needed")
+ album_cover:emit_signal("widget::layout_changed")
+
+ collectgarbage('collect')
+ end
+ )
+ end
+ )
+end
+
+
+local update_title = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata' |
+ egrep -A 1 "title" | egrep -v "title" | awk -F '"' '{print $2}'
+ ]],
+ function(stdout)
+
+ local title = stdout:gsub('%\n', '')
+
+ local title_widget = song_info.music_title
+
+ local title_text = song_info.music_title:get_children_by_id('title')[1]
+
+ title_text:set_text(title)
+
+ title_widget:emit_signal("widget::redraw_needed")
+ title_widget:emit_signal("widget::layout_changed")
+
+ collectgarbage('collect')
+ end
+ )
+end
+
+
+local update_artist = function()
+
+
+ awful.spawn.easy_async_with_shell(
+ [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|
+ egrep -A 2 "artist" | egrep -v "artist" | egrep -v "array" | awk -F '"' '{print $2}'
+ ]],
+ function(stdout)
+
+ -- Remove new lines
+ local artist = stdout:gsub('%\n', '')
+
+ if (stdout == nil or stdout == '') then
+ artist = 'Advertisement'
+ end
+
+ local artist_widget = song_info.music_artist
+
+ local artist_text = artist_widget:get_children_by_id('artist')[1]
+
+ artist_text:set_text(artist)
+
+ artist_widget:emit_signal("widget::redraw_needed")
+ artist_widget:emit_signal("widget::layout_changed")
+
+ collectgarbage('collect')
+ end
+ )
+end
+
+
+local update_volume_slider = function()
+
+-- Stop. Don't indent.
+-- It's python. Nuff said
+ local get_volume = [[
+python - < 100:
+ arg = 100
+ subprocess.run(['pactl', 'set-sink-input-volume', sink_id, str(arg) + '%'])
+
+END
+ ]]
+
+ awful.spawn.easy_async_with_shell(
+ set_volume,
+ function(stdout) end
+ )
+
+end
+
+
+vol_slider.vol_slider:connect_signal(
+ 'property::value',
+ function()
+ local volume_slider = vol_slider.vol_slider
+ set_spotify_volume(tostring(volume_slider:get_value()))
+ end
+)
+
+
+local update_all_content = function()
+ -- Add a delay
+ gears.timer.start_new(2, function()
+ update_title()
+ update_artist()
+ update_cover()
+ check_if_playing()
+ update_volume_slider()
+ end)
+end
+
+
+update_all_content()
+
+
+media_buttons.play_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause
+ ]],
+ function()
+ check_if_playing()
+ end
+ )
+ end
+ )
+ )
+)
+
+
+media_buttons.next_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next
+ ]],
+ function()
+ update_all_content()
+ end
+ )
+ end
+ )
+ )
+)
+
+
+media_buttons.prev_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous
+ ]],
+ function()
+ update_all_content()
+ end
+ )
+ end
+ )
+ )
+)
\ No newline at end of file
diff --git a/.config/awesome/widget/network/icons/airplane-mode-off.svg b/.config/awesome/widget/network/icons/airplane-mode-off.svg
new file mode 100644
index 0000000..7a4c91c
--- /dev/null
+++ b/.config/awesome/widget/network/icons/airplane-mode-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/icons/airplane-mode.svg b/.config/awesome/widget/network/icons/airplane-mode.svg
new file mode 100644
index 0000000..70fc89d
--- /dev/null
+++ b/.config/awesome/widget/network/icons/airplane-mode.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/widget/network/icons/loading.svg b/.config/awesome/widget/network/icons/loading.svg
new file mode 100755
index 0000000..cd7bc0e
--- /dev/null
+++ b/.config/awesome/widget/network/icons/loading.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-off.svg b/.config/awesome/widget/network/icons/wifi-off.svg
new file mode 100755
index 0000000..dbcbc7a
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-off.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg
new file mode 100755
index 0000000..7a8de11
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg
new file mode 100755
index 0000000..9bcf910
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-1.svg b/.config/awesome/widget/network/icons/wifi-strength-1.svg
new file mode 100755
index 0000000..9e90049
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-1.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg
new file mode 100755
index 0000000..970987a
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg
new file mode 100755
index 0000000..cbedd27
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-2.svg b/.config/awesome/widget/network/icons/wifi-strength-2.svg
new file mode 100755
index 0000000..e65871e
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-2.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg
new file mode 100755
index 0000000..e1b5a5f
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg
new file mode 100755
index 0000000..865d01a
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-3.svg b/.config/awesome/widget/network/icons/wifi-strength-3.svg
new file mode 100755
index 0000000..cec90d5
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-3.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg
new file mode 100755
index 0000000..2d9d47d
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg
new file mode 100755
index 0000000..fb51f35
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-4.svg b/.config/awesome/widget/network/icons/wifi-strength-4.svg
new file mode 100755
index 0000000..259a3a9
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-4.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg
new file mode 100755
index 0000000..3e4c33a
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/network/icons/wifi-strength-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-alert.svg
new file mode 100755
index 0000000..ca80f6c
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-alert.svg
@@ -0,0 +1,65 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-empty.svg b/.config/awesome/widget/network/icons/wifi-strength-empty.svg
new file mode 100755
index 0000000..0a1380a
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-empty.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg
new file mode 100755
index 0000000..3edc636
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg
new file mode 100755
index 0000000..2f9b636
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/network/icons/wifi-strength-off.svg b/.config/awesome/widget/network/icons/wifi-strength-off.svg
new file mode 100755
index 0000000..12cb043
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-off.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wifi-strength-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-outline.svg
new file mode 100755
index 0000000..00fcd26
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi-strength-outline.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/network/icons/wifi.svg b/.config/awesome/widget/network/icons/wifi.svg
new file mode 100755
index 0000000..7887868
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wifi.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/.config/awesome/widget/network/icons/wired-alert.svg b/.config/awesome/widget/network/icons/wired-alert.svg
new file mode 100755
index 0000000..60ad378
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wired-alert.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wired-off.svg b/.config/awesome/widget/network/icons/wired-off.svg
new file mode 100755
index 0000000..35481c0
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wired-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/icons/wired.svg b/.config/awesome/widget/network/icons/wired.svg
new file mode 100755
index 0000000..00441ac
--- /dev/null
+++ b/.config/awesome/widget/network/icons/wired.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/network/init.lua b/.config/awesome/widget/network/init.lua
new file mode 100755
index 0000000..105dd50
--- /dev/null
+++ b/.config/awesome/widget/network/init.lua
@@ -0,0 +1,358 @@
+----------------------------------------------------------------------------
+--- Simple Network Widget
+--
+-- Depends: iproute2, iw
+--
+--
+-- @author manilarome <gerome.matilla07@gmail.com>
+-- @copyright 2020 manilarome
+-- @widget network
+----------------------------------------------------------------------------
+
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local naughty = require('naughty')
+local dpi = require('beautiful').xresources.apply_dpi
+local apps = require('configuration.apps')
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/network/icons/'
+local config = require('configuration.config')
+
+-- Configuration
+local interfaces = {
+ wlan_interface = config.widget.network.wireless_interface or 'wlan0',
+ lan_interface = config.widget.network.wired_interface or 'enp0s25'
+}
+
+local network_mode = nil
+
+local return_button = function()
+
+ local update_notify_no_access = true
+ local notify_no_access_quota = 0
+
+ local startup = true
+ local reconnect_startup = true
+ local notify_new_wifi_conn = false
+
+ local widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'wifi-strength-off' .. '.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn(apps.default.network_manager, false)
+ end
+ )
+ )
+ )
+
+ local network_tooltip = awful.tooltip {
+ text = 'Loading...',
+ objects = {widget_button},
+ mode = 'outside',
+ align = 'right',
+ preferred_positions = {'left', 'right', 'top', 'bottom'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8)
+ }
+
+ local check_internet_health = [=[
+ status_ping=0
+
+ packets="$(ping -q -w2 -c2 1.1.1.1 | grep -o "100% packet loss")"
+ if [ ! -z "${packets}" ];
+ then
+ status_ping=0
+ else
+ status_ping=1
+ fi
+
+ if [ $status_ping -eq 0 ];
+ then
+ echo 'Connected but no internet'
+ fi
+ ]=]
+
+ -- Awesome/System startup
+ local update_startup = function()
+ if startup then
+ startup = false
+ end
+ end
+
+ -- Consider reconnecting a startup
+ local update_reconnect_startup = function(status)
+ reconnect_startup = status
+ end
+
+ -- Update tooltip
+ local update_tooltip = function(message)
+ network_tooltip:set_markup(message)
+ end
+
+ local network_notify = function(message, title, app_name, icon)
+ naughty.notification({
+ message = message,
+ title = title,
+ app_name = app_name,
+ icon = icon
+ })
+ end
+
+ -- Wireless mode / Update
+ local update_wireless = function()
+
+ network_mode = 'wireless'
+
+ -- Create wireless connection notification
+ local notify_connected = function(essid)
+ local message = 'You are now connected to \"' .. essid .. '\"'
+ local title = 'Connection Established'
+ local app_name = 'System Notification'
+ local icon = widget_icon_dir .. 'wifi.svg'
+ network_notify(message, title, app_name, icon)
+ end
+
+ -- Get wifi essid and bitrate
+ local update_wireless_data = function(strength, healthy)
+ awful.spawn.easy_async_with_shell(
+ [[
+ iw dev ]] .. interfaces.wlan_interface .. [[ link
+ ]],
+ function(stdout)
+ local essid = stdout:match('SSID: (.-)\n') or 'N/A'
+ local bitrate = stdout:match('tx bitrate: (.+/s)') or 'N/A'
+ local message = 'Connected to: ' .. (essid or 'Loading...*') ..
+ '\nWireless Interface: ' .. interfaces.wlan_interface ..
+ '\nWiFi-Strength: ' .. tostring(wifi_strength) .. '%' ..
+ '\nBit rate: ' .. tostring(bitrate) .. ''
+
+ if healthy then
+ update_tooltip(message)
+ else
+ update_tooltip('Connected but no internet!\n' .. message)
+ end
+
+ if reconnect_startup or startup then
+ notify_connected(essid)
+ update_reconnect_startup(false)
+ end
+ end
+ )
+ end
+
+ -- Update wifi icon based on wifi strength and health
+ local update_wireless_icon = function(strength)
+ awful.spawn.easy_async_with_shell(
+ check_internet_health,
+ function(stdout)
+ local widget_icon_name = 'wifi-strength'
+ if not stdout:match('Connected but no internet') then
+ if startup or reconnect_startup then
+ awesome.emit_signal('system::network_connected')
+ end
+ widget_icon_name = widget_icon_name .. '-' .. tostring(strength)
+ update_wireless_data(wifi_strength_rounded, true)
+ else
+ widget_icon_name = widget_icon_name .. '-' .. tostring(strength) .. '-alert'
+ update_wireless_data(wifi_strength_rounded, false)
+ end
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+ )
+ end
+
+ -- Get wifi strength
+ local update_wireless_strength = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ awk 'NR==3 {printf "%3.0f" ,($3/70)*100}' /proc/net/wireless
+ ]],
+ function(stdout)
+ if not tonumber(stdout) then
+ return
+ end
+ wifi_strength = tonumber(stdout)
+ local wifi_strength_rounded = math.floor(wifi_strength / 25 + 0.5)
+ update_wireless_icon(wifi_strength_rounded)
+ end
+ )
+ end
+
+ update_wireless_strength()
+ update_startup()
+ end
+
+ local update_wired = function()
+
+ network_mode = 'wired'
+
+ local notify_connected = function()
+ local message = 'Connected to internet with \"' .. interfaces.lan_interface .. '\"'
+ local title = 'Connection Established'
+ local app_name = 'System Notification'
+ local icon = widget_icon_dir .. 'wired.svg'
+ network_notify(message, title, app_name, icon)
+ end
+
+ awful.spawn.easy_async_with_shell(
+ check_internet_health,
+ function(stdout)
+
+ local widget_icon_name = 'wired'
+
+ if stdout:match('Connected but no internet') then
+ widget_icon_name = widget_icon_name .. '-alert'
+ update_tooltip(
+ 'Connected but no internet!' ..
+ '\nEthernet Interface: ' .. interfaces.lan_interface .. ''
+ )
+ else
+ update_tooltip('Ethernet Interface: ' .. interfaces.lan_interface .. '')
+ if startup or reconnect_startup then
+ awesome.emit_signal('system::network_connected')
+ notify_connected()
+ update_startup(false)
+ end
+ update_reconnect_startup(false)
+ end
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+ )
+ end
+
+ local update_disconnected = function()
+
+ local notify_wireless_disconnected = function(essid)
+ local message = 'Wi-Fi network has been disconnected'
+ local title = 'Connection Disconnected'
+ local app_name = 'System Notification'
+ local icon = widget_icon_dir .. 'wifi-strength-off.svg'
+ network_notify(message, title, app_name, icon)
+ end
+
+ local notify_wired_disconnected = function(essid)
+ local message = 'Ethernet network has been disconnected'
+ local title = 'Connection Disconnected'
+ local app_name = 'System Notification'
+ local icon = widget_icon_dir .. 'wired-off.svg'
+ network_notify(message, title, app_name, icon)
+ end
+
+ local widget_icon_name = 'wifi-strength-off'
+
+ if network_mode == 'wireless' then
+ widget_icon_name = 'wifi-strength-off'
+ if not reconnect_startup then
+ update_reconnect_startup(true)
+ notify_wireless_disconnected()
+ end
+ elseif network_mode == 'wired' then
+ widget_icon_name = 'wired-off'
+ if not reconnect_startup then
+ update_reconnect_startup(true)
+ notify_wired_disconnected()
+ end
+ end
+ update_tooltip('Network is currently disconnected')
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+
+ local check_network_mode = function()
+ awful.spawn.easy_async_with_shell(
+ [=[
+ wireless="]=] .. tostring(interfaces.wlan_interface) .. [=["
+ wired="]=] .. tostring(interfaces.lan_interface) .. [=["
+ net="/sys/class/net/"
+
+ wired_state="down"
+ wireless_state="down"
+ network_mode=""
+
+ # Check network state based on interface's operstate value
+ function check_network_state() {
+ # Check what interface is up
+ if [[ "${wireless_state}" == "up" ]];
+ then
+ network_mode='wireless'
+ elif [[ "${wired_state}" == "up" ]];
+ then
+ network_mode='wired'
+ else
+ network_mode='No internet connection'
+ fi
+ }
+
+ # Check if network directory exist
+ function check_network_directory() {
+ if [[ -n "${wireless}" && -d "${net}${wireless}" ]];
+ then
+ wireless_state="$(cat "${net}${wireless}/operstate")"
+ fi
+ if [[ -n "${wired}" && -d "${net}${wired}" ]]; then
+ wired_state="$(cat "${net}${wired}/operstate")"
+ fi
+ check_network_state
+ }
+
+ # Start script
+ function print_network_mode() {
+ # Call to check network dir
+ check_network_directory
+ # Print network mode
+ printf "${network_mode}"
+ }
+
+ print_network_mode
+
+ ]=],
+ function(stdout)
+ local mode = stdout:gsub('%\n', '')
+ if stdout:match('No internet connection') then
+ update_disconnected()
+ elseif stdout:match('wireless') then
+ update_wireless()
+ elseif stdout:match('wired') then
+ update_wired()
+ end
+ end
+ )
+ end
+
+ local network_updater = gears.timer {
+ timeout = 5,
+ autostart = true,
+ call_now = true,
+ callback = function()
+ check_network_mode()
+ end
+ }
+
+ return widget_button
+end
+
+return return_button
diff --git a/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua b/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua
new file mode 100644
index 0000000..447f95d
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua
@@ -0,0 +1,65 @@
+-- This returns the "Wow, such empty." message.
+
+local wibox = require('wibox')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = require('gears').filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/notif-center/icons/'
+
+local empty_notifbox = wibox.widget {
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ nil,
+ {
+ image = widget_icon_dir .. 'empty-notification' .. '.svg',
+ resize = true,
+ forced_height = dpi(35),
+ forced_width = dpi(35),
+ widget = wibox.widget.imagebox,
+ },
+ nil
+ },
+ {
+ text = 'Wow, such empty.',
+ font = 'Inter Bold 14',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ {
+ text = 'Come back later.',
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ },
+ margins = dpi(20),
+ widget = wibox.container.margin
+
+}
+
+
+local separator_for_empty_msg = wibox.widget
+{
+ orientation = 'vertical',
+ opacity = 0.0,
+ widget = wibox.widget.separator
+}
+
+-- Make empty_notifbox center
+local centered_empty_notifbox = wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.align.vertical,
+ separator_for_empty_msg,
+ empty_notifbox,
+ separator_for_empty_msg
+}
+
+return centered_empty_notifbox
+
diff --git a/.config/awesome/widget/notif-center/build-notifbox/init.lua b/.config/awesome/widget/notif-center/build-notifbox/init.lua
new file mode 100644
index 0000000..c4aa484
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/init.lua
@@ -0,0 +1,80 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/notif-center/icons/'
+
+local empty_notifbox = require('widget.notif-center.build-notifbox.empty-notifbox')
+local notifbox_scroller = require('widget.notif-center.build-notifbox.notifbox-scroller')
+
+local notif_core = {}
+
+notif_core.remove_notifbox_empty = true
+
+notif_core.notifbox_layout = wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(7),
+ empty_notifbox
+}
+
+notifbox_scroller(notif_core.notifbox_layout)
+
+notif_core.reset_notifbox_layout = function()
+ notif_core.notifbox_layout:reset()
+ notif_core.notifbox_layout:insert(1, empty_notifbox)
+ notif_core.remove_notifbox_empty = true
+end
+
+local notifbox_add = function(n, notif_icon, notifbox_color)
+ if #notif_core.notifbox_layout.children == 1 and notif_core.remove_notifbox_empty then
+ notif_core.notifbox_layout:reset(notif_core.notifbox_layout)
+ notif_core.remove_notifbox_empty = false
+ end
+
+ local notifbox_box = require('widget.notif-center.build-notifbox.notifbox-builder')
+ notif_core.notifbox_layout:insert(
+ 1,
+ notifbox_box(
+ n,
+ notif_icon,
+ n.title,
+ n.message,
+ n.app_name,
+ notifbox_color
+ )
+ )
+end
+
+local notifbox_add_expired = function(n, notif_icon, notifbox_color)
+ n:connect_signal(
+ 'destroyed',
+ function(self, reason, keep_visble)
+ if reason == 1 then
+ notifbox_add(n, notif_icon, notifbox_color)
+ end
+ end
+ )
+end
+
+naughty.connect_signal(
+ 'request::display',
+ function(n)
+ local notifbox_color = beautiful.groups_bg
+ if n.urgency == 'critical' then
+ notifbox_color = n.bg .. '66'
+ end
+
+ local notif_icon = n.icon or n.app_icon
+ if not notif_icon then
+ notif_icon = widget_icon_dir .. 'new-notif' .. '.svg'
+ end
+
+ notifbox_add_expired(n, notif_icon, notifbox_color)
+ end
+)
+
+return notif_core
diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua
new file mode 100644
index 0000000..e721232
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua
@@ -0,0 +1,177 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local builder = require('widget.notif-center.build-notifbox.notifbox-ui-elements')
+local notifbox_core = require('widget.notif-center.build-notifbox')
+
+local notifbox_layout = notifbox_core.notifbox_layout
+local remove_notifbox_empty = notifbox_core.remove_notifbox_empty
+local reset_notifbox_layout = notifbox_core.reset_notifbox_layout
+
+local return_date_time = function(format)
+ return os.date(format)
+end
+
+local parse_to_seconds = function(time)
+ local hourInSec = tonumber(string.sub(time, 1, 2)) * 3600
+ local minInSec = tonumber(string.sub(time, 4, 5)) * 60
+ local getSec = tonumber(string.sub(time, 7, 8))
+ return (hourInSec + minInSec + getSec)
+end
+
+notifbox_box = function(notif, icon, title, message, app, bgcolor)
+
+ local time_of_pop = return_date_time('%H:%M:%S')
+ local exact_time = return_date_time('%I:%M %p')
+ local exact_date_time = return_date_time('%b %d, %I:%M %p')
+
+ local notifbox_timepop = wibox.widget {
+ id = 'time_pop',
+ markup = nil,
+ font = 'Inter Regular 10',
+ align = 'left',
+ valign = 'center',
+ visible = true,
+ widget = wibox.widget.textbox
+ }
+
+ local notifbox_dismiss = builder.notifbox_dismiss()
+
+ local time_of_popup = gears.timer {
+ timeout = 60,
+ call_now = true,
+ autostart = true,
+ callback = function()
+
+ local time_difference = nil
+
+ time_difference = parse_to_seconds(return_date_time('%H:%M:%S')) - parse_to_seconds(time_of_pop)
+ time_difference = tonumber(time_difference)
+
+ if time_difference < 60 then
+ notifbox_timepop:set_markup('now')
+
+ elseif time_difference >= 60 and time_difference < 3600 then
+ local time_in_minutes = math.floor(time_difference / 60)
+ notifbox_timepop:set_markup(time_in_minutes .. 'm ago')
+
+ elseif time_difference >= 3600 and time_difference < 86400 then
+ notifbox_timepop:set_markup(exact_time)
+
+ elseif time_difference >= 86400 then
+ notifbox_timepop:set_markup(exact_date_time)
+ return false
+
+ end
+
+ collectgarbage('collect')
+ end
+ }
+
+ local notifbox_template = wibox.widget {
+ id = 'notifbox_template',
+ expand = 'none',
+ {
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(5),
+ builder.notifbox_icon(icon),
+ builder.notifbox_appname(app),
+ },
+ nil,
+ {
+ notifbox_timepop,
+ notifbox_dismiss,
+ layout = wibox.layout.fixed.horizontal
+ }
+ },
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ builder.notifbox_title(title),
+ builder.notifbox_message(message),
+ layout = wibox.layout.fixed.vertical
+ },
+ builder.notifbox_actions(notif),
+ },
+
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ bg = bgcolor,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background,
+ }
+
+ -- Put the generated template to a container
+ local notifbox = wibox.widget {
+ notifbox_template,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+
+ -- Delete notification box
+ local notifbox_delete = function()
+ notifbox_layout:remove_widgets(notifbox, true)
+ end
+
+ -- Delete notifbox on LMB
+ notifbox:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ if #notifbox_layout.children == 1 then
+ reset_notifbox_layout()
+ else
+ notifbox_delete()
+ end
+ collectgarbage('collect')
+ end
+ )
+ )
+ )
+
+ -- Add hover, and mouse leave events
+ notifbox_template:connect_signal(
+ 'mouse::enter',
+ function()
+ notifbox.bg = beautiful.groups_bg
+ notifbox_timepop.visible = false
+ notifbox_dismiss.visible = true
+ end
+ )
+
+ notifbox_template:connect_signal(
+ 'mouse::leave',
+ function()
+ notifbox.bg = beautiful.tranparent
+ notifbox_timepop.visible = true
+ notifbox_dismiss.visible = false
+ end
+ )
+
+ collectgarbage('collect')
+
+ return notifbox
+end
+
+
+return notifbox_box
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua
new file mode 100644
index 0000000..3fe79da
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua
@@ -0,0 +1,33 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+
+local find_widget_in_wibox = function(wb, widget)
+ local function find_widget_in_hierarchy(h, widget)
+ if h:get_widget() == widget then
+ return h
+ end
+ local result
+
+ for _, ch in ipairs(h:get_children()) do
+ result = result or find_widget_in_hierarchy(ch, widget)
+ end
+ return result
+ end
+ local h = wb._drawable._widget_hierarchy
+ return h and find_widget_in_hierarchy(h, widget)
+end
+
+
+local focused = awful.screen.focused()
+local h = find_widget_in_wibox(focused.top_panel, focused.music)
+local x, y, width, height = h:get_matrix_to_device():transform_rectangle(0, 0, h:get_size())
+-- local geo = focused.mywibox:geometry()
+
+
+-- x, y = x + geo.x, y + geo.y
+
+-- print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height)
+
+
+naughty.notification({message=tostring(height)})
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua
new file mode 100644
index 0000000..f05d323
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua
@@ -0,0 +1,37 @@
+local awful = require('awful')
+local gears = require('gears')
+
+local add_button_event = function(widget)
+
+ widget:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 4,
+ nil,
+ function()
+ if #widget.children == 1 then
+ return
+ end
+ widget:insert(1, widget.children[#widget.children])
+ widget:remove(#widget.children)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ nil,
+ function()
+ if #widget.children == 1 then
+ return
+ end
+ widget:insert(#widget.children + 1, widget.children[1])
+ widget:remove(1)
+ end
+ )
+ )
+ )
+
+end
+
+return add_button_event
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua
new file mode 100644
index 0000000..ef5e574
--- /dev/null
+++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua
@@ -0,0 +1,136 @@
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/notif-center/icons/'
+
+local clickable_container = require('widget.clickable-container')
+
+local ui_noti_builder = {}
+
+-- Notification icon container
+ui_noti_builder.notifbox_icon = function(ico_image)
+ local noti_icon = wibox.widget {
+ {
+ id = 'icon',
+ resize = true,
+ forced_height = dpi(25),
+ forced_width = dpi(25),
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.fixed.horizontal
+ }
+ noti_icon.icon:set_image(ico_image)
+ return noti_icon
+end
+
+-- Notification title container
+ui_noti_builder.notifbox_title = function(title)
+ return wibox.widget {
+ markup = title,
+ font = 'Inter Bold 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+end
+
+-- Notification message container
+ui_noti_builder.notifbox_message = function(msg)
+ return wibox.widget {
+ markup = msg,
+ font = 'Inter Regular 11',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+end
+
+-- Notification app name container
+ui_noti_builder.notifbox_appname = function(app)
+ return wibox.widget {
+ markup = app,
+ font = 'Inter Bold 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+end
+
+-- Notification actions container
+ui_noti_builder.notifbox_actions = function(n)
+ actions_template = wibox.widget {
+ notification = n,
+ base_layout = wibox.widget {
+ spacing = dpi(0),
+ layout = wibox.layout.flex.horizontal
+ },
+ widget_template = {
+ {
+ {
+ {
+ {
+ id = 'text_role',
+ font = 'Inter Regular 10',
+ widget = wibox.widget.textbox
+ },
+ widget = wibox.container.place
+ },
+ widget = clickable_container
+ },
+ bg = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ forced_height = 30,
+ widget = wibox.container.background
+ },
+ margins = 4,
+ widget = wibox.container.margin
+ },
+ style = { underline_normal = false, underline_selected = true },
+ widget = naughty.list.actions,
+ }
+
+ return actions_template
+end
+
+
+-- Notification dismiss button
+ui_noti_builder.notifbox_dismiss = function()
+
+ local dismiss_imagebox = wibox.widget {
+ {
+ id = 'dismiss_icon',
+ image = widget_icon_dir .. 'delete.svg',
+ resize = true,
+ forced_height = dpi(5),
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.fixed.horizontal
+ }
+
+ local dismiss_button = wibox.widget {
+ {
+ dismiss_imagebox,
+ margins = dpi(5),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ local notifbox_dismiss = wibox.widget {
+ dismiss_button,
+ visible = false,
+ bg = beautiful.groups_title_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ }
+
+ return notifbox_dismiss
+end
+
+
+return ui_noti_builder
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/clear-all/init.lua b/.config/awesome/widget/notif-center/clear-all/init.lua
new file mode 100644
index 0000000..7c14657
--- /dev/null
+++ b/.config/awesome/widget/notif-center/clear-all/init.lua
@@ -0,0 +1,61 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/notif-center/icons/'
+
+local notifbox_core = require('widget.notif-center.build-notifbox')
+local reset_notifbox_layout = notifbox_core.reset_notifbox_layout
+
+local clear_all_imagebox = wibox.widget {
+ {
+ image = widget_icon_dir .. 'clear_all.svg',
+ resize = true,
+ forced_height = dpi(20),
+ forced_width = dpi(20),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local clear_all_button = wibox.widget {
+ {
+ clear_all_imagebox,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+clear_all_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ reset_notifbox_layout()
+ end
+ )
+ )
+)
+
+local clear_all_button_wrapped = wibox.widget {
+ nil,
+ {
+ clear_all_button,
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+return clear_all_button_wrapped
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/dont-disturb/disturb_status b/.config/awesome/widget/notif-center/dont-disturb/disturb_status
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/.config/awesome/widget/notif-center/dont-disturb/disturb_status
@@ -0,0 +1 @@
+false
diff --git a/.config/awesome/widget/notif-center/dont-disturb/init.lua b/.config/awesome/widget/notif-center/dont-disturb/init.lua
new file mode 100644
index 0000000..b135b65
--- /dev/null
+++ b/.config/awesome/widget/notif-center/dont-disturb/init.lua
@@ -0,0 +1,122 @@
+local awful = require('awful')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+
+local widget_dir = config_dir .. 'widget/notif-center/dont-disturb/'
+local widget_icon_dir = config_dir .. 'widget/notif-center/icons/'
+
+_G.dont_disturb = false
+
+local dont_disturb_imagebox = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'dont-disturb-mode.svg',
+ resize = true,
+ forced_height = dpi(20),
+ forced_width = dpi(20),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local function update_icon()
+
+ local widget_icon_name = nil
+ local dd_icon = dont_disturb_imagebox.icon
+
+ if dont_disturb then
+ widget_icon_name = 'toggled-on'
+ dd_icon:set_image(widget_icon_dir .. 'dont-disturb-mode.svg')
+ else
+ widget_icon_name = 'toggled-off'
+ dd_icon:set_image(widget_icon_dir .. 'notify-mode.svg')
+ end
+end
+
+local check_disturb_status = function()
+
+ awful.spawn.easy_async_with_shell(
+ 'cat ' .. widget_dir .. 'disturb_status',
+ function(stdout)
+
+ local status = stdout
+
+ if status:match('true') then
+ dont_disturb = true
+ elseif status:match('false') then
+ dont_disturb = false
+ else
+ dont_disturb = false
+ awful.spawn.with_shell('echo "false" > ' .. widget_dir .. 'disturb_status')
+ end
+
+ update_icon()
+ end
+ )
+end
+
+check_disturb_status()
+
+local toggle_disturb = function()
+ if dont_disturb then
+ dont_disturb = false
+ else
+ dont_disturb = true
+ end
+ awful.spawn.with_shell('echo "' .. tostring(dont_disturb) .. '" > ' .. widget_dir .. 'disturb_status')
+ update_icon()
+end
+
+local dont_disturb_button = wibox.widget {
+ {
+ dont_disturb_imagebox,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+dont_disturb_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ toggle_disturb()
+ end
+ )
+ )
+)
+
+local dont_disturb_wrapped = wibox.widget {
+ nil,
+ {
+ dont_disturb_button,
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+-- Create a notification sound
+naughty.connect_signal(
+ 'request::display',
+ function(n)
+ if not dont_disturb then
+ awful.spawn.with_shell('canberra-gtk-play -i message')
+ end
+ end
+)
+
+return dont_disturb_wrapped
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/icons/clear_all.svg b/.config/awesome/widget/notif-center/icons/clear_all.svg
new file mode 100644
index 0000000..3f5b9b4
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/clear_all.svg
@@ -0,0 +1,91 @@
+
+
+
+
diff --git a/.config/awesome/widget/notif-center/icons/delete.svg b/.config/awesome/widget/notif-center/icons/delete.svg
new file mode 100644
index 0000000..3f1f88c
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/delete.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg b/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg
new file mode 100644
index 0000000..d5dc170
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg
@@ -0,0 +1,64 @@
+
+
diff --git a/.config/awesome/widget/notif-center/icons/empty-notification.svg b/.config/awesome/widget/notif-center/icons/empty-notification.svg
new file mode 100644
index 0000000..df4154c
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/empty-notification.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.config/awesome/widget/notif-center/icons/new-notif.svg b/.config/awesome/widget/notif-center/icons/new-notif.svg
new file mode 100644
index 0000000..630b90a
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/new-notif.svg
@@ -0,0 +1,15 @@
+
diff --git a/.config/awesome/widget/notif-center/icons/notify-mode.svg b/.config/awesome/widget/notif-center/icons/notify-mode.svg
new file mode 100644
index 0000000..92b960b
--- /dev/null
+++ b/.config/awesome/widget/notif-center/icons/notify-mode.svg
@@ -0,0 +1,91 @@
+
+
diff --git a/.config/awesome/widget/notif-center/init.lua b/.config/awesome/widget/notif-center/init.lua
new file mode 100644
index 0000000..bdc544b
--- /dev/null
+++ b/.config/awesome/widget/notif-center/init.lua
@@ -0,0 +1,38 @@
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local notif_header = wibox.widget {
+ text = 'Notification Center',
+ font = 'Inter Bold 16',
+ align = 'left',
+ valign = 'bottom',
+ widget = wibox.widget.textbox
+}
+
+local notif_center = function(s)
+
+ s.dont_disturb = require('widget.notif-center.dont-disturb')
+ s.clear_all = require('widget.notif-center.clear-all')
+ s.notifbox_layout = require('widget.notif-center.build-notifbox').notifbox_layout
+
+ return wibox.widget {
+ expand = 'none',
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(10),
+ {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ notif_header,
+ nil,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(5),
+ s.dont_disturb,
+ s.clear_all
+ },
+ },
+ s.notifbox_layout
+ }
+end
+
+return notif_center
\ No newline at end of file
diff --git a/.config/awesome/widget/open-default-app/init.lua b/.config/awesome/widget/open-default-app/init.lua
new file mode 100644
index 0000000..bb7ac8a
--- /dev/null
+++ b/.config/awesome/widget/open-default-app/init.lua
@@ -0,0 +1,52 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+local create_open_default_button = function(s)
+ s.add_button = wibox.widget {
+ {
+ {
+ {
+ {
+ image = icons.plus,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ margins = dpi(4),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ bg = beautiful.transparent,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ },
+ margins = dpi(4),
+ widget = wibox.container.margin
+ }
+
+ s.add_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn(
+ awful.screen.focused().selected_tag.default_app,
+ {
+ tag = mouse.screen.selected_tag
+ }
+ )
+ end
+ )
+ )
+ )
+ return s.add_button
+end
+
+return create_open_default_button
diff --git a/.config/awesome/widget/package-updater/icons/package-up.svg b/.config/awesome/widget/package-updater/icons/package-up.svg
new file mode 100644
index 0000000..2251baa
--- /dev/null
+++ b/.config/awesome/widget/package-updater/icons/package-up.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/package-updater/icons/package.svg b/.config/awesome/widget/package-updater/icons/package.svg
new file mode 100644
index 0000000..7d4b2f9
--- /dev/null
+++ b/.config/awesome/widget/package-updater/icons/package.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/package-updater/init.lua b/.config/awesome/widget/package-updater/init.lua
new file mode 100644
index 0000000..2f52244
--- /dev/null
+++ b/.config/awesome/widget/package-updater/init.lua
@@ -0,0 +1,105 @@
+local awful = require('awful')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local gears = require('gears')
+
+local watch = awful.widget.watch
+
+local apps = require('configuration.apps')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/package-updater/icons/'
+
+local update_available = false
+local number_of_updates_available = nil
+local update_package = nil
+
+local return_button = function()
+
+ local widget = wibox.widget {
+ {
+ id = 'icon',
+ widget = wibox.widget.imagebox,
+ image = widget_icon_dir .. 'package.svg',
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+
+ if update_available then
+ awful.spawn(apps.default.package_manager .. ' --updates', false)
+
+ else
+ awful.spawn(apps.default.package_manager, false)
+
+ end
+ end
+ )
+ )
+ )
+
+ awful.tooltip(
+ {
+ objects = {widget_button},
+ mode = 'outside',
+ align = 'right',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ timer_function = function()
+
+ if update_available then
+ return update_package:gsub('\n$', '')
+ else
+ return 'We are up-to-date!'
+ end
+
+ end,
+ preferred_positions = {'right', 'left', 'top', 'bottom'}
+ }
+ )
+
+ watch(
+ 'pamac checkupdates',
+ 60,
+ function(_, stdout)
+ number_of_updates_available = tonumber(stdout:match('.-\n'):match('%d*'))
+ update_package = stdout
+ local icon_name = nil
+ if number_of_updates_available ~= nil then
+ update_available = true
+ icon_name = 'package-up'
+ else
+ update_available = false
+ icon_name = 'package'
+
+ end
+
+ widget.icon:set_image(widget_icon_dir .. icon_name .. '.svg')
+ collectgarbage('collect')
+ end
+ )
+
+ return widget_button
+end
+
+return return_button
diff --git a/.config/awesome/widget/ram-meter/init.lua b/.config/awesome/widget/ram-meter/init.lua
new file mode 100644
index 0000000..c630e81
--- /dev/null
+++ b/.config/awesome/widget/ram-meter/init.lua
@@ -0,0 +1,60 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local watch = require('awful.widget.watch')
+local icons = require('theme.icons')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'ram_usage',
+ max_value = 100,
+ value = 29,
+ forced_height = dpi(2),
+ color = beautiful.fg_normal,
+ background_color = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.widget.progressbar
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+watch(
+ 'bash -c "free | grep -z Mem.*Swap.*"',
+ 10,
+ function(_, stdout)
+ local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap =
+ stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)')
+ slider.ram_usage:set_value(used / total * 100)
+ collectgarbage('collect')
+ end
+)
+
+local ram_meter = wibox.widget {
+ {
+ {
+ {
+ image = icons.memory,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return ram_meter
diff --git a/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua b/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua
new file mode 100644
index 0000000..5fe2e4b
--- /dev/null
+++ b/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua
@@ -0,0 +1,63 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local watch = require('awful.widget.watch')
+local icons = require('theme.icons')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'temp_status',
+ max_value = 100,
+ value = 29,
+ forced_height = dpi(2),
+ color = beautiful.fg_normal,
+ background_color = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.widget.progressbar
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+local max_temp = 80
+
+watch(
+ 'bash -c "cat /sys/class/thermal/thermal_zone0/temp"',
+ 5,
+ function(_, stdout)
+ local temp = stdout:match('(%d+)')
+ slider.temp_status:set_value((temp / 1000) / max_temp * 100)
+ collectgarbage('collect')
+ end
+)
+
+
+local temperature_meter = wibox.widget {
+ {
+ {
+ {
+ image = icons.thermometer,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return temperature_meter
diff --git a/.config/awesome/widget/screen-recorder/icons/audio.svg b/.config/awesome/widget/screen-recorder/icons/audio.svg
new file mode 100644
index 0000000..2f8668f
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/audio.svg
@@ -0,0 +1,71 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/screen-recorder/icons/back.svg b/.config/awesome/widget/screen-recorder/icons/back.svg
new file mode 100644
index 0000000..f0e76e5
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/back.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/screen-recorder/icons/close-screen.svg b/.config/awesome/widget/screen-recorder/icons/close-screen.svg
new file mode 100644
index 0000000..3f1f88c
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/close-screen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg b/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg
new file mode 100644
index 0000000..63134d5
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-off.svg b/.config/awesome/widget/screen-recorder/icons/recorder-off.svg
new file mode 100644
index 0000000..8ade140
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/recorder-off.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-on.svg b/.config/awesome/widget/screen-recorder/icons/recorder-on.svg
new file mode 100644
index 0000000..29800ca
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/recorder-on.svg
@@ -0,0 +1,71 @@
+
+
+
+
diff --git a/.config/awesome/widget/screen-recorder/icons/recording-button.svg b/.config/awesome/widget/screen-recorder/icons/recording-button.svg
new file mode 100644
index 0000000..4caa7b3
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/recording-button.svg
@@ -0,0 +1,86 @@
+
+
\ No newline at end of file
diff --git a/.config/awesome/widget/screen-recorder/icons/settings.svg b/.config/awesome/widget/screen-recorder/icons/settings.svg
new file mode 100644
index 0000000..2c5a0b9
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/settings.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg b/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg
new file mode 100644
index 0000000..986f9dd
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg
@@ -0,0 +1,14 @@
+
+
diff --git a/.config/awesome/widget/screen-recorder/init.lua b/.config/awesome/widget/screen-recorder/init.lua
new file mode 100644
index 0000000..1dabee6
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/init.lua
@@ -0,0 +1,9 @@
+local recorder_table = require('widget.screen-recorder.screen-recorder-ui')
+require('widget.screen-recorder.screen-recorder-ui-backend')
+local screen_rec_toggle_button = recorder_table.screen_rec_toggle_button
+
+local return_button = function()
+ return screen_rec_toggle_button
+end
+
+return return_button
diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-config.lua b/.config/awesome/widget/screen-recorder/screen-recorder-config.lua
new file mode 100644
index 0000000..faf7593
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/screen-recorder-config.lua
@@ -0,0 +1,22 @@
+local user_preferences = {}
+local config = require('configuration.config')
+
+-- Screen WIDTHxHEIGHT
+user_preferences.user_resolution = config.widget.screen_recorder.resolution or '1366x768'
+
+-- Offset x,y
+user_preferences.user_offset = config.widget.screen_recorder.offset or '0,0'
+
+-- bool true or false
+user_preferences.user_audio = config.widget.screen_recorder.audio or false
+
+-- String $HOME
+user_preferences.user_save_directory = config.widget.screen_recorder.save_directory or '$(xdg-user-dir VIDEOS)/Recordings/'
+
+-- String
+user_preferences.user_mic_lvl = config.widget.screen_recorder.mic_level or '20'
+
+-- String
+user_preferences.user_fps = config.widget.screen_recorder.fps or '30'
+
+return user_preferences
diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua b/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua
new file mode 100644
index 0000000..b55ef0a
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua
@@ -0,0 +1,169 @@
+local awful = require('awful')
+local naughty = require('naughty')
+local user_config = require('widget.screen-recorder.screen-recorder-config')
+local scripts_tbl = {}
+local ffmpeg_pid = nil
+
+-- Get user settings
+scripts_tbl.user_resolution = user_config.user_resolution
+scripts_tbl.user_offset = user_config.user_offset
+scripts_tbl.user_audio = user_config.user_audio
+scripts_tbl.user_dir = user_config.user_save_directory
+scripts_tbl.user_mic_lvl = user_config.user_mic_lvl
+scripts_tbl.user_fps = user_config.user_fps
+
+scripts_tbl.update_user_settings = function(res, offset, audio)
+ scripts_tbl.user_resolution = res
+ scripts_tbl.user_offset = offset
+ scripts_tbl.user_audio = audio
+end
+
+scripts_tbl.check_settings = function()
+ -- For debugging purpose only
+ -- naughty.notification({
+ -- message=scripts_tbl.user_resolution .. ' ' .. scripts_tbl.user_offset .. tostring(scripts_tbl.user_audio)
+ -- })
+end
+
+local create_save_directory = function()
+
+ local create_dir_cmd = [[
+ dir="]] .. scripts_tbl.user_dir .. [["
+
+ if [ ! -d "$dir" ]; then
+ mkdir -p "$dir"
+ fi
+ ]]
+
+ awful.spawn.easy_async_with_shell(
+ create_dir_cmd,
+ function(stdout) end
+ )
+end
+
+create_save_directory()
+
+local kill_existing_recording_ffmpeg = function()
+ -- Let's killall ffmpeg instance first after awesome (re)-starts if there's any
+ awful.spawn.easy_async_with_shell(
+ [[
+ ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill
+ ]],
+ function(stdout) end
+ )
+end
+
+kill_existing_recording_ffmpeg()
+
+local turn_on_the_mic = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ amixer set Capture cap
+ amixer set Capture ]].. scripts_tbl.user_mic_lvl ..[[%
+ ]],
+ function() end
+ )
+end
+
+local ffmpeg_stop_recording = function()
+ -- Let's killall ffmpeg instance first after awesome (re)-starts if there's any
+ awful.spawn.easy_async_with_shell(
+ [[
+ ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill -2
+ ]],
+ function(stdout) end
+ )
+end
+
+local create_notification = function(file_dir)
+ local open_video = naughty.action {
+ name = 'Open',
+ icon_only = false,
+ }
+
+ local delete_video = naughty.action {
+ name = 'Delete',
+ icon_only = false,
+ }
+
+ open_video:connect_signal(
+ 'invoked',
+ function()
+ awful.spawn('xdg-open ' .. file_dir, false)
+ end
+ )
+
+ delete_video:connect_signal(
+ 'invoked',
+ function()
+ awful.spawn('gio trash ' .. file_dir, false)
+ end
+ )
+
+ naughty.notification ({
+ app_name = 'Screen Recorder',
+ timeout = 60,
+ title = 'Recording Finished!',
+ message = 'Recording can now be viewed.',
+ actions = { open_video, delete_video }
+ })
+end
+
+local ffmpeg_start_recording = function(audio, filename)
+ local add_audio_str = ' '
+
+ if audio then
+ turn_on_the_mic()
+ add_audio_str = '-f pulse -ac 2 -i default'
+ end
+
+ ffmpeg_pid = awful.spawn.easy_async_with_shell(
+ [[
+ file_name=]] .. filename .. [[
+
+ ffmpeg -video_size ]] .. scripts_tbl.user_resolution .. [[ -framerate ]] .. scripts_tbl.user_fps .. [[ -f x11grab \
+ -i :0.0+]] .. scripts_tbl.user_offset .. ' ' .. add_audio_str .. [[ -c:v libx264 -crf 20 -profile:v baseline -level 3.0 -pix_fmt yuv420p $file_name
+ ]],
+ function(stdout, stderr)
+ if stderr and stderr:match('Invalid argument') then
+ naughty.notification({
+ app_name = 'Screen Recorder',
+ title = 'Invalid Configuration!',
+ message = 'Please, put a valid settings!',
+ timeout = 60,
+ urgency = 'normal'
+ })
+ awesome.emit_signal('widget::screen_recorder')
+ return
+ end
+ create_notification(filename)
+ end
+ )
+end
+
+local create_unique_filename = function(audio)
+ awful.spawn.easy_async_with_shell(
+ [[
+ dir="]] .. scripts_tbl.user_dir .. [["
+ date=$(date '+%Y-%m-%d_%H-%M-%S')
+ format=.mp4
+
+ echo "${dir}${date}${format}" | tr -d '\n'
+ ]],
+ function(stdout)
+ local filename = stdout
+ ffmpeg_start_recording(audio, filename)
+ end
+ )
+end
+
+scripts_tbl.start_recording = function(audio_mode)
+ create_save_directory()
+ create_unique_filename(audio_mode)
+end
+
+scripts_tbl.stop_recording = function()
+ ffmpeg_stop_recording()
+end
+
+return scripts_tbl
diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua b/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua
new file mode 100644
index 0000000..2b03e31
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua
@@ -0,0 +1,454 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/screen-recorder/icons/'
+
+-- The screen-recorders scripting
+local screen_rec_backend = require('widget.screen-recorder.screen-recorder-scripts')
+
+-- The screen-recorder's UI
+local screen_rec_ui = require('widget.screen-recorder.screen-recorder-ui')
+
+-- User Preferences
+local sr_user_resolution = screen_rec_backend.user_resolution
+local sr_user_offset = screen_rec_backend.user_offset
+local sr_user_audio = screen_rec_backend.user_audio
+local sr_user_update = screen_rec_backend.update_user_settings
+
+-- Panel UIs
+local sr_toggle_imgbox = screen_rec_ui.screen_rec_toggle_imgbox
+local sr_toggle_button = screen_rec_ui.screen_rec_toggle_button
+local sr_countdown_text = screen_rec_ui.screen_rec_countdown_txt
+local sr_main_imgbox = screen_rec_ui.screen_rec_main_imgbox
+local sr_main_button = screen_rec_ui.screen_rec_main_button
+local sr_audio_imgbox = screen_rec_ui.screen_rec_audio_imgbox
+local sr_audio_button = screen_rec_ui.screen_rec_audio_button
+local sr_settings_button = screen_rec_ui.screen_rec_settings_button
+local sr_close_button = screen_rec_ui.screen_rec_close_button
+
+
+-- Settings UIs
+local sr_back_button = screen_rec_ui.screen_rec_back_button
+local sr_resolution_box = screen_rec_ui.screen_rec_res_txtbox
+local sr_offset_box = screen_rec_ui.screen_rec_offset_txtbox
+local sr_resolution_tbox = sr_resolution_box:get_children_by_id('res_tbox')[1]
+local sr_offset_tbox = sr_offset_box:get_children_by_id('offset_tbox')[1]
+
+
+-- Main Scripts
+local sr_start_recording = screen_rec_backend.start_recording
+local sr_stop_recording = screen_rec_backend.stop_recording
+
+-- Active Screen Recorder
+local sr_screen = nil
+
+-- Active textbox
+local sr_active_tbox = nil
+
+
+-- Status variables
+local status_countdown = false
+local status_recording = false
+local status_audio = sr_user_audio
+
+
+-- Update UI on startup using the user config
+sr_resolution_tbox:set_markup('' .. sr_user_resolution .. "")
+sr_offset_tbox:set_markup('' .. sr_user_offset .. "")
+
+local sr_res_default_markup = sr_resolution_tbox:get_markup()
+local sr_offset_default_markup = sr_offset_tbox:get_markup()
+
+
+if status_audio then
+ sr_audio_button.bg = '#EE4F84' .. '66'
+else
+ sr_audio_button.bg = beautiful.groups_bg
+end
+
+-- Textbox ui manipulators
+local emphasize_inactive_tbox = function()
+ if sr_active_tbox == 'res_tbox' then
+ sr_resolution_box.shape_border_width = dpi(0)
+ sr_resolution_box.shape_border_color = beautiful.transparent
+ elseif sr_active_tbox == 'offset_tbox' then
+ sr_offset_box.shape_border_width = dpi(0)
+ sr_offset_box.shape_border_color = beautiful.transparent
+ end
+ sr_active_tbox = nil
+end
+
+local emphasize_active_tbox = function()
+ if sr_active_tbox == 'res_tbox' then
+ sr_resolution_box.border_width = dpi(1)
+ sr_resolution_box.border_color = '#F2F2F2AA'
+ elseif sr_active_tbox == 'offset_tbox' then
+ sr_offset_box.border_width = dpi(1)
+ sr_offset_box.border_color = '#F2F2F2AA'
+ end
+end
+
+-- Delete, reset and write to the textbox
+local write_to_textbox = function(char)
+ if sr_active_tbox == 'res_tbox' and (char:match('%d') or char == 'x') then
+ if sr_resolution_tbox:get_markup() == sr_res_default_markup then
+ sr_resolution_tbox:set_text('')
+ end
+ if tonumber(#sr_resolution_tbox:get_text()) <= 8 then
+ sr_resolution_tbox:set_text(sr_resolution_tbox:get_text() .. char)
+ end
+ elseif sr_active_tbox == 'offset_tbox' and (char:match('%d') or char == ',') then
+ if sr_offset_tbox:get_markup() == sr_offset_default_markup then
+ sr_offset_tbox:set_text('')
+ end
+ sr_offset_tbox:set_text(sr_offset_tbox:get_text() .. char)
+ end
+end
+
+local reset_textbox = function()
+ if sr_active_tbox == 'res_tbox' then
+ sr_resolution_tbox:set_markup(sr_res_default_markup)
+ elseif sr_active_tbox == 'offset_tbox' then
+ sr_offset_tbox:set_markup(sr_offset_default_markup)
+ end
+ emphasize_inactive_tbox()
+end
+
+-- Set audio mode
+local sr_audio_mode = function()
+ if not status_recording and not status_countdown then
+ if status_audio then
+ status_audio = false
+ sr_audio_button.bg = beautiful.groups_bg
+ else
+ status_audio = true
+ sr_audio_button.bg = '#EE4F84' .. '66'
+ end
+ end
+end
+
+local delete_key = function()
+ if sr_active_tbox == 'res_tbox' then
+ if tonumber(#sr_resolution_tbox:get_text()) == 1 then
+ reset_textbox()
+ return
+ end
+ sr_resolution_tbox:set_text(sr_resolution_tbox:get_text():sub(1, -2))
+ elseif sr_active_tbox == 'offset_tbox' then
+ if tonumber(#sr_offset_tbox:get_text()) == 1 then
+ reset_textbox()
+ return
+ end
+ sr_offset_tbox:set_text(sr_offset_tbox:get_text():sub(1, -2))
+ end
+end
+
+local apply_new_settings = function()
+
+ -- Get the text on texbox
+ sr_user_resolution = sr_resolution_tbox:get_text()
+ sr_user_offset = sr_offset_tbox:get_text()
+
+ -- Apply new settings
+ sr_user_update(sr_user_resolution, sr_user_offset, status_audio)
+
+ -- Debugger
+ screen_rec_backend.check_settings()
+end
+
+-- Settings Key grabber
+local settings_updater = awful.keygrabber {
+ auto_start = true,
+ stop_event = 'release',
+ keypressed_callback = function(self, mod, key, command)
+ if key == 'BackSpace' then
+ delete_key()
+ end
+ end,
+ keyreleased_callback = function(self, mod, key, command)
+ if key == 'Return' then
+ apply_new_settings()
+ self:stop()
+ end
+
+ if key == 'Escape' then
+ self:stop()
+ reset_textbox()
+ end
+
+ if key:match('%d') or key == 'x' or key == ',' then
+ write_to_textbox(key)
+ end
+
+ end
+}
+
+-- Textboxes
+sr_resolution_tbox:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ emphasize_inactive_tbox()
+ sr_active_tbox = 'res_tbox'
+ emphasize_active_tbox()
+ settings_updater:start()
+ end
+ )
+ )
+)
+
+sr_offset_tbox:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ emphasize_inactive_tbox()
+ sr_active_tbox = 'offset_tbox'
+ emphasize_active_tbox()
+ settings_updater:start()
+ end
+ )
+ )
+)
+
+-- UI switcher
+local sr_navigation_reset = function()
+ if sr_screen then
+ local recorder_panel = sr_screen:get_children_by_id('recorder_panel')[1]
+ local recorder_settings = sr_screen:get_children_by_id('recorder_settings')[1]
+ recorder_settings.visible = false
+ recorder_panel.visible = true
+ end
+end
+
+local sr_navigation = function()
+ if sr_screen then
+ local recorder_panel = sr_screen:get_children_by_id('recorder_panel')[1]
+ local recorder_settings = sr_screen:get_children_by_id('recorder_settings')[1]
+ if recorder_panel.visible then
+ recorder_panel.visible = false
+ recorder_settings.visible = true
+ else
+ recorder_settings.visible = false
+ recorder_panel.visible = true
+ end
+ end
+end
+
+sr_settings_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ if not status_recording and not status_countdown then
+ sr_navigation()
+ end
+ end
+ )
+ )
+)
+
+sr_back_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+
+ -- Save settings
+ apply_new_settings()
+
+ -- Reset textbox UI
+ emphasize_inactive_tbox()
+
+ -- Go back to UI Panel
+ sr_navigation()
+ end
+ )
+ )
+)
+
+-- Close button functions and buttons
+local screen_rec_close = function()
+
+ for s in screen do
+ s.recorder_screen.visible = false
+ end
+ settings_updater:stop()
+ sr_navigation_reset()
+ sr_screen = nil
+end
+
+sr_close_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ screen_rec_close()
+ end
+ )
+ )
+)
+
+-- Right click to exit
+local screen_close_on_rmb = function(widget)
+ widget:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 3,
+ nil,
+ function()
+ screen_rec_close()
+ end
+ )
+ )
+ )
+end
+
+-- Open recorder screen
+sr_toggle_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ for s in screen do
+ s.recorder_screen.visible = false
+ end
+ sr_screen = awful.screen.focused().recorder_screen
+ screen_close_on_rmb(sr_screen)
+ sr_screen.visible = not sr_screen.visible
+ end
+ )
+ )
+)
+
+-- Start Recording
+local sr_recording_start = function()
+ status_countdown = false
+ status_recording = true
+ local sr_screen = awful.screen.focused().recorder_screen
+
+ -- Hide recorder screen
+ sr_screen.visible = false
+
+ -- Manipulate UIs
+ sr_toggle_imgbox:set_image(widget_icon_dir .. 'recording-button' .. '.svg')
+ sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-on' .. '.svg')
+
+ sr_start_recording(status_audio)
+end
+
+-- Stop Recording
+local sr_recording_stop = function()
+ status_recording = false
+ status_audio = false
+
+ -- Manipulate UIs
+ sr_toggle_imgbox:set_image(widget_icon_dir .. 'start-recording-button' .. '.svg')
+ sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-off' .. '.svg')
+ sr_stop_recording()
+end
+
+awesome.connect_signal(
+ 'widget::screen_recorder',
+ function()
+ sr_recording_stop()
+ end
+)
+
+-- Countdown timer functions
+local countdown_timer = nil
+local counter_timer = function()
+ status_countdown = true
+ local seconds = 3
+ countdown_timer = gears.timer.start_new(
+ 1,
+ function()
+ if seconds == 0 then
+ sr_countdown_text.opacity = 0.0
+
+ -- Start recording function
+ sr_recording_start()
+ sr_countdown_text:emit_signal('widget::redraw_needed')
+ return false
+ else
+ sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-countdown' .. '.svg')
+ sr_countdown_text.opacity = 1.0
+ sr_countdown_text:set_text(tostring(seconds))
+ sr_countdown_text:emit_signal('widget::redraw_needed')
+ end
+ seconds = seconds - 1
+ return true
+ end
+ )
+end
+
+-- Stop Countdown timer
+local sr_countdown_stop = function()
+ countdown_timer:stop()
+ status_countdown = false
+ sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-off' .. '.svg')
+ sr_countdown_text.opacity = 0.0
+ sr_countdown_text:emit_signal('widget::redraw_needed')
+end
+
+sr_audio_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ sr_audio_mode()
+ end
+ )
+ )
+)
+
+-- Main button functions and buttons
+local status_checker = function()
+ if status_recording and not status_countdown then
+
+ -- Stop recording
+ sr_recording_stop()
+ return
+ elseif not status_recording and status_countdown then
+
+ -- Stop timer
+ sr_countdown_stop()
+ return
+ end
+
+ -- Start counting down
+ counter_timer()
+end
+
+sr_main_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ status_checker()
+ end
+ )
+ )
+)
diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua b/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua
new file mode 100644
index 0000000..c877d89
--- /dev/null
+++ b/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua
@@ -0,0 +1,343 @@
+local awful = require('awful')
+local gears = require('gears')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/screen-recorder/icons/'
+local record_tbl = {}
+
+-- Panel UI
+record_tbl.screen_rec_toggle_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'start-recording-button' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_toggle_button = wibox.widget {
+ {
+ record_tbl.screen_rec_toggle_imgbox,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+record_tbl.screen_rec_countdown_txt = wibox.widget {
+ id = 'countdown_text',
+ font = 'Inter Bold 64',
+ text = '4',
+ align = 'center',
+ valign = 'bottom',
+ opacity = 0.0,
+ widget = wibox.widget.textbox
+}
+
+record_tbl.screen_rec_main_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'recorder-off' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_main_button = wibox.widget {
+ {
+ {
+ {
+ record_tbl.screen_rec_main_imgbox,
+ margins = dpi(24),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ forced_width = dpi(200),
+ forced_height = dpi(200),
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ },
+ margins = dpi(24),
+ widget = wibox.container.margin
+}
+
+record_tbl.screen_rec_audio_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'audio' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_audio_button = wibox.widget {
+ {
+ nil,
+ {
+ {
+ record_tbl.screen_rec_audio_imgbox,
+ margins = dpi(16),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+ },
+ forced_width = dpi(60),
+ forced_height = dpi(60),
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+record_tbl.screen_rec_close_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'close-screen' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_close_button = wibox.widget {
+ {
+ nil,
+ {
+ {
+ record_tbl.screen_rec_close_imgbox,
+ margins = dpi(16),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ forced_width = dpi(60),
+ forced_height = dpi(60),
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+record_tbl.screen_rec_settings_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'settings' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_settings_button = wibox.widget {
+ {
+ nil,
+ {
+ {
+ record_tbl.screen_rec_settings_imgbox,
+ margins = dpi(16),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+ },
+ forced_width = dpi(60),
+ forced_height = dpi(60),
+ bg = beautiful.groups_bg,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+record_tbl.screen_rec_back_imgbox = wibox.widget {
+ image = widget_icon_dir .. 'back' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+}
+
+record_tbl.screen_rec_back_button = wibox.widget {
+ {
+ nil,
+ {
+ {
+ record_tbl.screen_rec_back_imgbox,
+ margins = dpi(16),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+ },
+ forced_width = dpi(48),
+ forced_height = dpi(48),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+}
+
+record_tbl.screen_rec_back_txt = wibox.widget {
+ {
+ text = 'Back',
+ font = 'Inter Bold 16',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+
+}
+
+record_tbl.screen_rec_res_txt = wibox.widget {
+ {
+ text = 'Resolution',
+ font = 'Inter Bold 16',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+
+}
+
+record_tbl.screen_rec_res_txtbox = wibox.widget {
+ {
+ {
+ {
+ id = 'res_tbox',
+ markup = '' .. '1366x768' .. "",
+ font = 'Inter Bold 16',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ forced_width = dpi(60),
+ forced_height = dpi(60),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+}
+
+record_tbl.screen_rec_offset_txt = wibox.widget {
+ {
+ text = 'Offset',
+ font = 'Inter Bold 16',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+}
+
+record_tbl.screen_rec_offset_txtbox = wibox.widget {
+ {
+ {
+ {
+ id = 'offset_tbox',
+ markup = '' .. '0,0' .. "",
+ font = 'Inter Bold 16',
+ ellipsize = 'start',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ margins = dpi(5),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ },
+ forced_width = dpi(60),
+ forced_height = dpi(60),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+}
+
+screen.connect_signal("request::desktop_decoration", function(s)
+
+ s.recorder_screen = wibox
+ ({
+ ontop = true,
+ screen = s,
+ type = 'dock',
+ height = s.geometry.height,
+ width = s.geometry.width,
+ x = s.geometry.x,
+ y = s.geometry.y,
+ bg = beautiful.background,
+ fg = beautiful.fg_normal
+ })
+
+ s.recorder_screen : setup {
+ layout = wibox.layout.stack,
+ {
+ id = 'recorder_panel',
+ visible = true,
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ record_tbl.screen_rec_countdown_txt,
+ {
+ layout = wibox.layout.align.horizontal,
+ record_tbl.screen_rec_settings_button,
+ record_tbl.screen_rec_main_button,
+ record_tbl.screen_rec_audio_button
+ },
+ record_tbl.screen_rec_close_button,
+ },
+ nil
+
+ },
+ nil
+ },
+ {
+ id = 'recorder_settings',
+ visible = false,
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ forced_width = dpi(240),
+ spacing = dpi(10),
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(10),
+ record_tbl.screen_rec_back_button,
+ record_tbl.screen_rec_back_txt,
+ },
+ record_tbl.screen_rec_res_txt,
+ record_tbl.screen_rec_res_txtbox,
+ record_tbl.screen_rec_offset_txt,
+ record_tbl.screen_rec_offset_txtbox
+ },
+ nil
+
+ },
+ nil
+ }
+ }
+
+end)
+
+return record_tbl
diff --git a/.config/awesome/widget/search-apps/icons/app-launcher.svg b/.config/awesome/widget/search-apps/icons/app-launcher.svg
new file mode 100644
index 0000000..616879f
--- /dev/null
+++ b/.config/awesome/widget/search-apps/icons/app-launcher.svg
@@ -0,0 +1,257 @@
+
+
+
+
diff --git a/.config/awesome/widget/search-apps/init.lua b/.config/awesome/widget/search-apps/init.lua
new file mode 100644
index 0000000..4839ab8
--- /dev/null
+++ b/.config/awesome/widget/search-apps/init.lua
@@ -0,0 +1,51 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local filesystem = gears.filesystem
+local config_dir = filesystem.get_configuration_dir()
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local widget_icon_dir = config_dir .. '/widget/search-apps/icons/'
+local apps = require('configuration.apps')
+
+local return_button = function()
+
+ local widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'app-launcher.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ if screen.primary.left_panel.opened then
+ screen.primary.left_panel:toggle()
+ end
+ awful.spawn(apps.default.rofi_appmenu, false)
+ end
+ )
+ )
+ )
+
+ return widget_button
+end
+
+return return_button
\ No newline at end of file
diff --git a/.config/awesome/widget/social-media/icons/facebook.svg b/.config/awesome/widget/social-media/icons/facebook.svg
new file mode 100644
index 0000000..1052f58
--- /dev/null
+++ b/.config/awesome/widget/social-media/icons/facebook.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/.config/awesome/widget/social-media/icons/instagram.svg b/.config/awesome/widget/social-media/icons/instagram.svg
new file mode 100644
index 0000000..afda8b7
--- /dev/null
+++ b/.config/awesome/widget/social-media/icons/instagram.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/.config/awesome/widget/social-media/icons/reddit.svg b/.config/awesome/widget/social-media/icons/reddit.svg
new file mode 100644
index 0000000..b94ef6f
--- /dev/null
+++ b/.config/awesome/widget/social-media/icons/reddit.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/.config/awesome/widget/social-media/icons/twitter.svg b/.config/awesome/widget/social-media/icons/twitter.svg
new file mode 100644
index 0000000..76840b2
--- /dev/null
+++ b/.config/awesome/widget/social-media/icons/twitter.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/.config/awesome/widget/social-media/init.lua b/.config/awesome/widget/social-media/init.lua
new file mode 100644
index 0000000..c1304dc
--- /dev/null
+++ b/.config/awesome/widget/social-media/init.lua
@@ -0,0 +1,130 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local clickable_container = require('widget.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/social-media/icons/'
+
+local decorate_widget = function(widgets)
+
+ return wibox.widget {
+ widgets,
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, groups_radius)
+ end,
+ widget = wibox.container.background
+ }
+
+end
+
+local build_social_button = function(website)
+
+ local social_imgbox = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. website .. '.svg',
+ widget = wibox.widget.imagebox,
+ resize = true,
+ forced_height = dpi(35)
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local social_button = wibox.widget {
+ {
+ social_imgbox,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ local website_url = nil
+ if website == 'facebook' then
+ website_url = 'https://facebook.com'
+
+ elseif website == 'reddit' then
+ website_url = 'https://reddit.com'
+
+ elseif website == 'twitter' then
+ website_url = 'https://twitter.com'
+
+ elseif website == 'instagram' then
+ website_url = 'https://instagram.com'
+
+ end
+
+ social_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn({'xdg-open', website_url}, false)
+ end
+ )
+ )
+ )
+
+ local social_name = website:sub(1,1):upper() .. website:sub(2)
+
+ local social_tbox = wibox.widget {
+ text = social_name,
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ return wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ decorate_widget(social_button),
+ nil
+ },
+ social_tbox
+ }
+end
+
+
+local social_layout = wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(5),
+ build_social_button('reddit'),
+ build_social_button('facebook'),
+ build_social_button('twitter'),
+ build_social_button('instagram'),
+}
+
+local social = wibox.widget {
+ {
+ {
+ expand = 'none',
+ layout = wibox.layout.align.horizontal,
+ nil,
+ social_layout,
+ nil
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin,
+ },
+ forced_height = dpi(92),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+}
+
+return social
diff --git a/.config/awesome/widget/tag-list/init.lua b/.config/awesome/widget/tag-list/init.lua
new file mode 100644
index 0000000..df5ae64
--- /dev/null
+++ b/.config/awesome/widget/tag-list/init.lua
@@ -0,0 +1,168 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+--- Common method to create buttons.
+-- @tab buttons
+-- @param object
+-- @return table
+local function create_buttons(buttons, object)
+ if buttons then
+ local btns = {}
+ for _, b in ipairs(buttons) do
+ -- Create a proxy button object: it will receive the real
+ -- press and release events, and will propagate them to the
+ -- button object the user provided, but with the object as
+ -- argument.
+ local btn = awful.button {
+ modifiers = b.modifiers,
+ button = b.button,
+ on_press = function()
+ b:emit_signal('press', object)
+ end,
+ on_release = function()
+ b:emit_signal('release', object)
+ end
+ }
+ btns[#btns + 1] = btn
+ end
+ return btns
+ end
+end
+
+local function list_update(w, buttons, label, data, objects)
+ -- update the widgets, creating them if needed
+ w:reset()
+ for i, o in ipairs(objects) do
+ local cache = data[o]
+ local ib, tb, bgb, tbm, ibm, l, bg_clickable
+ if cache then
+ ib = cache.ib
+ tb = cache.tb
+ bgb = cache.bgb
+ tbm = cache.tbm
+ ibm = cache.ibm
+ else
+ ib = wibox.widget.imagebox()
+ tb = wibox.widget.textbox()
+ bgb = wibox.container.background()
+ tbm = wibox.widget {
+ tb,
+ left = dpi(4),
+ right = dpi(16),
+ widget = wibox.container.margin
+ }
+ ibm = wibox.widget {
+ ib,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ }
+ l = wibox.layout.fixed.horizontal()
+ bg_clickable = clickable_container()
+
+ -- All of this is added in a fixed widget
+ l:fill_space(true)
+ l:add(ibm)
+ -- l:add(tbm)
+ bg_clickable:set_widget(l)
+
+ -- And all of this gets a background
+ bgb:set_widget(bg_clickable)
+
+ bgb:buttons(create_buttons(buttons, o))
+
+ data[o] = {
+ ib = ib,
+ tb = tb,
+ bgb = bgb,
+ tbm = tbm,
+ ibm = ibm
+ }
+ end
+
+ local text, bg, bg_image, icon, args = label(o, tb)
+ args = args or {}
+
+ -- The text might be invalid, so use pcall.
+ if text == nil or text == '' then
+ tbm:set_margins(0)
+ else
+ if not tb:set_markup_silently(text) then
+ tb:set_markup('<Invalid text>')
+ end
+ end
+ bgb:set_bg(bg)
+ if type(bg_image) == 'function' then
+ -- TODO: Why does this pass nil as an argument?
+ bg_image = bg_image(tb, o, nil, objects, i)
+ end
+ bgb:set_bgimage(bg_image)
+ if icon then
+ ib.image = icon
+ else
+ ibm:set_margins(0)
+ end
+
+ bgb.shape = args.shape
+ bgb.shape_border_width = args.shape_border_width
+ bgb.shape_border_color = args.shape_border_color
+
+ w:add(bgb)
+ end
+end
+
+local tag_list = function(s)
+ return awful.widget.taglist(
+ s,
+ awful.widget.taglist.filter.all,
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function(t)
+ t:view_only()
+ end
+ ),
+ awful.button(
+ {modkey},
+ 1,
+ function(t)
+ if _G.client.focus then
+ _G.client.focus:move_to_tag(t)
+ t:view_only()
+ end
+ end
+ ),
+ awful.button({}, 3, awful.tag.viewtoggle),
+ awful.button(
+ {modkey},
+ 3,
+ function(t)
+ if _G.client.focus then
+ _G.client.focus:toggle_tag(t)
+ end
+ end
+ ),
+ awful.button(
+ {},
+ 4,
+ function(t)
+ awful.tag.viewprev(t.screen)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ function(t)
+ awful.tag.viewnext(t.screen)
+ end
+ )
+ ),
+ {},
+ list_update,
+ wibox.layout.fixed.vertical()
+ )
+end
+return tag_list
diff --git a/.config/awesome/widget/task-list/init.lua b/.config/awesome/widget/task-list/init.lua
new file mode 100644
index 0000000..9bf921e
--- /dev/null
+++ b/.config/awesome/widget/task-list/init.lua
@@ -0,0 +1,232 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local gears = require('gears')
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+--- Common method to create buttons.
+-- @tab buttons
+-- @param object
+-- @return table
+local function create_buttons(buttons, object)
+ if buttons then
+ local btns = {}
+ for _, b in ipairs(buttons) do
+ -- Create a proxy button object: it will receive the real
+ -- press and release events, and will propagate them to the
+ -- button object the user provided, but with the object as
+ -- argument.
+ local btn = awful.button {
+ modifiers = b.modifiers,
+ button = b.button,
+ on_press = function()
+ b:emit_signal('press', object)
+ end,
+ on_release = function()
+ b:emit_signal('release', object)
+ end
+ }
+ btns[#btns + 1] = btn
+ end
+ return btns
+ end
+end
+
+local function list_update(w, buttons, label, data, objects)
+ -- Update the widgets, creating them if needed
+ w:reset()
+ for i, o in ipairs(objects) do
+ local cache = data[o]
+ local ib, cb, tb, cbm, bgb, tbm, ibm, tt, l, ll, bg_clickable
+ if cache then
+ ib = cache.ib
+ tb = cache.tb
+ bgb = cache.bgb
+ tbm = cache.tbm
+ ibm = cache.ibm
+ tt = cache.tt
+ else
+ ib = wibox.widget.imagebox()
+ tb = wibox.widget.textbox()
+ cb = wibox.widget {
+ {
+ {
+ image = icons.close,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ margins = dpi(4),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+ cb.shape = gears.shape.circle
+ cbm = wibox.widget {
+ -- 4, 8 ,12 ,12 -- close button
+ cb,
+ left = dpi(4),
+ right = dpi(8),
+ top = dpi(4),
+ bottom = dpi(4),
+ widget = wibox.container.margin
+ }
+ cbm:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ o:kill()
+ end
+ )
+ )
+ )
+ bg_clickable = clickable_container()
+ bgb = wibox.container.background()
+ tbm = wibox.widget {
+ tb,
+ left = dpi(4),
+ right = dpi(4),
+ widget = wibox.container.margin
+ }
+ ibm = wibox.widget {
+ -- 12 top bottom
+ ib,
+ left = dpi(6),
+ right = dpi(6),
+ top = dpi(6),
+ bottom = dpi(6),
+ widget = wibox.container.margin
+ }
+ l = wibox.layout.fixed.horizontal()
+ ll = wibox.layout.fixed.horizontal()
+
+ -- All of this is added in a fixed widget
+ l:fill_space(true)
+ l:add(ibm)
+ l:add(tbm)
+ ll:add(l)
+ ll:add(cbm)
+
+ bg_clickable:set_widget(ll)
+ -- And all of this gets a background
+ bgb:set_widget(bg_clickable)
+
+ l:buttons(create_buttons(buttons, o))
+
+ -- Tooltip to display whole title, if it was truncated
+ tt = awful.tooltip({
+ objects = {tb},
+ mode = 'outside',
+ align = 'bottom',
+ delay_show = 1,
+ })
+
+ data[o] = {
+ ib = ib,
+ tb = tb,
+ bgb = bgb,
+ tbm = tbm,
+ ibm = ibm,
+ tt = tt
+ }
+ end
+
+ local text, bg, bg_image, icon, args = label(o, tb)
+ args = args or {}
+
+ -- The text might be invalid, so use pcall.
+ if text == nil or text == '' then
+ tbm:set_margins(0)
+ else
+ -- Truncate when title is too long
+ local text_only = text:match('>(.-)<')
+ if (utf8.len(text_only) > 24) then
+ text = text:gsub('>(.-)<', '>' .. string.sub(text_only, 1, utf8.offset(text_only,22) - 1) .. '...<')
+ tt:set_text(text_only)
+ tt:add_to_object(tb)
+ else
+ tt:remove_from_object(tb)
+ end
+ if not tb:set_markup_silently(text) then
+ tb:set_markup('<Invalid text>')
+ end
+ end
+ bgb:set_bg(bg)
+ if type(bg_image) == 'function' then
+ -- TODO: Why does this pass nil as an argument?
+ bg_image = bg_image(tb, o, nil, objects, i)
+ end
+ bgb:set_bgimage(bg_image)
+ if icon then
+ ib.image = gears.surface(icon)
+ else
+ ibm:set_margins(0)
+ end
+
+ bgb.shape = args.shape
+ bgb.shape_border_width = args.shape_border_width
+ bgb.shape_border_color = args.shape_border_color
+
+ w:add(bgb)
+ end
+end
+
+local tasklist_buttons = awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function(c)
+ if c == client.focus then
+ c.minimized = true
+ else
+ -- Without this, the following
+ -- :isvisible() makes no sense
+ c.minimized = false
+ if not c:isvisible() and c.first_tag then
+ c.first_tag:view_only()
+ end
+ -- This will also un-minimize
+ -- the client, if needed
+ c:emit_signal('request::activate')
+ c:raise()
+ end
+ end
+ ),
+ awful.button(
+ {},
+ 2,
+ function(c)
+ c:kill()
+ end
+ ),
+ awful.button(
+ {},
+ 4,
+ function()
+ awful.client.focus.byidx(1)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ function()
+ awful.client.focus.byidx(-1)
+ end
+ )
+)
+
+local task_list = function(s)
+ return awful.widget.tasklist(
+ s,
+ awful.widget.tasklist.filter.currenttags,
+ tasklist_buttons,
+ {},
+ list_update,
+ wibox.layout.fixed.horizontal()
+ )
+end
+
+return task_list
diff --git a/.config/awesome/widget/temperature-meter/init.lua b/.config/awesome/widget/temperature-meter/init.lua
new file mode 100644
index 0000000..ca59e9b
--- /dev/null
+++ b/.config/awesome/widget/temperature-meter/init.lua
@@ -0,0 +1,88 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+local watch = awful.widget.watch
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'temp_status',
+ max_value = 100,
+ value = 29,
+ forced_height = dpi(2),
+ color = beautiful.fg_normal,
+ background_color = beautiful.groups_bg,
+ shape = gears.shape.rounded_rect,
+ widget = wibox.widget.progressbar
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+local max_temp = 80
+
+awful.spawn.easy_async_with_shell(
+ [[
+ temp_path=null
+ for i in /sys/class/hwmon/hwmon*/temp*_input;
+ do
+ temp_path="$(echo "$(<$(dirname $i)/name): $(cat ${i%_*}_label 2>/dev/null ||
+ echo $(basename ${i%_*})) $(readlink -f $i)");"
+
+ label="$(echo $temp_path | awk '{print $2}')"
+
+ if [ "$label" = "Package" ];
+ then
+ echo ${temp_path} | awk '{print $5}' | tr -d ';\n'
+ exit;
+ fi
+ done
+ ]],
+ function(stdout)
+ local temp_path = stdout:gsub('%\n', '')
+ if temp_path == '' or not temp_path then
+ temp_path = '/sys/class/thermal/thermal_zone0/temp'
+ end
+
+ watch(
+ [[
+ sh -c "cat ]] .. temp_path .. [["
+ ]],
+ 10,
+ function(_, stdout)
+ local temp = stdout:match('(%d+)')
+ slider.temp_status:set_value((temp / 1000) / max_temp * 100)
+ collectgarbage('collect')
+ end
+ )
+ end
+)
+
+local temperature_meter = wibox.widget {
+ {
+ {
+ {
+ image = icons.thermometer,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return temperature_meter
diff --git a/.config/awesome/widget/tray-toggle/icons/left-arrow.svg b/.config/awesome/widget/tray-toggle/icons/left-arrow.svg
new file mode 100644
index 0000000..f0e76e5
--- /dev/null
+++ b/.config/awesome/widget/tray-toggle/icons/left-arrow.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/tray-toggle/icons/right-arrow.svg b/.config/awesome/widget/tray-toggle/icons/right-arrow.svg
new file mode 100644
index 0000000..7446424
--- /dev/null
+++ b/.config/awesome/widget/tray-toggle/icons/right-arrow.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/tray-toggle/init.lua b/.config/awesome/widget/tray-toggle/init.lua
new file mode 100644
index 0000000..76af98d
--- /dev/null
+++ b/.config/awesome/widget/tray-toggle/init.lua
@@ -0,0 +1,68 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/tray-toggle/icons/'
+
+local widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'right-arrow' .. '.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+local widget_button = wibox.widget {
+ {
+ widget,
+ margins = dpi(7),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+}
+
+widget_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awesome.emit_signal('widget::systray:toggle')
+ end
+ )
+ )
+)
+
+-- Listen to signal
+awesome.connect_signal(
+ 'widget::systray:toggle',
+ function()
+ if screen.primary.systray then
+
+ if not screen.primary.systray.visible then
+
+ widget.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'left-arrow.svg'))
+ else
+
+ widget.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'right-arrow.svg'))
+ end
+
+ screen.primary.systray.visible = not screen.primary.systray.visible
+ end
+ end
+)
+
+-- Update icon on start-up
+if screen.primary.systray then
+ if screen.primary.systray.visible then
+ widget.icon:set_image(widget_icon_dir .. 'right-arrow' .. '.svg')
+ end
+end
+
+-- Show only the tray button in the primary screen
+return awful.widget.only_on_screen(widget_button, 'primary')
diff --git a/.config/awesome/widget/user-profile/init.lua b/.config/awesome/widget/user-profile/init.lua
new file mode 100644
index 0000000..6151a76
--- /dev/null
+++ b/.config/awesome/widget/user-profile/init.lua
@@ -0,0 +1,239 @@
+-- User profile widget
+-- Optional dependency:
+-- mugshot (use to update profile picture and information)
+
+
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local apps = require('configuration.apps')
+local clickable_container = require('widget.clickable-container')
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'configuration/user-profile/'
+local user_icon_dir = '/var/lib/AccountsService/icons/'
+
+title_table = {
+ 'Hey, I have a message for you',
+ 'Listen here you little shit!',
+ 'Le\' me tell you a secret',
+ 'I never lie',
+ 'Message received from your boss'
+}
+
+message_table = {
+ 'Let me rate your face! Oops... It looks like I can\'t compute negative numbers. You\'re ugly af, sorry',
+ 'Lookin\' good today, now fuck off!',
+ 'The last thing I want to do is hurt you. But it’s still on the list.',
+ 'If I agreed with you we’d both be wrong.',
+ 'I intend to live forever. So far, so good.',
+ 'Jesus loves you, but everyone else thinks you’re an asshole.',
+ 'Your baby is so ugly, you should have thrown it away and kept the stork.',
+ 'If your brain was dynamite, there wouldn’t be enough to blow your hat off.',
+ 'You are more disappointing than an unsalted pretzel.',
+ 'Your kid is so ugly, he makes his Happy Meal cry.',
+ 'Your secrets are always safe with me. I never even listen when you tell me them.',
+ 'I only take you everywhere I go just so I don’t have to kiss you goodbye.',
+ 'You look so pretty. Not at all gross, today.',
+ 'It’s impossible to underestimate you.',
+ 'I’m not insulting you, I’m describing you.',
+ 'Keep rolling your eyes, you might eventually find a brain.',
+ 'You bring everyone so much joy, when you leave the room.',
+ 'I thought of you today. It reminded me to take out the trash.',
+ 'You are the human version of period cramps.',
+ 'You’re the reason God created the middle finger.'
+}
+
+local profile_imagebox = wibox.widget {
+ {
+ id = 'icon',
+ forced_height = dpi(45),
+ forced_width = dpi(45),
+ image = widget_icon_dir .. 'default.svg',
+ widget = wibox.widget.imagebox,
+ resize = true,
+ clip_shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+profile_imagebox:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.single_instance('mugshot')
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ nil,
+ function()
+ naughty.notification({
+ app_name = 'FBI\'s ChatBot v69',
+ title = title_table[math.random(#title_table)],
+ message = message_table[math.random(#message_table)] ..
+ '\n\n- xXChatBOT69Xx',
+ urgency = 'normal'
+ })
+ end
+ )
+ )
+)
+
+local profile_name = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'User',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local distro_name = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'GNU/Linux',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local kernel_version = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'Linux',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local uptime_time = wibox.widget {
+ font = 'Inter Regular 10',
+ markup = 'up 1 minute',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local update_profile_image = function()
+ awful.spawn.easy_async_with_shell(
+ apps.utils.update_profile,
+ function(stdout)
+ stdout = stdout:gsub('%\n','')
+ if not stdout:match('default') then
+ profile_imagebox.icon:set_image(stdout)
+ else
+ profile_imagebox.icon:set_image(widget_icon_dir .. 'default.svg')
+ end
+ end
+ )
+end
+
+update_profile_image()
+
+awful.spawn.easy_async_with_shell(
+ [[
+ sh -c '
+ fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")"
+ if [ -z "$fullname" ];
+ then
+ printf "$(whoami)@$(hostname)"
+ else
+ printf "$fullname"
+ fi
+ '
+ ]],
+ function(stdout)
+ local stdout = stdout:gsub('%\n', '')
+ profile_name:set_markup(stdout)
+ end
+)
+
+awful.spawn.easy_async_with_shell(
+ [[
+ cat /etc/os-release | awk 'NR==1'| awk -F '"' '{print $2}'
+ ]],
+ function(stdout)
+ local distroname = stdout:gsub('%\n', '')
+ distro_name:set_markup(distroname)
+ end
+)
+
+awful.spawn.easy_async_with_shell(
+ 'uname -r',
+ function(stdout)
+ local kname = stdout:gsub('%\n', '')
+ kernel_version:set_markup(kname)
+ end
+)
+
+local update_uptime = function()
+ awful.spawn.easy_async_with_shell(
+ 'uptime -p',
+ function(stdout)
+ local uptime = stdout:gsub('%\n','')
+ uptime_time:set_markup(uptime)
+ end
+ )
+end
+
+local uptime_updater_timer = gears.timer{
+ timeout = 60,
+ autostart = true,
+ call_now = true,
+ callback = function()
+ update_uptime()
+ end
+}
+
+local user_profile = wibox.widget {
+ {
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(10),
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ profile_imagebox,
+ nil
+ },
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ profile_name,
+ distro_name,
+ kernel_version,
+ uptime_time
+ },
+ nil
+ }
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ forced_height = dpi(92),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+
+}
+
+user_profile:connect_signal(
+ 'mouse::enter',
+ function()
+ update_uptime()
+ end
+)
+
+return user_profile
diff --git a/.config/awesome/widget/volume-slider/init.lua b/.config/awesome/widget/volume-slider/init.lua
new file mode 100644
index 0000000..101772d
--- /dev/null
+++ b/.config/awesome/widget/volume-slider/init.lua
@@ -0,0 +1,180 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+local spawn = awful.spawn
+local dpi = beautiful.xresources.apply_dpi
+local icons = require('theme.icons')
+local clickable_container = require('widget.clickable-container')
+
+local icon = wibox.widget {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ image = icons.volume,
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ nil
+}
+
+local action_level = wibox.widget {
+ {
+ icon,
+ widget = clickable_container,
+ },
+ bg = beautiful.transparent,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'volume_slider',
+ bar_shape = gears.shape.rounded_rect,
+ bar_height = dpi(2),
+ bar_color = '#ffffff20',
+ bar_active_color = '#f2f2f2EE',
+ handle_color = '#ffffff',
+ handle_shape = gears.shape.circle,
+ handle_width = dpi(15),
+ handle_border_color = '#00000012',
+ handle_border_width = dpi(1),
+ maximum = 100,
+ widget = wibox.widget.slider,
+ },
+ nil,
+ forced_height = dpi(24),
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+}
+
+
+local volume_slider = slider.volume_slider
+
+volume_slider:connect_signal(
+ 'property::value',
+ function()
+ local volume_level = volume_slider:get_value()
+
+ spawn('amixer -D pulse sset Master ' ..
+ volume_level .. '%',
+ false
+ )
+
+ -- Update volume osd
+ awesome.emit_signal(
+ 'module::volume_osd',
+ volume_level
+ )
+ end
+)
+
+volume_slider:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 4,
+ nil,
+ function()
+ if volume_slider:get_value() > 100 then
+ volume_slider:set_value(100)
+ return
+ end
+ volume_slider:set_value(volume_slider:get_value() + 5)
+ end
+ ),
+ awful.button(
+ {},
+ 5,
+ nil,
+ function()
+ if volume_slider:get_value() < 0 then
+ volume_slider:set_value(0)
+ return
+ end
+ volume_slider:set_value(volume_slider:get_value() - 5)
+ end
+ )
+ )
+)
+
+
+local update_slider = function()
+ awful.spawn.easy_async_with_shell(
+ [[bash -c "amixer -D pulse sget Master"]],
+ function(stdout)
+ local volume = string.match(stdout, '(%d?%d?%d)%%')
+ volume_slider:set_value(tonumber(volume))
+ end
+ )
+end
+
+-- Update on startup
+update_slider()
+
+local action_jump = function()
+ local sli_value = volume_slider:get_value()
+ local new_value = 0
+
+ if sli_value >= 0 and sli_value < 50 then
+ new_value = 50
+ elseif sli_value >= 50 and sli_value < 100 then
+ new_value = 100
+ else
+ new_value = 0
+ end
+ volume_slider:set_value(new_value)
+end
+
+action_level:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ action_jump()
+ end
+ )
+ )
+)
+
+-- The emit will come from the global keybind
+awesome.connect_signal(
+ 'widget::volume',
+ function()
+ update_slider()
+ end
+)
+
+-- The emit will come from the OSD
+awesome.connect_signal(
+ 'widget::volume:update',
+ function(value)
+ volume_slider:set_value(tonumber(value))
+ end
+)
+
+local volume_setting = wibox.widget {
+ {
+ {
+ action_level,
+ top = dpi(12),
+ bottom = dpi(12),
+ widget = wibox.container.margin
+ },
+ slider,
+ spacing = dpi(24),
+ layout = wibox.layout.fixed.horizontal
+
+ },
+ left = dpi(24),
+ right = dpi(24),
+ forced_height = dpi(48),
+ widget = wibox.container.margin
+}
+
+return volume_setting
diff --git a/.config/awesome/widget/weather/icons/d_rain.svg b/.config/awesome/widget/weather/icons/d_rain.svg
new file mode 100644
index 0000000..44cacc1
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/d_rain.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dbroken_clouds.svg b/.config/awesome/widget/weather/icons/dbroken_clouds.svg
new file mode 100644
index 0000000..8fa8005
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dbroken_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dfew_clouds.svg b/.config/awesome/widget/weather/icons/dfew_clouds.svg
new file mode 100644
index 0000000..a4f1fd3
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dfew_clouds.svg
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dmist.svg b/.config/awesome/widget/weather/icons/dmist.svg
new file mode 100644
index 0000000..b23f3bf
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dmist.svg
@@ -0,0 +1,77 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dscattered_clouds.svg b/.config/awesome/widget/weather/icons/dscattered_clouds.svg
new file mode 100644
index 0000000..9c0ebcb
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dscattered_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dshower_rain.svg b/.config/awesome/widget/weather/icons/dshower_rain.svg
new file mode 100644
index 0000000..3a88004
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dshower_rain.svg
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/dthunderstorm.svg b/.config/awesome/widget/weather/icons/dthunderstorm.svg
new file mode 100644
index 0000000..10375e4
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/dthunderstorm.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/moon_icon.svg b/.config/awesome/widget/weather/icons/moon_icon.svg
new file mode 100644
index 0000000..b9e5c3a
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/moon_icon.svg
@@ -0,0 +1,67 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/n_rain.svg b/.config/awesome/widget/weather/icons/n_rain.svg
new file mode 100644
index 0000000..3ba466a
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/n_rain.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nbroken_clouds.svg b/.config/awesome/widget/weather/icons/nbroken_clouds.svg
new file mode 100644
index 0000000..d462c33
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nbroken_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nfew_clouds.svg b/.config/awesome/widget/weather/icons/nfew_clouds.svg
new file mode 100644
index 0000000..74575ee
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nfew_clouds.svg
@@ -0,0 +1,83 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nmist.svg b/.config/awesome/widget/weather/icons/nmist.svg
new file mode 100644
index 0000000..34d0e41
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nmist.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nscattered_clouds.svg b/.config/awesome/widget/weather/icons/nscattered_clouds.svg
new file mode 100644
index 0000000..007e66b
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nscattered_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nshower_rain.svg b/.config/awesome/widget/weather/icons/nshower_rain.svg
new file mode 100644
index 0000000..50b4ebc
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nshower_rain.svg
@@ -0,0 +1,73 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/nthunderstorm.svg b/.config/awesome/widget/weather/icons/nthunderstorm.svg
new file mode 100644
index 0000000..73f67e5
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/nthunderstorm.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/refresh.svg b/.config/awesome/widget/weather/icons/refresh.svg
new file mode 100644
index 0000000..0eb9ef7
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/refresh.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/.config/awesome/widget/weather/icons/snow.svg b/.config/awesome/widget/weather/icons/snow.svg
new file mode 100644
index 0000000..f4fcc6a
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/snow.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/sun_icon.svg b/.config/awesome/widget/weather/icons/sun_icon.svg
new file mode 100644
index 0000000..24ac40d
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/sun_icon.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/.config/awesome/widget/weather/icons/sunrise.svg b/.config/awesome/widget/weather/icons/sunrise.svg
new file mode 100644
index 0000000..f0e8a47
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/sunrise.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/.config/awesome/widget/weather/icons/sunset.svg b/.config/awesome/widget/weather/icons/sunset.svg
new file mode 100644
index 0000000..d60f574
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/sunset.svg
@@ -0,0 +1,72 @@
+
+
diff --git a/.config/awesome/widget/weather/icons/weather-error.svg b/.config/awesome/widget/weather/icons/weather-error.svg
new file mode 100644
index 0000000..afcb331
--- /dev/null
+++ b/.config/awesome/widget/weather/icons/weather-error.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/.config/awesome/widget/weather/init.lua b/.config/awesome/widget/weather/init.lua
new file mode 100644
index 0000000..1c1a516
--- /dev/null
+++ b/.config/awesome/widget/weather/init.lua
@@ -0,0 +1,398 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/weather/icons/'
+local clickable_container = require('widget.clickable-container')
+local json = require('library.json')
+
+local config = require('configuration.config')
+local secrets = {
+ key = config.widget.weather.key,
+ city_id = config.widget.weather.city_id,
+ units = config.widget.weather.units,
+ update_interval = config.widget.weather.update_interval
+}
+
+local weather_icon_widget = wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'weather-error.svg',
+ resize = true,
+ forced_height = dpi(45),
+ forced_width = dpi(45),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local sunrise_icon_widget = wibox.widget {
+ {
+ id = 'sunrise_icon',
+ image = widget_icon_dir .. 'sunrise.svg',
+ resize = true,
+ forced_height = dpi(18),
+ forced_width = dpi(18),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local sunset_icon_widget = wibox.widget {
+ {
+ id = 'sunset_icon',
+ image = widget_icon_dir .. 'sunset.svg',
+ resize = true,
+ forced_height = dpi(18),
+ forced_width = dpi(18),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local refresh_icon_widget = wibox.widget {
+ {
+ id = 'refresh_icon',
+ image = widget_icon_dir .. 'refresh.svg',
+ resize = true,
+ forced_height = dpi(18),
+ forced_width = dpi(18),
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.fixed.horizontal
+}
+
+local refresh_button = clickable_container(refresh_icon_widget)
+refresh_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awesome.emit_signal('widget::weather_fetch')
+ awesome.emit_signal('widget::forecast_fetch')
+ end
+ )
+ )
+)
+
+local refresh_widget = wibox.widget {
+ refresh_button,
+ bg = beautiful.transparent,
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local weather_desc_temp = wibox.widget {
+ {
+ id = 'description',
+ markup = 'Dust and clouds, -1000°C',
+ font = 'Inter Regular 10',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ id = 'scroll_container',
+ max_size = 345,
+ speed = 75,
+ expand = true,
+ direction = 'h',
+ step_function = wibox.container.scroll
+ .step_functions.waiting_nonlinear_back_and_forth,
+ fps = 30,
+ layout = wibox.container.scroll.horizontal,
+}
+
+local weather_location = wibox.widget {
+ {
+ id = 'location',
+ markup = 'Earth, Milky Way',
+ font = 'Inter Regular 10',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ id = 'scroll_container',
+ max_size = 345,
+ speed = 75,
+ expand = true,
+ direction = 'h',
+ step_function = wibox.container.scroll
+ .step_functions.waiting_nonlinear_back_and_forth,
+ fps = 30,
+ layout = wibox.container.scroll.horizontal,
+}
+
+local weather_sunrise = wibox.widget {
+ markup = '00:00',
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local weather_sunset = wibox.widget {
+ markup = '00:00',
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local weather_data_time = wibox.widget {
+ markup = '00:00',
+ font = 'Inter Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local weather_forecast_tooltip = awful.tooltip {
+ text = 'Loading...',
+ objects = {weather_icon_widget},
+ mode = 'outside',
+ align = 'right',
+ preferred_positions = {'left', 'right', 'top', 'bottom'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8)
+}
+
+local weather_report = wibox.widget {
+ {
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(10),
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ weather_icon_widget,
+ nil
+ },
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ weather_location,
+ weather_desc_temp,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(7),
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(3),
+ sunrise_icon_widget,
+ weather_sunrise
+ },
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(3),
+ sunset_icon_widget,
+ weather_sunset
+ },
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = dpi(3),
+ refresh_widget,
+ weather_data_time
+ }
+ }
+ },
+ nil
+ }
+ },
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ forced_height = dpi(92),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius)
+ end,
+ widget = wibox.container.background
+}
+
+-- Return weather symbol
+local get_weather_symbol = function()
+ local symbol_tbl = {
+ ['metric'] = '°C',
+ ['imperial'] = '°F'
+ }
+ return symbol_tbl[secrets.units]
+end
+
+-- Create openweathermap script based on pass mode
+-- Mode must be `forecast` or `weather`
+local create_weather_script = function(mode)
+ local weather_script = [[
+ KEY="]] .. secrets.key .. [["
+ CITY="]] .. secrets.city_id .. [["
+ UNITS="]] .. secrets.units .. [["
+
+ weather=$(curl -sf "http://api.openweathermap.org/data/2.5/]] .. mode ..
+ [[?APPID="${KEY}"&id="${CITY}"&units="${UNITS}"")
+
+ if [ ! -z "$weather" ]; then
+ printf "${weather}"
+ else
+ printf "error"
+ fi
+ ]]
+
+ return weather_script
+end
+
+awesome.connect_signal(
+ 'widget::forecast_fetch',
+ function()
+ awful.spawn.easy_async_with_shell(
+ create_weather_script('forecast'),
+ function(stdout)
+ if stdout:match('error') then
+ weather_forecast_tooltip:set_markup('Can\'t retrieve data!')
+ else
+ local forecast_data = json.parse(stdout)
+ local forecast = ''
+
+ for i = 8, 40, 8 do
+ local day = os.date('%A @ %H:%M', forecast_data.list[i].dt)
+ local temp = math.floor(forecast_data.list[i].main.temp + 0.5)
+ local feels_like = math.floor(forecast_data.list[i].main.feels_like + 0.5)
+ local weather = forecast_data.list[i].weather[1].description
+
+ -- Capitalize weather description
+ weather = weather:sub(1, 1):upper() .. weather:sub(2)
+
+ forecast = forecast .. '' .. day .. '\n' ..
+ 'Weather: ' .. weather .. '\n' ..
+ 'Temperature: ' .. temp .. get_weather_symbol() .. '\n' ..
+ 'Feels like: ' .. feels_like .. get_weather_symbol() .. '\n\n'
+
+ weather_forecast_tooltip:set_markup(forecast:sub(1, -2))
+ end
+ end
+ end
+ )
+ end
+)
+
+awesome.connect_signal(
+ 'widget::weather_fetch',
+ function()
+ awful.spawn.easy_async_with_shell(
+ create_weather_script('weather'),
+ function(stdout)
+ if stdout:match('error') then
+ awesome.emit_signal(
+ 'widget::weather_update',
+ '...',
+ 'Dust and clouds, -1000°C',
+ 'Earth, Milky Way',
+ '00:00',
+ '00:00',
+ '00:00'
+ )
+ else
+ -- Parse JSON string
+ local weather_data = json.parse(stdout)
+
+ -- Process weather data
+ local location = weather_data.name
+ local country = weather_data.sys.country
+ local sunrise = os.date('%H:%M', weather_data.sys.sunrise)
+ local sunset = os.date('%H:%M', weather_data.sys.sunset)
+ local refresh = os.date('%H:%M', weather_data.dt)
+ local temperature = math.floor(weather_data.main.temp + 0.5)
+ local weather = weather_data.weather[1].description
+ local weather_icon = weather_data.weather[1].icon
+
+ -- Capitalize weather description
+ local weather = weather:sub(1, 1):upper() .. weather:sub(2)
+
+ -- Contantenate weather description and symbol
+ local weather_description = weather .. ', ' .. temperature .. get_weather_symbol()
+
+ -- Contantenate city and country
+ local weather_location = location .. ', ' .. country
+
+ awesome.emit_signal(
+ 'widget::weather_update',
+ weather_icon,
+ weather_description,
+ weather_location,
+ sunrise,
+ sunset,
+ refresh
+ )
+ end
+ end
+ )
+ end
+)
+
+local update_widget_timer = gears.timer {
+ timeout = secrets.update_interval,
+ autostart = true,
+ call_now = true,
+ single_shot = false,
+ callback = function()
+ awesome.emit_signal('widget::weather_fetch')
+ awesome.emit_signal('widget::forecast_fetch')
+ end
+}
+
+awesome.connect_signal(
+ 'system::network_connected',
+ function()
+ awesome.emit_signal('widget::weather_fetch')
+ awesome.emit_signal('widget::forecast_fetch')
+ end
+)
+
+awesome.connect_signal(
+ 'widget::weather_update',
+ function(code, desc, location, sunrise, sunset, data_receive)
+ local widget_icon_name = 'weather-error'
+
+ local icon_tbl = {
+ ['01d'] = 'sun_icon.svg',
+ ['01n'] = 'moon_icon.svg',
+ ['02d'] = 'dfew_clouds.svg',
+ ['02n'] = 'nfew_clouds.svg',
+ ['03d'] = 'dscattered_clouds.svg',
+ ['03n'] = 'nscattered_clouds.svg',
+ ['04d'] = 'dbroken_clouds.svg',
+ ['04n'] = 'nbroken_clouds.svg',
+ ['09d'] = 'dshower_rain.svg',
+ ['09n'] = 'nshower_rain.svg',
+ ['10d'] = 'd_rain.svg',
+ ['10n'] = 'n_rain.svg',
+ ['11d'] = 'dthunderstorm.svg',
+ ['11n'] = 'nthunderstorm.svg',
+ ['13d'] = 'snow.svg',
+ ['13n'] = 'snow.svg',
+ ['50d'] = 'dmist.svg',
+ ['50n'] = 'nmist.svg',
+ ['...'] = 'weather-error.svg'
+ }
+
+ widget_icon_name = icon_tbl[code]
+
+ weather_icon_widget.icon:set_image(widget_icon_dir .. widget_icon_name)
+ weather_icon_widget.icon:emit_signal('widget::redraw_needed')
+
+ weather_desc_temp.description:set_markup(desc)
+ weather_location.location:set_markup(location)
+ weather_sunrise:set_markup(sunrise)
+ weather_sunset:set_markup(sunset)
+ weather_data_time:set_markup(data_receive)
+ end
+)
+
+return weather_report
diff --git a/.config/awesome/widget/xdg-folders/documents.lua b/.config/awesome/widget/xdg-folders/documents.lua
new file mode 100644
index 0000000..5906a8b
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/documents.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local docu_widget = wibox.widget {
+ {
+ image = widget_icon_dir .. 'folder-documents' .. '.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local docu_button = wibox.widget {
+ {
+ docu_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ docu_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('xdg-open $(xdg-user-dir DOCUMENTS)')
+ end
+ )
+ )
+ )
+
+ awful.tooltip(
+ {
+ objects = {docu_button},
+ mode = 'outside',
+ align = 'right',
+ text = 'Documents',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+ )
+
+ return docu_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/xdg-folders/downloads.lua b/.config/awesome/widget/xdg-folders/downloads.lua
new file mode 100644
index 0000000..02f572b
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/downloads.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local dl_widget = wibox.widget {
+ {
+ image = widget_icon_dir .. 'folder-download.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local downloads_button = wibox.widget {
+ {
+ dl_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ downloads_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('xdg-open $(xdg-user-dir DOWNLOAD)')
+ end
+ )
+ )
+ )
+
+ awful.tooltip(
+ {
+ objects = {downloads_button},
+ mode = 'outside',
+ align = 'right',
+ text = 'Downloads',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+ )
+
+ return downloads_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/xdg-folders/home.lua b/.config/awesome/widget/xdg-folders/home.lua
new file mode 100644
index 0000000..24c3820
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/home.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local home_widget = wibox.widget {
+ {
+ image = widget_icon_dir .. 'user-home.svg',
+ resize = true,
+ widget = wibox.widget.imagebox,
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local home_button = wibox.widget {
+ {
+ home_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ home_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('xdg-open $(xdg-user-dir)')
+ end
+ )
+ )
+ )
+
+ awful.tooltip(
+ {
+ objects = {home_button},
+ mode = 'outside',
+ align = 'right',
+ text = 'Home',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+ )
+
+ return home_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/xdg-folders/icons/folder-documents.svg b/.config/awesome/widget/xdg-folders/icons/folder-documents.svg
new file mode 100644
index 0000000..e6a53e5
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/folder-documents.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/folder-download.svg b/.config/awesome/widget/xdg-folders/icons/folder-download.svg
new file mode 100644
index 0000000..9b75134
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/folder-download.svg
@@ -0,0 +1,134 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg b/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg
new file mode 100644
index 0000000..014b5b3
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg
@@ -0,0 +1,127 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/folder-videos.svg b/.config/awesome/widget/xdg-folders/icons/folder-videos.svg
new file mode 100644
index 0000000..50b53df
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/folder-videos.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/no.svg b/.config/awesome/widget/xdg-folders/icons/no.svg
new file mode 100644
index 0000000..0654b8a
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/no.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/open-folder.svg b/.config/awesome/widget/xdg-folders/icons/open-folder.svg
new file mode 100644
index 0000000..f1f131d
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/open-folder.svg
@@ -0,0 +1,110 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/user-home.svg b/.config/awesome/widget/xdg-folders/icons/user-home.svg
new file mode 100644
index 0000000..b0a0839
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/user-home.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg b/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg
new file mode 100644
index 0000000..f4d107f
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg
@@ -0,0 +1,160 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg b/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg
new file mode 100644
index 0000000..2d75d2d
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg
@@ -0,0 +1,979 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/icons/yes.svg b/.config/awesome/widget/xdg-folders/icons/yes.svg
new file mode 100644
index 0000000..2617c5d
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/icons/yes.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/.config/awesome/widget/xdg-folders/init.lua b/.config/awesome/widget/xdg-folders/init.lua
new file mode 100644
index 0000000..f0448ff
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/init.lua
@@ -0,0 +1,31 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+local dpi = beautiful.xresources.apply_dpi
+
+local create_xdg_widgets = function()
+ local separator = wibox.widget {
+ orientation = 'horizontal',
+ forced_height = dpi(1),
+ forced_width = dpi(1),
+ span_ratio = 0.55,
+ widget = wibox.widget.separator
+ }
+
+ return wibox.widget {
+ layout = wibox.layout.align.vertical,
+ {
+ separator,
+ require('widget.xdg-folders.home')(),
+ require('widget.xdg-folders.documents')(),
+ require('widget.xdg-folders.downloads')(),
+ -- require('widget.xdg-folders.pictures')(),
+ -- require('widget.xdg-folders.videos')(),
+ separator,
+ require('widget.xdg-folders.trash')(),
+ layout = wibox.layout.fixed.vertical,
+ },
+ }
+end
+
+return create_xdg_widgets
diff --git a/.config/awesome/widget/xdg-folders/pictures.lua b/.config/awesome/widget/xdg-folders/pictures.lua
new file mode 100644
index 0000000..2c591c2
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/pictures.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local pic_widget = wibox.widget {
+ {
+ image = widget_icon_dir .. 'folder-pictures.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local pic_button = wibox.widget {
+ {
+ pic_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ pic_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('xdg-open $(xdg-user-dir PICTURES)')
+ end
+ )
+ )
+ )
+
+ awful.tooltip(
+ {
+ objects = {pic_button},
+ mode = 'outside',
+ align = 'right',
+ text = 'Pictures',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+ )
+
+ return pic_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/xdg-folders/trash.lua b/.config/awesome/widget/xdg-folders/trash.lua
new file mode 100644
index 0000000..2625e5a
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/trash.lua
@@ -0,0 +1,148 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local naughty = require('naughty')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local trash_widget = wibox.widget {
+ {
+ id = 'trash_icon',
+ image = widget_icon_dir .. 'user-trash-empty.svg',
+ resize = true,
+ widget = wibox.widget.imagebox
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local trash_menu = awful.menu({
+ items = {
+ {
+ 'Open trash',
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'gio open trash:///',
+ function(stdout) end,
+ 1
+ )
+ end,
+ widget_icon_dir .. 'open-folder.svg'
+ },
+ {
+ 'Delete forever',
+ {
+ {
+ 'Yes',
+ function()
+ awful.spawn.easy_async_with_shell(
+ 'gio trash --empty',
+ function(stdout)
+ end,
+ 1
+ )
+ end,
+ widget_icon_dir .. 'yes.svg'
+ },
+ {
+ 'No',
+ '',
+ widget_icon_dir .. 'no.svg'
+ }
+ },
+ widget_icon_dir .. 'user-trash-empty.svg'
+ },
+ }
+ })
+
+ local trash_button = wibox.widget {
+ {
+ trash_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ -- Tooltip for trash_button
+ trash_tooltip = awful.tooltip {
+ objects = {trash_button},
+ mode = 'outside',
+ align = 'right',
+ markup = 'Trash',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+
+ -- Mouse event for trash_button
+ trash_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn({'gio', 'open', 'trash:///'}, false)
+ end
+ ),
+ awful.button(
+ {},
+ 3,
+ nil,
+ function()
+ trash_menu:toggle()
+ trash_tooltip.visible = not trash_tooltip.visible
+ end
+ )
+ )
+ )
+
+ -- Update icon on changes
+ local check_trash_list = function()
+ awful.spawn.easy_async_with_shell(
+ 'gio list trash:/// | wc -l',
+ function(stdout)
+ if tonumber(stdout) > 0 then
+ trash_widget.trash_icon:set_image(widget_icon_dir .. 'user-trash-full.svg')
+
+ awful.spawn.easy_async_with_shell(
+ 'gio list trash:///',
+ function(stdout)
+ trash_tooltip.markup = 'Trash contains:\n' .. stdout:gsub('\n$', '')
+ end
+ )
+ else
+ trash_widget.trash_icon:set_image(widget_icon_dir .. 'user-trash-empty.svg')
+ trash_tooltip.markup = 'Trash empty'
+ end
+ end
+ )
+ end
+
+ -- Check trash on awesome (re)-start
+ check_trash_list()
+
+ -- Kill the old process of gio monitor trash:///
+ awful.spawn.easy_async_with_shell(
+ 'ps x | grep \'gio monitor trash:///\' | grep -v grep | awk \'{print $1}\' | xargs kill',
+ function()
+ awful.spawn.with_line_callback(
+ 'gio monitor trash:///',
+ {
+ stdout = function(_)
+ check_trash_list()
+ end
+ }
+ )
+ end
+ )
+
+ return trash_button
+end
+
+return create_widget
diff --git a/.config/awesome/widget/xdg-folders/videos.lua b/.config/awesome/widget/xdg-folders/videos.lua
new file mode 100644
index 0000000..5c54088
--- /dev/null
+++ b/.config/awesome/widget/xdg-folders/videos.lua
@@ -0,0 +1,59 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/'
+
+local create_widget = function()
+ local vid_widget = wibox.widget {
+ {
+ image = widget_icon_dir .. 'folder-videos.svg',
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ local videos_button = wibox.widget {
+ {
+ vid_widget,
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ widget = clickable_container
+ }
+
+ videos_button:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ nil,
+ function()
+ awful.spawn.with_shell('xdg-open $(xdg-user-dir VIDEOS)')
+ end
+ )
+ )
+ )
+
+ awful.tooltip
+ {
+ objects = {videos_button},
+ mode = 'outside',
+ align = 'right',
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8),
+ timer_function = function()
+ return 'Videos'
+ end,
+ preferred_positions = {'top', 'bottom', 'right', 'left'}
+ }
+
+ return videos_button
+end
+
+return create_widget