diff --git a/alacritty/alacritty.yml b/alacritty/alacritty.yml
index 4f134ea..d872054 100644
--- a/alacritty/alacritty.yml
+++ b/alacritty/alacritty.yml
@@ -97,7 +97,7 @@ font:
# - (macOS) Menlo
# - (Linux/BSD) monospace
# - (Windows) Consolas
- family: MesloLGS NF
+ family: VictorMono Nerd Font
# The `style` can be specified to pick a specific face.
style: Regular
@@ -108,7 +108,7 @@ font:
#
# If the bold family is not specified, it will fall back to the
# value specified for the normal font.
- family: MesloLGS NF
+ family: VictorMono Nerd Font
# The `style` can be specified to pick a specific face.
style: Bold
@@ -119,7 +119,7 @@ font:
#
# If the italic family is not specified, it will fall back to the
# value specified for the normal font.
- family: MesloLGS NF
+ family: VictorMono Nerd Font
# The `style` can be specified to pick a specific face.
style: Italic
@@ -315,7 +315,7 @@ colors:
#
# Window opacity as a floating point number from `0.0` to `1.0`.
# The value `0.0` is completely transparent and `1.0` is opaque.
-background_opacity: 0.45
+background_opacity: 0.60
#selection:
#semantic_escape_chars: ",│`|:\"' ()[]{}<>\t"
diff --git a/awesome/awesome-wm-widgets b/awesome/awesome-wm-widgets
new file mode 160000
index 0000000..4204fa8
--- /dev/null
+++ b/awesome/awesome-wm-widgets
@@ -0,0 +1 @@
+Subproject commit 4204fa824181a90c09c4306481a7fa2538bcce52
diff --git a/awesome/binaries/profile-image b/awesome/binaries/profile-image
new file mode 100755
index 0000000..350c9ea
--- /dev/null
+++ b/awesome/binaries/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/awesome/binaries/snap b/awesome/binaries/snap
new file mode 100755
index 0000000..970cee2
--- /dev/null
+++ b/awesome/binaries/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/awesome/configuration/apps.lua b/awesome/configuration/apps.lua
new file mode 100644
index 0000000..9f62e86
--- /dev/null
+++ b/awesome/configuration/apps.lua
@@ -0,0 +1,67 @@
+local filesystem = require('gears.filesystem')
+
+local config_dir = filesystem.get_configuration_dir()
+local bin_dir = config_dir .. 'binaries/'
+
+return {
+
+ -- The default applications that we will use in keybindings and widgets
+ default = {
+ terminal = 'kitty', -- Terminal Emulator
+ text_editor = 'subl3', -- GUI Text Editor
+ web_browser = 'firefox', -- Web browser
+ file_manager = 'dolphin', -- GUI File manager
+ network_manager = 'nm-connection-editor', -- Network manager
+ bluetooth_manager = 'blueman-manager', -- Bluetooth manager
+ power_manager = 'xfce4-power-manager', -- Power manager
+ package_manager = 'pamac-manager', -- GUI Package manager
+ lock = 'awesome-client "awesome.emit_signal(\'module::lockscreen_show\')"', -- Lockscreen
+ quake = 'kitty --name QuakeTerminal', -- Quake-like Terminal
+
+ rofiglobal = 'rofi -dpi ' .. screen.primary.dpi ..
+ ' -show "Global Search" -modi "Global Search":' .. config_dir ..
+ '/configuration/rofi/sidebar/rofi-spotlight.sh' ..
+ ' -theme ' .. config_dir ..
+ '/configuration/rofi/sidebar/rofi.rasi', -- Rofi Web Search
+
+
+ rofiappmenu = 'rofi -dpi ' .. screen.primary.dpi ..
+ ' -show drun -theme ' .. config_dir ..
+ '/configuration/rofi/appmenu/rofi.rasi' -- Application Menu
+
+ -- You can add more default applications here
+ },
+
+ -- List of apps to start once on start-up
+ -- auto-start.lua module will start these
+
+ run_on_start_up = {
+
+ 'picom -b --experimental-backends --dbus --config ' ..
+ config_dir .. '/configuration/picom.conf', -- Compositor
+
+ 'blueman-applet', -- Bluetooth tray icon
+ 'mpd', -- Music Server
+ 'xfce4-power-manager', -- Power manager
+ '/usr/lib/polkit-kde-authentication-agent-1 &' ..
+ ' eval $(gnome-keyring-daemon -s --components=pkcs11,secrets,ssh,gpg)', -- Credential manager
+
+ 'xrdb $HOME/.Xresources', -- Load X Colors
+ 'nm-applet', -- NetworkManager Applet
+ 'pulseeffects --gapplication-service', -- Sound Equalizer
+ [[
+ xidlehook --not-when-fullscreen --not-when-audio --timer 600 \
+ "awesome-client 'awesome.emit_signal(\"module::lockscreen_show\")'" ""
+ ]] -- Auto lock timer
+
+ -- You can add more start-up applications here
+ },
+
+ -- List of binaries/shell scripts that will execute a certain task
+
+ bins = {
+ full_screenshot = bin_dir .. 'snap full', -- Full Screenshot
+ area_screenshot = bin_dir .. 'snap area', -- Area Selected Screenshot
+ update_profile = bin_dir .. 'profile-image' -- Update profile picture
+ }
+}
diff --git a/awesome/configuration/client/buttons.lua b/awesome/configuration/client/buttons.lua
new file mode 100644
index 0000000..e882861
--- /dev/null
+++ b/awesome/configuration/client/buttons.lua
@@ -0,0 +1,30 @@
+local awful = require('awful')
+
+local modkey = require('configuration.keys.mod').modKey
+
+return awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function(c)
+ _G.client.focus = c
+ 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/awesome/configuration/client/init.lua b/awesome/configuration/client/init.lua
new file mode 100644
index 0000000..bbd5480
--- /dev/null
+++ b/awesome/configuration/client/init.lua
@@ -0,0 +1 @@
+require('configuration.client.rules')
diff --git a/awesome/configuration/client/keys.lua b/awesome/configuration/client/keys.lua
new file mode 100644
index 0000000..9bbf23b
--- /dev/null
+++ b/awesome/configuration/client/keys.lua
@@ -0,0 +1,256 @@
+local awful = require('awful')
+local gears = require('gears')
+
+require('awful.autofocus')
+
+local modkey = require('configuration.keys.mod').modKey
+local altkey = require('configuration.keys.mod').altKey
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local clientKeys =
+ awful.util.table.join(
+
+ -- toggle fullscreen
+ awful.key(
+ {modkey},
+ 'f',
+ function(c)
+ -- Toggle fullscreen
+ c.fullscreen = not c.fullscreen
+ c:raise()
+ end,
+ {description = 'toggle fullscreen', group = 'client'}
+ ),
+
+ -- close client
+ awful.key(
+ {modkey},
+ 'q',
+ function(c)
+ c:kill()
+ end,
+ {description = 'close', group = 'client'}
+ ),
+ -- Default client focus
+ 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'}
+ ),
+ -- move floating client to center
+ 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"}
+ ),
+
+ -- toggle client floating mode
+ 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'}
+ ),
+
+ -- move client position
+ awful.key(
+ {modkey},
+ 'Up',
+ function(c)
+ if c.floating then
+ c:relative_move(0, dpi(-10), 0, 0)
+ end
+ end,
+ {description = 'move floating client up by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Down',
+ function(c)
+ if c.floating then
+ c:relative_move(0, dpi(10), 0, 0)
+ end
+ end,
+ {description = 'move floating client down by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Left',
+ function(c)
+ if c.floating then
+ c:relative_move(dpi(-10), 0, 0, 0)
+ end
+ end,
+ {description = 'move floating client to the left by 10 px', group = 'client'}
+ ),
+ awful.key(
+ {modkey},
+ 'Right',
+ function(c)
+ if c.floating then
+ c:relative_move(dpi(10), 0, 0, 0)
+ end
+ end,
+ {description = 'move floating client to the right by 10 px', group = 'client'}
+ ),
+
+ -- Increasing floating client size
+ awful.key(
+ {modkey, 'Shift'},
+ 'Up',
+ function(c)
+ if c.floating then
+ c:relative_move(0, dpi(-10), 0, dpi(10))
+ end
+ end,
+ {description = 'increase floating client size vertically by 10 px up', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Down',
+ function(c)
+ if c.floating then
+ c:relative_move(0, 0, 0, dpi(10))
+ end
+ end,
+ {description = 'increase floating client size vertically by 10 px down', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Left',
+ function(c)
+ if c.floating then
+ c:relative_move(dpi(-10), 0, dpi(10), 0)
+ end
+ end,
+ {description = 'increase floating client size horizontally by 10 px left', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Shift'},
+ 'Right',
+ function(c)
+ if c.floating then
+ c:relative_move(0, 0, dpi(10), 0)
+ end
+ end,
+ {description = 'increase floating client size horizontally by 10 px right', group = 'client'}
+ ),
+
+ -- Decreasing floating client size
+ awful.key(
+ {modkey, 'Control'},
+ 'Up',
+ function(c)
+ if c.floating and 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)
+ if c.floating then
+ 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
+ end,
+ {description = 'decrease floating client size vertically by 10 px down', group = 'client'}
+ ),
+ awful.key(
+ {modkey, 'Control'},
+ 'Left',
+ function(c)
+ if c.floating and 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)
+ if c.floating then
+ 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
+ end,
+ {description = 'decrease floating client size horizontally by 10 px right', group = 'client'}
+ )
+)
+
+return clientKeys
diff --git a/awesome/configuration/client/rules.lua b/awesome/configuration/client/rules.lua
new file mode 100644
index 0000000..bd16fe4
--- /dev/null
+++ b/awesome/configuration/client/rules.lua
@@ -0,0 +1,415 @@
+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,
+ round_corners = true,
+ keys = client_keys,
+ buttons = client_buttons,
+ screen = awful.screen.preferred,
+ placement = awful.placement.no_overlap + awful.placement.no_offscreen
+ }
+ }
+
+ -- 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,
+ draw_backdrop = true,
+ skip_decoration = true,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
+ end,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Modals
+ ruled.client.append_rule {
+ id = "dialog",
+ rule_any = {
+ type = { "modal" }
+ },
+ properties = {
+ titlebars_enabled = true,
+ floating = true,
+ above = true,
+ draw_backdrop = true,
+ skip_decoration = true,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
+ end,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Utilities
+ ruled.client.append_rule {
+ id = "utility",
+ rule_any = {
+ type = { "utility" }
+ },
+ properties = {
+ titlebars_enabled = false,
+ floating = true,
+ hide_titlebars = true,
+ draw_backdrop = false,
+ skip_decoration = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Splash
+ ruled.client.append_rule {
+ id = "splash",
+ rule_any = {
+ type = { "splash" }
+ },
+ properties = {
+ titlebars_enabled = false,
+ floating = true,
+ above = true,
+ hide_titlebars = true,
+ draw_backdrop = false,
+ skip_decoration = true,
+ shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
+ end,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- terminal emulators
+ ruled.client.append_rule {
+ id = "terminals",
+ rule_any = {
+ class = {
+ "URxvt",
+ "XTerm",
+ "UXTerm",
+ "kitty",
+ "K3rmit"
+ }
+ },
+ except_any = {
+ instance = { "QuakeTerminal" }
+ },
+ properties = {
+ tag = '1',
+ switchtotag = true,
+ draw_backdrop = false,
+ size_hints_honor = false
+ }
+ }
+
+ -- Browsers
+ ruled.client.append_rule {
+ id = "web_browsers",
+ rule_any = {
+ class = {
+ "firefox",
+ "Tor Browser",
+ "discord",
+ "Chromium",
+ "Google-chrome"
+ }
+ },
+ properties = {
+ tag = '2'
+ }
+ }
+
+ -- text editors
+ ruled.client.append_rule {
+ id = "text_editors",
+ rule_any = {
+ class = {
+ "Geany",
+ "Atom",
+ "Subl3",
+ "code-oss"
+ },
+ name = {
+ "LibreOffice",
+ "libreoffice"
+ }
+ },
+ properties = {
+ tag = '3'
+ }
+ }
+
+ -- File managers
+ ruled.client.append_rule {
+ id = "file_managers",
+ rule_any = {
+ class = {
+ "dolphin",
+ "ark",
+ "Nemo",
+ "File-roller"
+ }
+ },
+ properties = {
+ tag = '4',
+ switchtotag = true
+ }
+ }
+
+ -- Multimedia
+ ruled.client.append_rule {
+ id = "multimedia",
+ rule_any = {
+ class = {
+ "vlc",
+ "Spotify"
+ }
+ },
+ properties = {
+ tag = '5',
+ switchtotag = true,
+ draw_backdrop = false
+ }
+ }
+
+ -- Gaming
+ ruled.client.append_rule {
+ id = "gaming",
+ rule_any = {
+ class = {
+ "Wine",
+ "dolphin-emu",
+ "Steam",
+ "Citra",
+ "SuperTuxKart"
+ },
+ name = { "Steam" }
+ },
+ properties = {
+ tag = '6',
+ skip_decoration = true,
+ draw_backdrop = false,
+ switchtotag = true,
+ floating = true,
+ hide_titlebars = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Graphics Editing
+ ruled.client.append_rule {
+ id = "graphics_editors",
+ 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"
+ }
+ },
+ properties = {
+ tag = '8'
+ }
+ }
+
+ -- IDEs and Tools
+ ruled.client.append_rule {
+ id = "ide",
+ rule_any = {
+ class = {
+ "Oomox",
+ "Unity",
+ "UnityHub",
+ "jetbrains-studio"
+ }
+ },
+ properties = {
+ tag = '9',
+ skip_decoration = true
+ }
+ }
+
+ -- Image viewers with splash-like behaviour
+ ruled.client.append_rule {
+ id = "splash_like",
+ rule_any = {
+ class = {
+ "feh",
+ "Pqiv",
+ "Sxiv"
+ },
+ name = {"Discord Updater"}
+ },
+ properties = {
+ skip_decoration = true,
+ hide_titlebars = true,
+ floating = true,
+ ontop = true,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Splash-like but with titlebars enabled
+ ruled.client.append_rule {
+ id = "instances",
+ rule_any = {
+ instance = {
+ "file_progress",
+ "Popup",
+ "nm-connection-editor",
+ },
+ class = {
+ "scrcpy" ,
+ "Mugshot",
+ "Pulseeffects"
+ }
+ },
+ properties = {
+ skip_decoration = true,
+ round_corners = true,
+ ontop = true,
+ floating = true,
+ draw_backdrop = false,
+ focus = awful.client.focus.filter,
+ raise = true,
+ keys = client_keys,
+ buttons = client_buttons,
+ placement = awful.placement.centered
+ }
+ }
+
+ -- Fullsreen
+ ruled.client.append_rule {
+ id = "fullscreen",
+ rule_any = {
+ class = {
+ "SuperTuxKart"
+ }
+ },
+ properties = {
+ skip_decoration = true,
+ round_corners = false,
+ ontop = true,
+ floating = false,
+ fullscreen = true,
+ draw_backdrop = false,
+ raise = true,
+ keys = client_keys,
+ buttons = client_buttons,
+ placement = awful.placement.centered
+ }
+ }
+
+ end
+)
+
+
+-- Normally we'd do this with a rule, but other apps like spotify and supertuxkart doesn't set its class or name
+-- until after it starts up, so we need to catch that signal.
+
+-- If the application is fullscreen in its settings, make sure to set `c.fullscreen = false` first
+-- before moving to the desired tag or else the tag where the program spawn will cause panels to hide.
+-- After moving the program to specified tag you can set `c.fullscreen = true` now
+-- See what I did in `SuperTuxKart`
+
+client.connect_signal(
+ "property::class",
+ function(c)
+ if c.class == "Spotify" then
+ -- Check if Spotify is already open
+ local spotify = function (c)
+ return ruled.client.match(c, { class = "Spotify" })
+ end
+
+ local spotify_count = 0
+ for c in awful.client.iterate(spotify) do
+ spotify_count = spotify_count + 1
+ end
+
+ -- If Spotify is already open, don't open a new instance
+ if spotify_count > 1 then
+ c:kill()
+ -- Switch to previous instance
+ for c in awful.client.iterate(spotify) do
+ c:jump_to(false)
+ end
+ else
+ -- Move the Spotify instance to "5" tag on this screen
+ local t = awful.tag.find_by_name(awful.screen.focused(), "5")
+ c:move_to_tag(t)
+ end
+ elseif c.class == "SuperTuxKart" then
+ -- Disable fullscreen first
+ c.fullscreen = false
+
+ -- Check if SuperTuxKart is already open
+ local stk = function (c)
+ return ruled.client.match(c, { class = "SuperTuxKart" })
+ end
+
+ local stk_count = 0
+ for c in awful.client.iterate(stk) do
+ stk_count = stk_count + 1
+ end
+
+ -- If SuperTuxKart is already open, don't open a new instance
+ if stk_count > 1 then
+ c:kill()
+ -- Switch to previous instance
+ for c in awful.client.iterate(stk) do
+ c:jump_to(false)
+ end
+ else
+ -- Move the instance to specified tag tag on this screen
+ local t = awful.tag.find_by_name(awful.screen.focused(), "6")
+ c:move_to_tag(t)
+ t:view_only()
+ -- Enable fullscreeen again
+ c.fullscreen = true
+ end
+ end
+
+ end
+)
\ No newline at end of file
diff --git a/awesome/configuration/init.lua b/awesome/configuration/init.lua
new file mode 100644
index 0000000..f93e86b
--- /dev/null
+++ b/awesome/configuration/init.lua
@@ -0,0 +1,4 @@
+return {
+ keys = require('configuration.keys'),
+ apps = require('configuration.apps')
+}
diff --git a/awesome/configuration/keys/global.lua b/awesome/configuration/keys/global.lua
new file mode 100644
index 0000000..817203a
--- /dev/null
+++ b/awesome/configuration/keys/global.lua
@@ -0,0 +1,564 @@
+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').modKey
+local altkey = require('configuration.keys.mod').altKey
+local apps = require('configuration.apps')
+
+-- Key bindings
+local globalKeys = 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},
+ '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
+ client.focus = c
+ 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},
+ '`',
+ function()
+ _G.toggle_quake()
+ 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.bins.full_screenshot,function() end)
+ end,
+ {description = "fullscreen screenshot", group = 'Utility'}
+ ),
+ awful.key(
+ {modkey, "Shift"},
+ 's',
+ function ()
+ awful.spawn.easy_async_with_shell(apps.bins.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:HideDashboard()
+ focused.left_panel.opened = false
+ end
+ if focused.right_panel then
+ focused.right_panel:HideDashboard()
+ focused.right_panel.opened = false
+ end
+ awful.spawn(apps.default.rofiappmenu, 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 notification center", 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 today pane", 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
+ globalKeys =
+ awful.util.table.join(
+ globalKeys,
+ -- 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 globalKeys
diff --git a/awesome/configuration/keys/init.lua b/awesome/configuration/keys/init.lua
new file mode 100644
index 0000000..9591667
--- /dev/null
+++ b/awesome/configuration/keys/init.lua
@@ -0,0 +1,4 @@
+return {
+ mod = require('configuration.keys.mod'),
+ global = require('configuration.keys.global')
+}
diff --git a/awesome/configuration/keys/mod.lua b/awesome/configuration/keys/mod.lua
new file mode 100644
index 0000000..1062e04
--- /dev/null
+++ b/awesome/configuration/keys/mod.lua
@@ -0,0 +1,4 @@
+return {
+ modKey = 'Mod4',
+ altKey = 'Mod1'
+}
diff --git a/awesome/configuration/picom.conf b/awesome/configuration/picom.conf
new file mode 100644
index 0000000..317c24b
--- /dev/null
+++ b/awesome/configuration/picom.conf
@@ -0,0 +1,152 @@
+
+# ▀ ▄▀▀
+# ▄▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄ ▄▄▄ ▄ ▄▄ ▄▄█▄▄
+# █▀ ▀█ █ █▀ ▀ █▀ ▀█ █ █ █ █▀ ▀ █▀ ▀█ █▀ █ █
+# █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
+# ██▄█▀ ▄▄█▄▄ ▀█▄▄▀ ▀█▄█▀ █ █ █ █ ▀█▄▄▀ ▀█▄█▀ █ █ █
+# █
+# ▀
+
+
+
+
+# Shadow
+
+shadow = true;
+shadow-radius = 12;
+shadow-offset-x = -12;
+shadow-offset-y = -12;
+shadow-opacity = 0.7;
+
+# shadow-red = 0.0;
+# shadow-green = 0.0;
+# shadow-blue = 0.0;
+
+# shadow-exclude-reg = "x10+0+0";
+# xinerama-shadow-crop = true;
+
+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'"
+];
+
+# Logs
+log-level = "ERROR";
+log-file = "~/.cache/picom-log.log";
+
+
+# Opacity
+
+# inactive-opacity = 0.8;
+# active-opacity = 0.8;
+# frame-opacity = 0.7;
+inactive-opacity-override = false;
+
+opacity-rule = [
+ "80:class_g = 'URxvt'",
+ "80:class_g = 'UXTerm'",
+ "80:class_g = 'XTerm'"
+];
+
+# inactive-dim = 0.2;
+# inactive-dim-fixed = true;
+
+
+# Blur
+
+blur: {
+ method = "dual_kawase";
+ strength = 3.2;
+ # deviation = 1.0;
+ # kernel = "11x11gaussian";
+}
+
+# blur-background = true;
+blur-background-frame = true;
+blur-background-fixed = true;
+# blur-kern = "3x3box";
+# blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1";
+
+blur-background-exclude = [
+ "window_type = 'desktop'",
+ "window_type = 'utility'",
+ "window_type = 'notification'",
+ "class_g = 'slop'",
+ "class_g = 'Firefox' && argb",
+ "name = 'rofi - Global Search'",
+ "_GTK_FRAME_EXTENTS@:c"
+];
+
+# max-brightness = 0.66
+
+# Fading
+
+fading = true;
+fade-delta = 3;
+fade-in-step = 0.03;
+fade-out-step = 0.03;
+# no-fading-openclose = true;
+# no-fading-destroyed-argb = true;
+fade-exclude = [ ];
+
+# Other
+
+backend = "glx";
+mark-wmwin-focused = true;
+mark-ovredir-focused = true;
+# use-ewmh-active-win = true;
+detect-rounded-corners = true;
+detect-client-opacity = true;
+refresh-rate = 0;
+vsync = true;
+# sw-opti = true;
+unredir-if-possible = false;
+# unredir-if-possible-delay = 5000;
+# unredir-if-possible-exclude = [ ];
+# focus-exclude = [ "class_g = 'Cairo-clock'" ];
+
+focus-exclude = [
+ "class_g = 'Cairo-clock'",
+ "class_g ?= 'rofi'",
+ "class_g ?= 'slop'",
+ "class_g ?= 'Steam'"
+];
+
+
+detect-transient = true;
+detect-client-leader = true;
+invert-color-include = [ ];
+# resize-damage = 1;
+
+# GLX backend
+
+glx-no-stencil = true;
+# glx-no-rebind-pixmap = true;
+# xrender-sync-fence = true;
+use-damage = true;
+
+# Window type settings
+
+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; };
+ notification = { shadow = false; };
+ desktop = { shadow = false };
+ menu = { focus = false };
+ dialog = { shadow = true; };
+};
diff --git a/awesome/configuration/rofi/appmenu/rofi.rasi b/awesome/configuration/rofi/appmenu/rofi.rasi
new file mode 100644
index 0000000..28d59f2
--- /dev/null
+++ b/awesome/configuration/rofi/appmenu/rofi.rasi
@@ -0,0 +1,152 @@
+configuration {
+ font: "SF Pro Text Regular 10";
+ show-icons: true;
+ drun-display-format: "{name}";
+ fullscreen: false;
+ threads: 0;
+ matching: "fuzzy";
+ scroll-method: 0;
+ disable-history: false;
+ monitor: "primary";
+ window-thumbnail: true;
+}
+
+* {
+ background: #00000000;
+ background-color: #00000066;
+ background-entry: #00000033;
+ background-alt: #f2f2f215;
+ foreground: #f2f2f2EE;
+ foreground-selected: #ffffffFF;
+ urgent: #E91E6366;
+ urgent-selected: #E91E6377;
+}
+
+window {
+ transparency: "real";
+ background-color: @background;
+ text-color: @foreground;
+ height: 740px;
+ width: 1321px;
+ location: northwest;
+ anchor: northwest;
+ x-offset: 45;
+ y-offset: 28;
+}
+
+prompt {
+ enabled: false;
+}
+
+button {
+ action: "ok";
+ str: " ";
+ font: "FantasqueSansMono Nerd Font 11";
+ expand: false;
+ text-color: @foreground;
+ background-color: @background;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+entry {
+ font: "SF Pro Text Regular 11";
+ background-color: @background;
+ text-color: @foreground;
+ expand: true;
+ vertical-align: 0.5;
+ horizontal-align: 0.0;
+ placeholder: "Type to search";
+ placeholder-color: @foreground;
+ blink: true;
+}
+
+case-indicator {
+ background-color: @background;
+ text-color: @foreground;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+entry-wrapper {
+ orientation: horizontal;
+ vertical-align: 0.5;
+ spacing: 4px;
+ background-color: @background;
+ children: [ case-indicator, entry, button ];
+}
+
+inputbar {
+ background-color: @background-alt;
+ text-color: @foreground;
+ expand: false;
+ border-radius: 6px;
+ margin: 0px 405px 0px 405px;
+ padding: 10px 10px 10px 10px;
+ position: north;
+ children: [ entry-wrapper ];
+}
+
+listview {
+ background-color: @background;
+ columns: 7;
+ spacing: 4px;
+ cycle: false;
+ dynamic: true;
+ layout: vertical;
+}
+
+mainbox {
+ background-color: @background-color;
+ children: [ inputbar, listview ];
+ spacing: 25px;
+ padding: 45px 135px 45px 135px;
+}
+
+element {
+ background-color: @background;
+ text-color: @foreground;
+ orientation: vertical;
+ border-radius: 9px;
+ padding: 25px 0px 25px 0px;
+}
+
+element-icon {
+ size: 64px;
+ border: 0px;
+}
+
+element-text {
+ expand: true;
+ horizontal-align: 0.5;
+ vertical-align: 0.5;
+ margin: 5px 10px 0px 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-alt;
+ text-color: @foreground;
+}
+
+element selected {
+ background-color: @background-alt;
+ text-color: @foreground-selected;
+}
+
+element selected.urgent {
+ background-color: @urgent-selected;
+ text-color: @foreground;
+}
+
+element selected.active {
+ background-color: @background-alt;
+ color: @foreground-selected;
+}
\ No newline at end of file
diff --git a/awesome/configuration/rofi/sidebar/icons/ddg.svg b/awesome/configuration/rofi/sidebar/icons/ddg.svg
new file mode 100644
index 0000000..20ea387
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/icons/ddg.svg
@@ -0,0 +1,615 @@
+
+
+
+
diff --git a/awesome/configuration/rofi/sidebar/icons/google.svg b/awesome/configuration/rofi/sidebar/icons/google.svg
new file mode 100644
index 0000000..21e5bf3
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/icons/google.svg
@@ -0,0 +1,365 @@
+
+
+
+
diff --git a/awesome/configuration/rofi/sidebar/icons/history.svg b/awesome/configuration/rofi/sidebar/icons/history.svg
new file mode 100644
index 0000000..872bac8
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/icons/history.svg
@@ -0,0 +1,75 @@
+
+
diff --git a/awesome/configuration/rofi/sidebar/icons/result.svg b/awesome/configuration/rofi/sidebar/icons/result.svg
new file mode 100644
index 0000000..0f4d883
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/icons/result.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/configuration/rofi/sidebar/icons/suggestion.svg b/awesome/configuration/rofi/sidebar/icons/suggestion.svg
new file mode 100644
index 0000000..bf67346
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/icons/suggestion.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/awesome/configuration/rofi/sidebar/rofi-spotlight.sh b/awesome/configuration/rofi/sidebar/rofi-spotlight.sh
new file mode 100755
index 0000000..d262d1c
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/rofi-spotlight.sh
@@ -0,0 +1,745 @@
+#!/usr/bin/env bash
+
+# ----------------------------------------------------------------------------
+# --- Rofi File Browser
+# --
+# --
+# -- @author manilarome <gerome.matilla07@gmail.com>
+# -- @copyright 2020 manilarome
+# -- @script rofi-spotlight.sh
+# ----------------------------------------------------------------------------
+
+TMP_DIR="/tmp/rofi/${USER}/"
+
+PREV_LOC_FILE="${TMP_DIR}rofi_fb_prevloc"
+CURRENT_FILE="${TMP_DIR}rofi_fb_current_file"
+
+MY_PATH="$(dirname "${0}")"
+HIST_FILE="${MY_PATH}/history.txt"
+
+OPENER=xdg-open
+TERM_EMU=kitty
+TEXT_EDITOR=${EDITOR}
+FILE_MANAGER=dolphin
+BLUETOOTH_SEND=blueman-sendto
+
+CUR_DIR=$PWD
+
+NEXT_DIR=""
+
+SHOW_HIDDEN=false
+
+declare -a SHELL_OPTIONS=(
+ "Run"
+ "Execute in ${TERM_EMU}"
+ "Edit"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+
+declare -a SHELL_NO_X_OPTIONS=(
+ "Edit"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+
+declare -a BIN_OPTIONS=(
+ "Run"
+ "Execute in ${TERM_EMU}"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Back"
+)
+
+declare -a BIN_NO_X_OPTIONS=(
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Back"
+)
+
+declare -a TEXT_OPTIONS=(
+ "Edit"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+
+declare -a XCF_SVG_OPTIONS=(
+ "Open"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+
+declare -a IMAGE_OPTIONS=(
+ "Open"
+ "Send via Bluetooth"
+ "Open file location in ${TERM_EMU}"
+ "Open file location in ${FILE_MANAGER}"
+ "Move to trash"
+ "Delete"
+ "Back"
+)
+
+declare -a ALL_OPTIONS=()
+
+# Combine all context menu
+COMBINED_OPTIONS=(
+ "${SHELL_OPTIONS[@]}"
+ "${SHELL_NO_X_OPTIONS[@]}"
+ "${BIN_OPTIONS[@]}"
+ "${BIN_NO_X_OPTIONS[@]}"
+ "${TEXT_OPTIONS[@]}"
+ "${XCF_SVG_OPTIONS[@]}"
+ "${IMAGE_OPTIONS[@]}"
+)
+
+# Remove duplicates
+while IFS= read -r -d '' x; do
+ ALL_OPTIONS+=("$x")
+done < <(printf "%s\0" "${COMBINED_OPTIONS[@]}" | sort -uz)
+
+# Create tmp dir for rofi
+if [ ! -d "${TMP_DIR}" ]
+then
+ mkdir -p "${TMP_DIR}";
+fi
+
+# Create hist file if it doesn't exist
+if [ ! -f "${HIST_FILE}" ]
+then
+ touch "${HIST_FILE}"
+fi
+
+# Help message
+if [[ ! -z "$@" ]] && [[ "$@" == ":help" ]]
+then
+
+ echo "Rofi Spotlight"
+ echo "A Rofi with file and web searching functionality"
+ echo " "
+ echo "Commands:"
+ echo ":help to print this help message"
+ echo ":h or :hidden to show hidden files/dirs"
+ echo ":sh or :show_hist to show search history"
+ echo ":ch or :clear_hist to clear search history"
+ echo ":xdg to jump to an xdg directory"
+ echo "Examples:"
+ echo " :xdg DOCUMENTS"
+ echo " :xdg DOWNLOADS"
+ echo "Also supports incomplete path:"
+ echo "Examples:"
+ echo " :xdg doc"
+ echo " :xdg down"
+ echo "For more info about XDG dirs, see:"
+ echo "\`man xdg-user-dir\`"
+ echo " "
+ echo "File search syntaxes:"
+ echo "! to search for a file and web suggestions"
+ echo "? to search parent directories"
+ echo "Examples:"
+ echo " !half-life 3"
+ echo " ?portal 3"
+ echo " "
+ echo "Web search syntaxes:"
+ echo "! to gets search suggestions"
+ echo ":web/:w to also to gets search suggestions"
+ echo ":webbro/:wb to search directly from your browser"
+ echo "Examples:"
+ echo " !how to install archlinux"
+ echo " :web how to install gentoo"
+ echo " :w how to make a nuclear fission"
+ echo " :webbro how to install wine in windowsxp"
+
+ 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'
+ ;;
+ "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 "${1}""\0icon\x1f""${icon_name}""\n"
+}
+
+
+# Pass the argument to python scrupt
+function web_search() {
+ # Pass the search query to web-search script
+ python "${MY_PATH}/web-search.py" "${1}"
+ exit;
+}
+
+# Handles the web search method
+if [ ! -z "$@" ] && ([[ "$@" == ":webbro"* ]] || [[ "$@" == ":wb"* ]])
+then
+ remove=''
+
+ if [[ "$@" == ":webbro"* ]]
+ then
+ remove=":webbro"
+ else
+ remove=":wb"
+ fi
+
+ # Search directly from your web browser
+ web_search "$(printf '%s\n' "${1//$remove/}")"
+ exit;
+
+elif [ ! -z "$@" ] && ([[ "$@" == ":web"* ]] || [[ "$@" == ":w"* ]])
+then
+ remove=''
+
+ if [[ "$@" == ":web"* ]]
+ then
+ remove=":web"
+ else
+ remove=":w"
+ fi
+
+ # Get search suggestions
+ web_search "!$(printf '%s\n' "${1//$remove/}")"
+ exit;
+fi
+
+# File and calls to the web search
+if [ ! -z "$@" ] && ([[ "$@" == /* ]] || [[ "$@" == \?* ]] || [[ "$@" == \!* ]])
+then
+ QUERY=$@
+
+ echo "${QUERY}" >> "${HIST_FILE}"
+
+ if [[ "$@" == /* ]]
+ then
+
+ if [[ "$@" == *\?\? ]]
+ then
+ coproc ( ${OPENER} "${QUERY%\/* \?\?}" > /dev/null 2>&1 )
+ exec 1>&-
+ exit;
+ else
+ coproc ( ${OPENER} "$@" > /dev/null 2>&1 )
+ exec 1>&-
+ exit;
+ fi
+
+ elif [[ "$@" == \?* ]]
+ then
+ while read -r line
+ do
+ echo "$line" \?\?
+ done <<< $(find "${HOME}" -iname *"${QUERY#\?}"* 2>&1 | grep -v 'Permission denied\|Input/output error')
+
+ else
+ # Find the file
+ find "${HOME}" -iname *"${QUERY#!}"* -exec echo -ne \
+ "{}\0icon\x1f${MY_PATH}/icons/result.svg\n" \; 2>&1 |
+ grep -av 'Permission denied\|Input/output error'
+
+ # Web search
+ web_search "${QUERY}"
+ fi
+ exit;
+fi
+
+# Create notification if there's an error
+function create_notification() {
+ if [[ "${1}" == "denied" ]]
+ then
+ notify-send -a "Global Search" "Permission denied!" \
+ 'You have no permission to access '"${CUR_DIR}!"
+ elif [[ "${1}" == "deleted" ]]
+ then
+ notify-send -a "Global Search" "Success!" \
+ 'File deleted!'
+ elif [[ "${1}" == "trashed" ]]
+ then
+ notify-send -a "Global Search" "Success!" \
+ 'The file has been moved to trash!'
+ elif [[ "${1}" == "cleared" ]]
+ then
+ notify-send -a "Global Search" "Success!" \
+ 'Search history has been successfully cleared!'
+
+ else
+ notify-send -a "Global Search" "Somethings wrong I can feel it!" \
+ 'This incident will be reported!'
+ fi
+}
+
+# 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
+ echo "${HOME}" > "${PREV_LOC_FILE}"
+ create_notification "denied"
+
+ else
+ echo "${CUR_DIR}/" > "${PREV_LOC_FILE}"
+ fi
+ pushd "${CUR_DIR}" >/dev/null
+ fi
+
+ printf "..\0icon\x1fup\n"
+
+ if [[ ${SHOW_HIDDEN} == true ]]
+ then
+
+ for i in .*/
+ do
+ if [[ -d "${i}" ]] && ([[ "${i}" != "./" ]] && [[ "${i}" != "../"* ]])
+ then
+ printf "$(icon_file_type "${i}")";
+ fi
+ done
+
+ for i in .*
+ do
+ if [[ -f "${i}" ]]
+ then
+ printf "$(icon_file_type "${i}")";
+ fi
+ done
+
+ fi
+
+ for i in */
+ do
+ if [[ -d "${i}" ]]
+ then
+ printf "$(icon_file_type "${i}")";
+ fi
+ done
+
+ for i in *
+ do
+ if [[ -f "${i}" ]]
+ then
+ printf "$(icon_file_type "${i}")";
+ fi
+ done
+}
+
+# Set XDG dir
+function return_xdg_dir() {
+ target_dir=$(echo "$1" | tr "[:lower:]" "[:upper:]")
+
+ 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}")
+
+ if [ ! -n "${hist}" ]
+ then
+ printf ".\0icon\x1fback\n"
+ printf "No history, yet.\0icon\x1ftext-plain\n"
+ fi
+
+ while IFS= read -r line;
+ do
+ printf "${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=$(echo "$@" | awk '{print $2}')
+
+ if [[ ! -z "$NEXT_DIR" ]]
+ then
+ return_xdg_dir "${NEXT_DIR}"
+ else
+ return_xdg_dir "${HOME}"
+ fi
+
+fi
+
+# Read last location, otherwise we default to PWD.
+if [ -f "${PREV_LOC_FILE}" ]
+then
+ CUR_DIR=$(cat "${PREV_LOC_FILE}")
+fi
+
+if [[ ! -z "$@" ]] && ([[ "$@" == ":h" ]] || [[ "$@" == ":hidden" ]])
+then
+ SHOW_HIDDEN=true
+ navigate_to
+ exit;
+fi
+
+# Handle argument.
+if [ -n "$@" ]
+then
+ CUR_DIR="${CUR_DIR}/$@"
+fi
+
+
+# Context Menu
+if [[ ! -z "$@" ]] && [[ "${ALL_OPTIONS[*]} " == *"${1}"* ]]
+then
+ case "${1}" in
+ "Run" )
+ coproc ( eval "$(cat "${CURRENT_FILE}")" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Execute in ${TERM_EMU}" )
+ coproc ( eval "${TERM_EMU} "$(cat "${CURRENT_FILE}")"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Open" )
+ coproc ( eval "${OPENER} "$(cat "${CURRENT_FILE}")"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Open file location in ${TERM_EMU}" )
+ file_path="$(cat "${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="$(cat "${CURRENT_FILE}")"
+ coproc ( eval "${FILE_MANAGER} "${file_path%/*}"" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Edit" )
+ coproc ( eval "${TERM_EMU} ${TEXT_EDITOR} $(cat "${CURRENT_FILE}")" & > /dev/null 2>&1 )
+ kill -9 $(pgrep rofi)
+ ;;
+ "Move to trash" )
+ coproc( gio trash "$(cat "${CURRENT_FILE}")" & > /dev/null 2>&1 )
+ create_notification "trashed"
+ CUR_DIR="$(dirname $(cat "${CURRENT_FILE}"))"
+ navigate_to
+ ;;
+ "Delete" )
+ shred "$(cat "${CURRENT_FILE}")"
+ rm "$(cat "${CURRENT_FILE}")"
+ create_notification "deleted"
+ CUR_DIR="$(dirname $(cat "${CURRENT_FILE}"))"
+ navigate_to
+ ;;
+ "Send via Bluetooth" )
+ rfkill unblock bluetooth && bluetoothctl power on
+ sleep 1
+ blueman-sendto "$(cat "${CURRENT_FILE}")" & > /dev/null 2>&1
+ kill -9 $(pgrep rofi)
+ ;;
+ "Back" )
+ CUR_DIR=$(cat "${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}" == "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 "${HOME}" -iname *"${QUERY#!}"* -exec echo -ne \
+ "{}\0icon\x1f${MY_PATH}/icons/result.svg\n" \; 2>&1 |
+ grep -av 'Permission denied\|Input/output error'
+
+ 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/awesome/configuration/rofi/sidebar/rofi.rasi b/awesome/configuration/rofi/sidebar/rofi.rasi
new file mode 100644
index 0000000..01ee1ee
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/rofi.rasi
@@ -0,0 +1,155 @@
+configuration {
+ font: "SF Pro Text Regular 10";
+ show-icons: true;
+ fullscreen: false;
+ sidebar-mode: true;
+ threads: 0;
+ matching: "fuzzy";
+ scroll-method: 0;
+ monitor: "primary";
+}
+
+* {
+ background: #00000000;
+ background-color: #00000000;
+ background-entry: #00000033;
+ background-alt: #f2f2f215;
+ foreground: #f2f2f2EE;
+ foreground-selected: #ffffffFF;
+ urgent: #E91E6366;
+ urgent-selected: #E91E6377;
+}
+
+window {
+ transparency: "real";
+ background: @background;
+ location: west;
+ anchor: west;
+ x-offset: 0px;
+ height: 100%;
+ width: 350px;
+ orientation: vertical;
+}
+
+mainbox {
+ background-color: @background;
+ spacing: 0px;
+ padding: 5px 5px 5px 5px;
+ width: 200px;
+ expand: true;
+ spacing: 12px;
+ children: [ inputbar, listview];
+}
+
+scrollbar {
+ background-color: @background-alt;
+ handle-width: 10px;
+ margin: 0px 0px 5px 0px;
+ border-radius: 9px;
+}
+
+listview {
+ background-color: @background;
+ spacing: 0px;
+ dynamic: true;
+ cycle: true;
+ scrollbar: true;
+}
+
+prompt {
+ enabled: false;
+}
+
+button {
+ action: "ok";
+ str: " ";
+ font: "FantasqueSansMono Nerd Font 16";
+ expand: false;
+ text-color: @foreground;
+ background-color: @background;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+
+entry {
+ font: "SF Pro Text Regular 12";
+ background-color: @background;
+ placeholder-color: @foreground;
+ placeholder: "Global Search";
+ blink: true;
+ expand: true;
+ text-color: @foreground;
+ vertical-align: 0.5;
+}
+
+entry-wrapper {
+ orientation: horizontal;
+ vertical-align: 0.5;
+ spacing: 4px;
+ background-color: @background;
+ children: [ button, entry ];
+}
+
+inputbar {
+ padding: 14px;
+ margin: 10px 10px 14px 10px;
+ background-color: @background-alt;
+ text-color: @foreground;
+ expand: false;
+ border-radius: 9px;
+ position: north;
+ children: [ entry-wrapper ];
+}
+
+element {
+ margin: 0px 12px 0px 12px;
+ background-color: @background;
+ text-color: @foreground;
+ orientation: horizontal;
+ border-radius: 0px;
+ padding: 10px 12px 10px 12px;
+ border: 0 0 2px;
+ border-color: @background-alt;
+}
+
+element-icon {
+ size: 16px;
+ border-color: @background;
+ border: 2px;
+}
+
+element-text {
+ font: "SF Pro Text Regular 11";
+ expand: true;
+ horizontal-align: 0.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-alt;
+ text-color: @foreground;
+}
+
+element selected {
+ background-color: @background-alt;
+ text-color: @foreground-selected;
+}
+
+element selected.urgent {
+ background-color: @urgent-selected;
+ text-color: @foreground;
+}
+
+element selected.active {
+ background-color: @background-alt;
+ color: @foreground-selected;
+}
diff --git a/awesome/configuration/rofi/sidebar/web-search.py b/awesome/configuration/rofi/sidebar/web-search.py
new file mode 100755
index 0000000..ba314d5
--- /dev/null
+++ b/awesome/configuration/rofi/sidebar/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/awesome/configuration/root/init.lua b/awesome/configuration/root/init.lua
new file mode 100644
index 0000000..176f13e
--- /dev/null
+++ b/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.rofiappmenu)
+ 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/awesome/configuration/secrets.lua b/awesome/configuration/secrets.lua
new file mode 100644
index 0000000..c66a5e0
--- /dev/null
+++ b/awesome/configuration/secrets.lua
@@ -0,0 +1,45 @@
+
+-- Credentials Manager
+
+-- How to get a valid credentials for email widget?
+-- The widget uses an IMAP.
+-- So it means any email service provider that provides an IMAP support is supported by the widget.
+-- First, you need an email_address.
+-- Second, you must generate an app password for your account. Your account password WILL NOT WORK!
+-- Just search in the internet on how to generate for your email service provider.
+-- For example `create app password for gmail account`
+-- Third, you need an imap_server.
+-- Just get your email service provider's imap server. Gmail's imap server is `imap.gmail.com`
+-- Fourth, provide the port.
+-- Just search it in the internet. Gmail's port is `993`
+
+
+
+-- How to get a credentials for weather widget?
+-- OpenWeatherMap is our weather provider. So go to `https://home.openweathermap.org/`
+-- Register, log-in, and then go to `https://home.openweathermap.org/api_keys`
+-- You can create your API keys there.
+-- For `units`, you have to choose for yourself.
+-- `metric` or 'imperial'
+-- metric uses °C, while imperial uses °F
+
+
+return {
+
+ email = {
+
+ address = '',
+ app_password = '',
+ imap_server = 'imap.gmail.com',
+ port = '993'
+
+ },
+
+ weather = {
+
+ key = '',
+ city_id = '',
+ units = 'metric'
+
+ }
+}
\ No newline at end of file
diff --git a/awesome/configuration/tags/init.lua b/awesome/configuration/tags/init.lua
new file mode 100644
index 0000000..9ea43c3
--- /dev/null
+++ b/awesome/configuration/tags/init.lua
@@ -0,0 +1,109 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local icons = require('theme.icons')
+
+local tags = {
+ {
+ icon = icons.terminal,
+ type = 'terminal',
+ default_app = 'kitty',
+ screen = 1
+ },
+ {
+ icon = icons.web_browser,
+ type = 'chrome',
+ default_app = 'firefox',
+ screen = 1
+ },
+ {
+ icon = icons.text_editor,
+ type = 'code',
+ default_app = 'subl3',
+ screen = 1
+ },
+ {
+ icon = icons.file_manager,
+ type = 'files',
+ default_app = 'nemo',
+ screen = 1
+ },
+ {
+ icon = icons.multimedia,
+ type = 'music',
+ default_app = 'vlc',
+ screen = 1
+ },
+ {
+ icon = icons.games,
+ type = 'game',
+ default_app = 'supertuxkart',
+ screen = 1
+ },
+ {
+ icon = icons.graphics,
+ type = 'art',
+ default_app = 'gimp-2.10',
+ screen = 1
+ },
+ {
+ icon = icons.sandbox,
+ type = 'virtualbox',
+ default_app = 'virtualbox',
+ screen = 1
+ },
+ {
+ icon = icons.development,
+ type = 'any',
+ default_app = '',
+ screen = 1
+ }
+ -- {
+ -- icon = icons.social,
+ -- type = 'social',
+ -- default_app = 'discord',
+ -- screen = 1
+ -- }
+}
+
+
+tag.connect_signal("request::default_layouts", function()
+ awful.layout.append_default_layouts({
+ awful.layout.suit.spiral.dwindle,
+ awful.layout.suit.tile,
+ awful.layout.suit.max
+ })
+end)
+
+
+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 = awful.layout.suit.spiral.dwindle,
+ gap_single_client = false,
+ gap = beautiful.useless_gap,
+ screen = s,
+ default_app = tag.default_app,
+ selected = i == 1
+ }
+ )
+ end
+end)
+
+
+tag.connect_signal(
+ 'property::layout',
+ function(t)
+ local currentLayout = awful.tag.getproperty(t, 'layout')
+ if (currentLayout == awful.layout.suit.max) then
+ t.gap = 0
+ else
+ t.gap = beautiful.useless_gap
+ end
+ end
+)
diff --git a/awesome/configuration/user-profile/default.svg b/awesome/configuration/user-profile/default.svg
new file mode 100644
index 0000000..14f8006
--- /dev/null
+++ b/awesome/configuration/user-profile/default.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/awesome/evil/battery.lua b/awesome/evil/battery.lua
new file mode 100644
index 0000000..4a8a413
--- /dev/null
+++ b/awesome/evil/battery.lua
@@ -0,0 +1,49 @@
+-- Provides:
+-- evil::battery
+-- percentage (integer)
+-- evil::charger
+-- plugged (boolean)
+
+local awful = require("awful")
+
+local update_interval = 60
+
+local battery_script = [[
+ sh -c "
+ upower -i $(upower -e | grep BAT) | grep percentage | awk '{print $2}'
+ "
+]]
+
+-- Subscribe to power supply status changes with acpi_listen
+local charger_script = [[
+ sh -c '
+ acpi_listen | grep --line-buffered ac_adapter
+ '
+]]
+
+-- Periodically get battery info
+awful.widget.watch(battery_script, update_interval, function(widget, stdout)
+ local battery = stdout:gsub("%%", "")
+ awesome.emit_signal("evil::battery", tonumber(battery))
+end)
+
+local emit_charger_info = function()
+ awful.spawn.easy_async_with_shell("cat /sys/class/power_supply/*/online", function (out)
+ local status = tonumber(out) == 1
+ awesome.emit_signal("evil::charger", status)
+ end)
+end
+
+-- Run once to initialize widgets
+emit_charger_info()
+
+-- Kill old acpi_listen process
+awful.spawn.easy_async_with_shell("ps x | grep \"acpi_listen\" | grep -v grep | awk '{print $1}' | xargs kill", function ()
+ -- Update charger status with each line printed
+ awful.spawn.with_line_callback(charger_script, {
+ stdout = function(_)
+ emit_charger_info()
+ end
+ })
+end)
+
diff --git a/awesome/glorious.rc.lua b/awesome/glorious.rc.lua
new file mode 100644
index 0000000..0d00091
--- /dev/null
+++ b/awesome/glorious.rc.lua
@@ -0,0 +1,118 @@
+
+-- ▄▄ ▄ ▄ ▄ ▄
+-- ██ ▄ ▄ ▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄ █ █ █ ██ ██
+-- █ █ ▀▄ ▄ ▄▀ █▀ █ █ ▀ █▀ ▀█ █ █ █ █▀ █ ▀ █▀█ █ █ ██ █
+-- █▄▄█ █▄█▄█ █▀▀▀▀ ▀▀▀▄ █ █ █ █ █ █▀▀▀▀ ██ ██▀ █ ▀▀ █
+-- █ █ █ █ ▀█▄▄▀ ▀▄▄▄▀ ▀█▄█▀ █ █ █ ▀█▄▄▀ █ █ █ █
+
+-- Banner generated using `toilet -f mono9 AwesomeWM"
+
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+
+require('awful.autofocus')
+
+-- ========================================
+-- Theme
+-- Load the Aesthetics
+-- ========================================
+beautiful.init(require('theme'))
+
+-- ========================================
+-- Layouts
+-- Load the Panels
+-- ========================================
+
+require('layout')
+
+-- ========================================
+-- Modules
+-- Load all the modules
+-- ========================================
+
+require('module.notifications')
+require('module.auto-start')
+require('module.decorate-client')
+-- require('module.backdrop')
+require('module.exit-screen')
+require('module.quake-terminal')
+require('module.titlebar')
+require('module.menu')
+require('module.volume-osd')
+require('module.brightness-osd')
+require('module.dynamic-wallpaper')
+require('module.battery-notifier')
+require('module.lockscreen')
+
+-- ========================================
+-- Configuration
+-- Load your prefrences
+-- ========================================
+
+require('configuration.client')
+require('configuration.root')
+require('configuration.tags')
+root.keys(require('configuration.keys.global'))
+
+
+-- ========================================
+-- Signals
+-- Signals Listeners and Senders
+-- ========================================
+
+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
+ if beautiful.wallpaper:sub(1, #"#") == "#" then
+ gears.wallpaper.set(beautiful.wallpaper)
+ elseif beautiful.wallpaper:sub(1, #"/") == "/" then
+ gears.wallpaper.maximized(beautiful.wallpaper, s)
+ end
+ else
+ beautiful.wallpaper(s)
+ end
+ end
+
+end)
+
+-- Signal function to execute when a new client appears.
+client.connect_signal(
+ 'manage',
+ function(c)
+ -- Set the windows at the slave,
+ -- i.e. put it at the end of others instead of setting it master.
+ if not _G.awesome.startup then
+ awful.client.setslave(c)
+ end
+
+ if _G.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
+ end
+)
+
+-- Enable sloppy focus, so that focus follows mouse.
+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
+)
diff --git a/awesome/layout/init.lua b/awesome/layout/init.lua
new file mode 100644
index 0000000..a13a980
--- /dev/null
+++ b/awesome/layout/init.lua
@@ -0,0 +1,72 @@
+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
+ -- Create the left_panel
+ s.left_panel = left_panel(s)
+ -- Create the Top bar
+ s.top_panel = top_panel(s, true)
+ else
+ -- Create the Top bar
+ 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 updateBarsVisibility()
+ for s in screen do
+ focused = awful.screen.focused()
+ if s.selected_tag then
+ local fullscreen = s.selected_tag.fullscreenMode
+ -- 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 focused.right_panel.visible then
+ focused.right_panel:toggle()
+ focused.right_panel_show_again = true
+ elseif not fullscreen and not focused.right_panel.visible and focused.right_panel_show_again then
+ focused.right_panel:toggle()
+ focused.right_panel_show_again = false
+ end
+ end
+ end
+ end
+end
+
+tag.connect_signal(
+ 'property::selected',
+ function(t)
+ updateBarsVisibility()
+ end
+)
+
+client.connect_signal(
+ 'property::fullscreen',
+ function(c)
+ if c.first_tag then
+ c.first_tag.fullscreenMode = c.fullscreen
+ end
+ updateBarsVisibility()
+ end
+)
+
+client.connect_signal(
+ 'unmanage',
+ function(c)
+ if c.fullscreen then
+ c.screen.selected_tag.fullscreenMode = false
+ updateBarsVisibility()
+ end
+ end
+)
diff --git a/awesome/layout/left-panel/action-bar.lua b/awesome/layout/left-panel/action-bar.lua
new file mode 100755
index 0000000..0cde0c1
--- /dev/null
+++ b/awesome/layout/left-panel/action-bar.lua
@@ -0,0 +1,74 @@
+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 home_button = wibox.widget {
+ {
+ menu_icon,
+ widget = clickable_container
+ },
+ bg = beautiful.background .. '66',
+ widget = wibox.container.background
+ }
+
+ home_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,
+ home_button
+ }
+end
diff --git a/awesome/layout/left-panel/dashboard/hardware-monitor.lua b/awesome/layout/left-panel/dashboard/hardware-monitor.lua
new file mode 100644
index 0000000..350a8f2
--- /dev/null
+++ b/awesome/layout/left-panel/dashboard/hardware-monitor.lua
@@ -0,0 +1,72 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local hardware_header = wibox.widget
+{
+
+ text = 'Hardware Monitor',
+ font = 'SF Pro Text 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
+
+ },
+ {
+ require('widget.cpu.cpu-meter'),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius)
+ end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+ {
+ require('widget.ram.ram-meter'),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius)
+ end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+ {
+ require('widget.temperature.temperature-meter'),
+ bg = beautiful.groups_bg,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius)
+ end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+
+ },
+ {
+ require('widget.harddrive.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,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+}
diff --git a/awesome/layout/left-panel/dashboard/init.lua b/awesome/layout/left-panel/dashboard/init.lua
new file mode 100644
index 0000000..6074534
--- /dev/null
+++ b/awesome/layout/left-panel/dashboard/init.lua
@@ -0,0 +1,137 @@
+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 = 'SF Pro Text 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
+ )
+ )
+ )
+
+ 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 = 'SF Pro Text 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
+ }
+
+ 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,
+ function()
+ panel:toggle()
+ awesome.emit_signal("module::exit_screen_show")
+ 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,
+ exit_button,
+ layout = wibox.layout.align.vertical
+ },
+ margins = dpi(16),
+ widget = wibox.container.margin
+
+ }
+end
diff --git a/awesome/layout/left-panel/dashboard/quick-settings.lua b/awesome/layout/left-panel/dashboard/quick-settings.lua
new file mode 100644
index 0000000..fc221ae
--- /dev/null
+++ b/awesome/layout/left-panel/dashboard/quick-settings.lua
@@ -0,0 +1,105 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local bar_color = beautiful.groups_bg
+
+local quick_header = wibox.widget
+{
+
+ text = 'Quick Settings',
+ font = 'SF Pro Text 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
+
+ },
+
+ {
+ require('widget.brightness.brightness-slider'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+
+ },
+ {
+ require('widget.volume.volume-slider'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+
+ },
+
+ {
+ require('widget.network.network-toggle'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+
+ {
+ require('widget.bluetooth.bluetooth-toggle'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, false, false, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+ {
+ require('widget.blue-light'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ }
+ },
+ {
+ layout = wibox.layout.fixed.vertical,
+ {
+ require('widget.window-effects.blur-toggle'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ },
+ {
+ require('widget.window-effects.blur-strength-slider'),
+ bg = bar_color,
+ shape = function(cr, width, height)
+ gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius) end,
+ forced_height = dpi(48),
+ widget = wibox.container.background
+ }
+ }
+}
diff --git a/awesome/layout/left-panel/init.lua b/awesome/layout/left-panel/init.lua
new file mode 100644
index 0000000..f112ff8
--- /dev/null
+++ b/awesome/layout/left-panel/init.lua
@@ -0,0 +1,124 @@
+local awful = require('awful')
+local beautiful = require('beautiful')
+local wibox = require('wibox')
+local apps = require('configuration.apps')
+local dpi = require('beautiful').xresources.apply_dpi
+
+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 - 500,
+ x = screen.geometry.x,
+ y = screen.geometry.y + 250,
+ ontop = false,
+ 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()
+ _G.awesome.spawn(
+ apps.default.rofiglobal,
+ 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
+
+ local openPanel = function(should_run_rofi)
+ panel.width = action_bar_width + panel_content_width
+ backdrop.visible = true
+ panel.visible = false
+ panel.visible = true
+ 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 closePanel = function()
+ panel.width = action_bar_width
+ panel:get_children_by_id('panel_content')[1].visible = false
+ backdrop.visible = false
+ panel:emit_signal('closed')
+ end
+
+ -- Hide this panel when app dashboard is called.
+ function panel:HideDashboard()
+ closePanel()
+ end
+
+ function panel:toggle(should_run_rofi)
+ self.opened = not self.opened
+ if self.opened then
+ openPanel(should_run_rofi)
+ else
+ closePanel()
+ 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/awesome/layout/right-panel/icons/notification.svg b/awesome/layout/right-panel/icons/notification.svg
new file mode 100644
index 0000000..c60cf96
--- /dev/null
+++ b/awesome/layout/right-panel/icons/notification.svg
@@ -0,0 +1,111 @@
+
+
diff --git a/awesome/layout/right-panel/init.lua b/awesome/layout/right-panel/init.lua
new file mode 100644
index 0000000..fede772
--- /dev/null
+++ b/awesome/layout/right-panel/init.lua
@@ -0,0 +1,175 @@
+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,
+ 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:HideDashboard()
+ 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('layout.right-panel.panel-mode-switcher'),
+ 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/awesome/layout/right-panel/panel-mode-switcher.lua b/awesome/layout/right-panel/panel-mode-switcher.lua
new file mode 100644
index 0000000..0617c38
--- /dev/null
+++ b/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 = 'SF Pro Text 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 = 'SF Pro Text 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/awesome/layout/right-panel/right-panel-opener.lua b/awesome/layout/right-panel/right-panel-opener.lua
new file mode 100644
index 0000000..cfc2e4e
--- /dev/null
+++ b/awesome/layout/right-panel/right-panel-opener.lua
@@ -0,0 +1,62 @@
+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')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'layout/right-panel/icons/'
+
+
+-- ▄▄▄▄▄ ▄ ▄
+-- █ █ ▄ ▄ ▄▄█▄▄ ▄▄█▄▄ ▄▄▄ ▄ ▄▄
+-- █▄▄▄▄▀ █ █ █ █ █▀ ▀█ █▀ █
+-- █ █ █ █ █ █ █ █ █ █
+-- █▄▄▄▄▀ ▀▄▄▀█ ▀▄▄ ▀▄▄ ▀█▄█▀ █ █
+
+
+-- The button in top panel
+
+local return_button = function()
+
+ local widget =
+ wibox.widget {
+ {
+ id = 'icon',
+ image = widget_icon_dir .. 'notification' .. '.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
\ No newline at end of file
diff --git a/awesome/layout/top-panel.lua b/awesome/layout/top-panel.lua
new file mode 100755
index 0000000..4c822da
--- /dev/null
+++ b/awesome/layout/top-panel.lua
@@ -0,0 +1,336 @@
+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 TopPanel = 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.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,
+ placement = awful.placement.bottom_right
+ }
+ )
+ end
+ )
+ )
+ )
+
+
+ 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
+
+
+ s.clock_widget = wibox.widget.textclock(
+ '%l:%M %p',
+ 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'},
+ 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 ' .. os.date('%A') .. ' ya idiot!'
+
+ 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 = 'SF Pro Text Regular 10',
+ long_weekdays = true,
+ margin = dpi(5),
+ screen = s,
+ style_month = {
+ border_width = dpi(0),
+ 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
+ }
+ )
+
+
+ s.systray = wibox.widget {
+ visible = false,
+ base_size = dpi(20),
+ horizontal = true,
+ screen = 'primary',
+ widget = wibox.widget.systray
+ }
+
+
+ s.tray_toggler = require('widget.tray-toggler')
+ s.updater = require('widget.package-updater')()
+ s.screen_rec = require('widget.screen-recorder')()
+ s.music = require('widget.music')()
+ s.bluetooth = require('widget.bluetooth')()
+ s.network = require('widget.network')()
+ s.battery = require('widget.battery')()
+ s.r_dashboard = require('layout.right-panel.right-panel-opener')()
+
+
+ panel : setup {
+ layout = wibox.layout.align.horizontal,
+ expand = "none",
+ {
+ layout = wibox.layout.fixed.horizontal,
+ task_list(s),
+ s.add_button
+ },
+ s.clock_widget,
+ {
+ 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.music,
+ s.bluetooth,
+ s.network,
+ s.battery,
+ layout_box(s),
+ s.r_dashboard
+ }
+ }
+
+ return panel
+end
+
+
+return TopPanel
diff --git a/awesome/library/liblua_pam.so b/awesome/library/liblua_pam.so
new file mode 100755
index 0000000..858bb1e
Binary files /dev/null and b/awesome/library/liblua_pam.so differ
diff --git a/awesome/module/auto-start.lua b/awesome/module/auto-start.lua
new file mode 100644
index 0000000..339d4f7
--- /dev/null
+++ b/awesome/module/auto-start.lua
@@ -0,0 +1,35 @@
+-- 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 apps = require('configuration.apps')
+
+local debugger_mode = 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 debugger_mode then
+ return
+ end
+ require('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/awesome/module/backdrop.lua b/awesome/module/backdrop.lua
new file mode 100644
index 0000000..ffb6a09
--- /dev/null
+++ b/awesome/module/backdrop.lua
@@ -0,0 +1,83 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+
+local function update_backdrop(w, c)
+ local cairo = require('lgi').cairo
+ local geo = c.screen.geometry
+
+ w.x = geo.x
+ w.y = geo.y
+ w.width = geo.width
+ w.height = geo.height
+
+ -- Create an image surface that is as large as the wibox
+ 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 = c:geometry()
+ local c_shape = gears.surface(c.shape_bounding)
+ cr:set_source_rgba(0, 0, 0, 0)
+ cr:mask_surface(c_shape, c_geo.x + c.border_width - geo.x, c_geo.y + c.border_width - geo.y)
+ c_shape:finish()
+
+ w.shape_bounding = shape._native
+ shape:finish()
+ w:draw()
+end
+
+local function backdrop(c)
+ local function update()
+ update_backdrop(c.backdrop, c)
+ end
+ if not c.backdrop then
+ c.backdrop = wibox {ontop = true, bg = '#00000054', type = 'splash'}
+ c.backdrop:buttons(
+ awful.util.table.join(
+ awful.button(
+ {},
+ 1,
+ function()
+ c:kill()
+ end
+ )
+ )
+ )
+ c:connect_signal('property::geometry', update)
+ c:connect_signal(
+ 'property::shape_client_bounding',
+ function()
+ gears.timer.delayed_call(update)
+ end
+ )
+ c:connect_signal(
+ 'unmanage',
+ function()
+ c.backdrop.visible = false
+ end
+ )
+ c:connect_signal(
+ 'property::shape_bounding',
+ function()
+ gears.timer.delayed_call(update)
+ end
+ )
+ end
+ update()
+ c.backdrop.visible = true
+end
+
+client.connect_signal(
+ 'manage',
+ function(c)
+ if c.draw_backdrop == true then
+ backdrop(c)
+ end
+ end
+)
diff --git a/awesome/module/battery-notifier.lua b/awesome/module/battery-notifier.lua
new file mode 100644
index 0000000..3c56696
--- /dev/null
+++ b/awesome/module/battery-notifier.lua
@@ -0,0 +1,157 @@
+-- Battery notification module
+-- Dependencies:
+-- acpid, upower, acpi_listens, acpi_call
+-- enabled acpid service
+
+local awful = require('awful')
+local naughty = require('naughty')
+local icons = require('theme.icons')
+
+local update_interval = 30
+
+-- Periodically get battery info
+awful.widget.watch(
+ [[
+ sh -c "
+ upower -i $(upower -e | grep BAT) | grep percentage | awk '{print $2}'
+ "]],
+ update_interval,
+ function(widget, stdout)
+ local battery = stdout:gsub("%%", "")
+ awesome.emit_signal("module::battery", tonumber(battery))
+ end
+)
+
+local emit_charger_info = function()
+ awful.spawn.easy_async_with_shell(
+ "cat /sys/class/power_supply/*/online",
+ function (stdout)
+ status = tonumber(stdout)
+ if status == 1 then
+ awesome.emit_signal("module::charger", true)
+ else
+ awesome.emit_signal("module::charger", false)
+ end
+ end
+ )
+end
+
+emit_charger_info()
+
+awful.spawn.easy_async_with_shell(
+ "ps x | grep \"acpi_listen\" | grep -v grep | awk '{print $1}' | xargs kill",
+ function ()
+ awful.spawn.with_line_callback(
+ [[
+ sh -c '
+ acpi_listen | grep --line-buffered ac_adapter
+ ']],
+ {
+ stdout = function(_)
+ emit_charger_info()
+ end
+ }
+ )
+ end
+)
+
+local charger_plugged = true
+local battery_full_already_notified = true
+local battery_low_already_notified = false
+local battery_critical_already_notified = false
+
+local last_notification
+
+local function send_notification(title, text, icon, timeout, urgency)
+
+ local args = {
+ title = title,
+ text = text,
+ icon = icon,
+ timeout = timeout,
+ urgency = urgency,
+ app_name = 'Power Notification'
+ }
+
+ if last_notification and not last_notification.is_expired then
+ last_notification.title = args.title
+ last_notification.text = args.text
+ last_notification.icon = args.icon
+ else
+ last_notification = naughty.notification(args)
+ end
+
+ last_notification = notification
+end
+
+-- Full / Low / Critical notifications
+awesome.connect_signal("module::battery", function(battery)
+
+ local text
+ local icon
+ local timeout
+ if not charger_plugged then
+
+ icon = icons.batt_discharging
+
+ if battery < 6 and not battery_critical_already_notified then
+ battery_critical_already_notified = true
+ text = "Battery Critical!"
+ timeout = 0
+ urgency = 'critical'
+ elseif battery < 16 and not battery_low_already_notified then
+ battery_low_already_notified = true
+ text = "Battery Full!"
+ timeout = 6
+ urgency = 'normal'
+ end
+
+ else
+ icon = icons.batt_charging
+ if battery ~= nil then
+ if battery > 99 and not battery_full_already_notified then
+ battery_full_already_notified = true
+ text = "Battery Full!"
+ timeout = 6
+ urgency = 'normal'
+ end
+ end
+ end
+
+ -- If text has been initialized, then we need to send a
+ -- notification
+ if text then
+ send_notification("Battery status", text, icon, timeout, urgency)
+ end
+
+end)
+
+-- Charger notifications
+local charger_first_time = true
+awesome.connect_signal("module::charger", function(plugged)
+ charger_plugged = plugged
+ local text
+ local icon
+ -- TODO if charger is plugged and battery is full, then set
+ -- battery_full_already_notified to true
+ if plugged then
+ battery_critical_already_notified = false
+ battery_low_already_notified = false
+ text = "Plugged"
+ icon = icons.batt_charging
+ urgency = 'normal'
+ else
+ battery_full_already_notified = false
+ text = "Unplugged"
+ icon = icons.batt_discharging
+ urgency = 'normal'
+ end
+
+ -- Do not send a notification the first time (when AwesomeWM (re)starts)
+ if charger_first_time then
+ charger_first_time = false
+ else
+ send_notification("Charger Status", text, icon, 3, urgency)
+ end
+end)
+
diff --git a/awesome/module/brightness-osd.lua b/awesome/module/brightness-osd.lua
new file mode 100644
index 0000000..7c0288f
--- /dev/null
+++ b/awesome/module/brightness-osd.lua
@@ -0,0 +1,272 @@
+local awful = require("awful")
+local gears = require("gears")
+local wibox = require("wibox")
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+local spawn = require('awful.spawn')
+
+screen.connect_signal("request::desktop_decoration", function(s)
+
+ s.show_bri_osd = false
+
+ local osd_header = wibox.widget {
+ text = 'Brightness',
+ font = 'VictorMono Nerd Font 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local osd_value = wibox.widget {
+ text = '0%',
+ font = 'VictorMono Nerd Font 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
+
+ -- Update brightness level using slider value
+ bri_osd_slider:connect_signal(
+ 'property::value',
+ function()
+
+ local brightness_level = bri_osd_slider:get_value()
+
+ 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 s.show_bri_osd then
+ awesome.emit_signal(
+ 'module::brightness_osd:show',
+ true
+ )
+ end
+
+ end
+ )
+
+ bri_osd_slider:connect_signal(
+ 'button::press',
+ function()
+ s.show_bri_osd = true
+ end
+ )
+ bri_osd_slider:connect_signal(
+ 'button::release',
+ function()
+ s.show_bri_osd = false
+ end
+ )
+ bri_osd_slider:connect_signal(
+ 'mouse::enter',
+ function()
+ s.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
+ }
+
+ -- Create the box
+ local osd_height = dpi(100)
+ local osd_width = dpi(300)
+
+ local osd_margin = dpi(10)
+
+ 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()
+ }
+
+ local hide_osd = gears.timer {
+ timeout = 2,
+ autostart = true,
+ callback = function()
+ awful.screen.focused().brightness_osd_overlay.visible = false
+ end
+ }
+
+ local timer_rerun = function()
+ if hide_osd.started then
+ hide_osd:again()
+ else
+ hide_osd:start()
+ end
+ end
+
+ -- Reset timer on mouse hover
+ s.brightness_osd_overlay:connect_signal(
+ 'mouse::enter',
+ function()
+ s.show_bri_osd = true
+ timer_rerun()
+ end
+ )
+ s.brightness_osd_overlay:connect_signal(
+ 'mouse::enter',
+ function()
+ s.show_bri_osd = false
+ timer_rerun()
+ 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.brightness_osd_overlay
+
+ if right_panel and left_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(focused.brightness_osd_overlay, { margins = {
+ left = osd_margin + left_panel.width,
+ right = 0,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ return
+ end
+ end
+
+ if right_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(focused.brightness_osd_overlay, { margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ return
+ end
+ end
+
+ awful.placement.bottom_right(focused.brightness_osd_overlay, { margins = {
+ left = 0,
+ right = osd_margin,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ end
+
+ awesome.connect_signal(
+ 'module::brightness_osd:show',
+ function(bool)
+ placement_placer()
+ awful.screen.focused().brightness_osd_overlay.visible = bool
+ if bool then
+ timer_rerun()
+ awesome.emit_signal(
+ 'module::volume_osd:show',
+ false
+ )
+ else
+ if hide_osd.started then
+ hide_osd:stop()
+ end
+ end
+ end
+ )
+
+
+end)
diff --git a/awesome/module/decorate-client.lua b/awesome/module/decorate-client.lua
new file mode 100644
index 0000000..7c45111
--- /dev/null
+++ b/awesome/module/decorate-client.lua
@@ -0,0 +1,112 @@
+local awful = require('awful')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local function render_client(client, mode)
+
+ if client.skip_decoration or (client.rendering_mode == mode) then
+ return
+ end
+
+ client.rendering_mode = mode
+ client.floating = false
+ client.maximized = false
+ client.above = false
+ client.below = false
+ client.ontop = false
+ client.sticky = false
+ client.maximized_horizontal = false
+ client.maximized_vertical = false
+
+ if client.rendering_mode == 'maximized' then
+ client.border_width = 0
+ client.shape = function(cr, w, h)
+ gears.shape.rectangle(cr, w, h)
+ end
+ elseif client.rendering_mode ~= 'maximized' then
+ client.border_width = beautiful.border_width
+ client.shape = function(cr, w, h)
+ gears.shape.rounded_rect(cr, w, h, beautiful.client_radius)
+ end
+ end
+
+end
+
+local changes_on_screen_called = false
+
+local function changes_on_screen(current_screen)
+
+ local tag_is_max = current_screen.selected_tag ~= nil and
+ current_screen.selected_tag.layout == awful.layout.suit.max
+
+ local clients_to_manage = {}
+
+ for _, client in pairs(current_screen.clients) do
+ if not client.skip_decoration and not client.hidden then
+ table.insert(clients_to_manage, client)
+ end
+ end
+
+ if (tag_is_max or #clients_to_manage == 1) then
+ current_screen.client_mode = 'maximized'
+ else
+ current_screen.client_mode = 'dwindle'
+ end
+
+ for _, client in pairs(clients_to_manage) do
+ render_client(client, current_screen.client_mode)
+ end
+ changes_on_screen_called = false
+end
+
+
+function client_callback(client)
+ if not changes_on_screen_called then
+ if not client.skip_decoration and client.screen then
+ changes_on_screen_called = true
+ local screen = client.screen
+ gears.timer.delayed_call(
+ function()
+ changes_on_screen(screen)
+ end
+ )
+ end
+ end
+end
+
+function tag_callback(tag)
+ if not changes_on_screen_called then
+ if tag.screen then
+ changes_on_screen_called = true
+ local screen = tag.screen
+ gears.timer.delayed_call(
+ function()
+ changes_on_screen(screen)
+ end
+ )
+ end
+ end
+end
+
+client.connect_signal('manage', client_callback)
+
+client.connect_signal('unmanage', client_callback)
+
+client.connect_signal('property::hidden', client_callback)
+
+client.connect_signal('property::minimized', client_callback)
+
+client.connect_signal(
+ 'property::fullscreen',
+ function(c)
+ if c.fullscreen then
+ render_client(c, 'maximized')
+ else
+ client_callback(c)
+ end
+ end
+)
+
+tag.connect_signal('property::selected', tag_callback)
+
+tag.connect_signal('property::layout', tag_callback)
diff --git a/awesome/module/dynamic-wallpaper.lua b/awesome/module/dynamic-wallpaper.lua
new file mode 100755
index 0000000..e13f99c
--- /dev/null
+++ b/awesome/module/dynamic-wallpaper.lua
@@ -0,0 +1,225 @@
+----------------------------------------------------------------------------
+--- 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 filesystem = require('gears.filesystem')
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+
+-- ========================================
+-- Configuration
+-- Change your preference here
+-- ========================================
+
+-- Wallpaper directory. The default is:
+local wall_dir = filesystem.get_configuration_dir() .. 'theme/wallpapers/'
+-- local wall_dir = os.getenv('HOME') .. 'Pictures/Wallpapers/'
+
+
+-- Wallpapers filename
+-- Note:
+-- Default image format is jpg
+wallpaper_morning = 'morning-wallpaper.jpg'
+wallpaper_noon = 'noon-wallpaper.jpg'
+wallpaper_night = 'night-wallpaper.jpg'
+wallpaper_midnight = 'midnight-wallpaper.jpg'
+
+
+-- Change the wallpaper on scheduled time
+morning_schedule = '06:22:00'
+noon_schedule = '12:00:00'
+night_schedule = '17:58:00'
+midnight_schedule = '24:00:00'
+
+
+-- Update lockscreen background
+local update_ls_bg = false
+
+-- Update lockscreen background command
+local update_ls_cmd = 'mantablockscreen --image'
+
+
+
+-- ========================================
+-- 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
+the_countdown = nil
+
+
+-- We will use an array for hour change and wallpaper string
+-- Element 0 errm 1 will store the incoming/next scheduled time
+-- Geez why the f is lua's array starts with `1`? lol
+-- Element 2 will have the wallpaper file name
+local wall_data = {}
+-- > Why array, you say?
+-- Because why not? I'm new to lua and I'm experimenting with it
+
+
+-- Parse HH:MM:SS to seconds
+local parse_to_seconds = function(time)
+
+ -- Convert HH in HH:MM:SS
+ hour_sec = tonumber(string.sub(time, 1, 2)) * 3600
+
+ -- Convert MM in HH:MM:SS
+ min_sec = tonumber(string.sub(time, 4, 5)) * 60
+
+ -- Get SS in HH:MM:SS
+ 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(current, schedule)
+ local diff = parse_to_seconds(current) - parse_to_seconds(schedule)
+ return diff
+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)
+ gears.timer.start_new(0, function()
+
+ local wall_dir = wall_dir .. wall_name
+
+ gears.wallpaper.maximized (wall_dir, s)
+
+ -- Overwrite the default wallpaper
+ -- This is important in case we add an extra monitor
+ beautiful.wallpaper = wall_dir
+
+ if update_ls_bg then
+ awful.spawn.easy_async_with_shell(update_ls_cmd .. ' ' .. wall_dir, function()
+ --
+ end)
+ end
+ end)
+end
+
+-- Updates variables
+local manage_timer = function()
+
+ -- Get current time
+ local time_now = parse_to_seconds(current_time())
+
+ -- Parse the schedules to seconds
+ local parsed_morning = parse_to_seconds(morning_schedule)
+ local parsed_noon = parse_to_seconds(noon_schedule)
+ local parsed_night = parse_to_seconds(night_schedule)
+ local parsed_midnight = parse_to_seconds('00:00:00')
+
+ -- Note that we will use '00:00:00' instead of '24:00:00' as midnight
+ -- As the latter causes an error. The time_diff() returns a negative value
+
+ if time_now >= parsed_midnight and time_now < parsed_morning then
+ -- Midnight time
+
+ -- Update Wallpaper
+ update_wallpaper(wallpaper_midnight)
+
+ -- Set the data for the next scheduled time
+ wall_data = {morning_schedule, wallpaper_morning}
+
+ elseif time_now >= parsed_morning and time_now < parsed_noon then
+ -- Morning time
+
+ -- Update Wallpaper
+ update_wallpaper(wallpaper_morning)
+
+ -- Set the data for the next scheduled time
+ wall_data = {noon_schedule, wallpaper_noon}
+
+ elseif time_now >= parsed_noon and time_now < parsed_night then
+ -- Noon time
+
+ -- Update Wallpaper
+ update_wallpaper(wallpaper_noon)
+
+ -- Set the data for the next scheduled time
+ wall_data = {night_schedule, wallpaper_night}
+
+ else
+ -- Night time
+
+ -- Update Wallpaper
+ update_wallpaper(wallpaper_night)
+
+ -- Set the data for the next scheduled time
+ wall_data = {midnight_schedule, wallpaper_midnight}
+
+ end
+
+
+ -- Get the time difference to set as timeout for the wall_updater timer below
+ the_countdown = time_diff(wall_data[1], 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()
+
+ -- Update wallpaper based on the data in the array
+ gears.wallpaper.maximized (wall_dir .. wall_data[2], s)
+
+ -- 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)
\ No newline at end of file
diff --git a/awesome/module/exit-screen.lua b/awesome/module/exit-screen.lua
new file mode 100644
index 0000000..df27656
--- /dev/null
+++ b/awesome/module/exit-screen.lua
@@ -0,0 +1,351 @@
+local awful = require('awful')
+local gears = require('gears')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local icons = require('theme.icons')
+local apps = require('configuration.apps')
+local clickable_container = require('widget.clickable-container')
+
+local filesystem = gears.filesystem
+local config_dir = filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'configuration/user-profile/'
+
+
+local greeter_message = wibox.widget {
+ markup = 'Choose wisely!',
+ font = 'SF Pro Text UltraLight 48',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local profile_name = wibox.widget {
+ markup = 'user@hostname',
+ font = 'SF Pro Text Regular 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(110),
+ clip_shape = gears.shape.circle,
+ widget = wibox.widget.imagebox
+}
+
+local profile_imagebox_bg = wibox.widget {
+ bg = beautiful.groups_bg,
+ forced_width = dpi(120),
+ forced_height = dpi(120),
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+}
+
+local update_profile_pic = function()
+ awful.spawn.easy_async_with_shell(
+ apps.bins.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_profile_pic()
+
+local update_user_name = function()
+ awful.spawn.easy_async_with_shell(
+ "printf \"$(whoami)@$(hostname)\"",
+ function(stdout)
+ local stdout = stdout:gsub('%\n','')
+ local username = stdout:match("(.*)@")
+ username = username:sub(1, 1):upper() .. username:sub(2)
+ greeter_message:set_markup('Choose wisely, ' .. username .. '!')
+ profile_name:set_markup(stdout)
+ end
+ )
+end
+
+update_user_name()
+
+local build_button = function(icon, name)
+
+ local button_text = wibox.widget {
+ text = name,
+ font = beautiful.font,
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local a_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 build_a_button = wibox.widget {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ a_button,
+ button_text
+ }
+
+ return build_a_button
+end
+
+local suspend_command = function()
+ awesome.emit_signal("module::exit_screen_hide")
+ awful.spawn.with_shell(apps.default.lock .. ' & systemctl suspend')
+end
+
+local exit_command = function()
+ awesome.quit()
+end
+
+local lock_command = function()
+ awesome.emit_signal("module::exit_screen_hide")
+ awful.spawn.with_shell('sleep 1 && ' .. 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_button(icons.power, 'Shutdown')
+poweroff:connect_signal(
+ 'button::release',
+ function()
+ poweroff_command()
+ end
+)
+
+local reboot = build_button(icons.restart, 'Restart')
+reboot:connect_signal(
+ 'button::release',
+ function()
+ reboot_command()
+ end
+)
+
+local suspend = build_button(icons.sleep, 'Sleep')
+suspend:connect_signal(
+ 'button::release',
+ function()
+ suspend_command()
+ end
+)
+
+local exit = build_button(icons.logout, 'Logout')
+exit:connect_signal(
+ 'button::release',
+ function()
+ exit_command()
+ end
+)
+
+local lock = build_button(icons.lock, 'Lock')
+lock:connect_signal(
+ 'button::release',
+ function()
+ lock_command()
+ end
+)
+
+screen.connect_signal(
+ "request::desktop_decoration",
+ 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
+ }
+
+ local exit_screen_hide = function()
+ awesome.emit_signal("module::exit_screen_hide")
+
+ 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
+ exit_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()
+ exit_screen_grabber:stop()
+ for s in screen do
+ s.exit_screen.visible = false
+ end
+ end
+ )
+
+ 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 {
+ nil,
+ {
+ nil,
+ {
+ {
+ nil,
+ {
+ layout = wibox.layout.fixed.vertical,
+ spacing = dpi(5),
+ {
+ profile_imagebox_bg,
+ {
+ layout = wibox.layout.align.vertical,
+ expand = 'none',
+ nil,
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ profile_imagebox,
+ nil
+ },
+ nil
+ },
+ layout = wibox.layout.stack
+ },
+ profile_name
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ {
+ greeter_message,
+ {
+ poweroff,
+ reboot,
+ suspend,
+ exit,
+ lock,
+ layout = wibox.layout.fixed.horizontal
+ },
+ spacing = dpi(30),
+ layout = wibox.layout.fixed.vertical
+ },
+ spacing = dpi(40),
+ layout = wibox.layout.fixed.vertical
+ },
+ nil
+ },
+ spacing = dpi(40),
+ layout = wibox.layout.fixed.vertical
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.vertical
+ }
+
+ end
+)
\ No newline at end of file
diff --git a/awesome/module/lockscreen.lua b/awesome/module/lockscreen.lua
new file mode 100755
index 0000000..d057e82
--- /dev/null
+++ b/awesome/module/lockscreen.lua
@@ -0,0 +1,896 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local naughty = require('naughty')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local filesystem = require('gears.filesystem')
+local config_dir = filesystem.get_configuration_dir()
+
+local apps = require('configuration.apps')
+
+local widget_icon_dir = config_dir .. 'configuration/user-profile/'
+
+package.cpath = package.cpath .. ";" .. config_dir .. "/library/?.so;"
+local pam = require('liblua_pam')
+
+-- General Configuration
+local capture_intruder = true -- Capture a picture using webcam
+local face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/' -- Save location, auto creates
+
+-- Background Mode Configuration
+local background_mode = 'blur' -- Available background mode: `image`, `blur`, `root`, `bg_color`
+local wall_dir = config_dir .. 'theme/wallpapers/' -- Wallpaper directory
+local default_wall_name = 'morning-wallpaper.jpg' -- Default wallpaper
+local tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/' -- /tmp directory
+
+
+-- Useful variables (DO NOT TOUCH)
+local input_password = nil
+local lock_again = nil
+local type_again = true
+local capture_now = capture_intruder
+local locked_tag = nil
+
+-- 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
+ }
+
+ local uname_text = wibox.widget {
+ id = 'uname_text',
+ markup = '$USER',
+ font = 'SF Pro Display Bold 17',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local uname_text_shadow = wibox.widget {
+ id = 'uname_text_shadow',
+ markup = '' .. '$USER' .. "",
+ font = 'SF Pro Display Bold 17',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local caps_text = wibox.widget {
+ id = 'uname_text',
+ markup = 'Caps Lock is on',
+ font = 'SF Pro Display Italic 10',
+ align = 'center',
+ valign = 'center',
+ opacity = 0.0,
+ widget = wibox.widget.textbox
+ }
+ local caps_text_shadow = wibox.widget {
+ id = 'uname_text',
+ markup = '' .. 'Caps Lock is on' .. "",
+ font = 'SF Pro Display Italic 10',
+ align = 'center',
+ valign = 'center',
+ opacity = 0.0,
+ widget = wibox.widget.textbox
+ }
+
+ -- Update username textbox
+ awful.spawn.easy_async_with_shell('whoami | tr -d "\\n"', function(stdout)
+ uname_text.markup = stdout
+ uname_text_shadow.markup = '' .. stdout .. ""
+ end)
+
+
+ local profile_imagebox = wibox.widget {
+ id = 'user_icon',
+ image = widget_icon_dir .. 'default' .. '.svg',
+ resize = true,
+ forced_height = dpi(100),
+ forced_width = dpi(100),
+ clip_shape = gears.shape.circle,
+ widget = wibox.widget.imagebox
+ }
+
+ local update_profile_pic = function()
+ awful.spawn.easy_async_with_shell(
+ apps.bins.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 time = wibox.widget.textclock(
+ '%H:%M',
+ 1
+ )
+
+ local time_shadow = wibox.widget.textclock(
+ '%H:%M',
+ 1
+ )
+
+ local wanted_text = wibox.widget {
+ markup = 'INTRUDER ALERT!',
+ font = 'SFNS Pro Text Bold 12',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local msg_table = {
+ 'We are watching you.',
+ 'We know where you live.',
+ 'This incident will be reported.',
+ 'RUN!',
+ 'Yamete, Oniichan~ uwu',
+ 'This will self-destruct in 5 seconds!',
+ 'Image successfully sent!',
+ 'You\'re doomed!'
+ }
+
+ local wanted_msg = wibox.widget {
+ markup = 'This incident will be reported!',
+ font = 'SFNS Pro Text 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(100),
+ clip_shape = gears.shape.rounded_rect,
+ widget = wibox.widget.imagebox
+ }
+
+ local wanted_poster = awful.popup {
+
+ widget = {
+ {
+ {
+ wanted_text,
+ {
+ nil,
+ wanted_image,
+ nil,
+ expand = 'none',
+ layout = wibox.layout.align.horizontal
+ },
+ wanted_msg,
+ spacing = dpi(10),
+ 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(200),
+ hide_on_right_click = false,
+ preferred_anchors = {'middle'},
+ visible = false
+
+ }
+
+ awful.placement.bottom(wanted_poster,
+ {
+ margins =
+ {
+ bottom = dpi(10),
+ },
+ parent = screen.primary
+ }
+ )
+
+
+ local date_value = function()
+ local date_val = {}
+ 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
+
+ date_val.day = day
+ date_val.month = month
+ date_val.ordinal= ordinal
+
+ return date_val
+ end
+
+ local date = wibox.widget {
+ markup = date_value().day .. date_value().ordinal .. ' of ' .. date_value().month,
+ font = 'SF Pro Display Bold 20',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local date_shadow = wibox.widget {
+ markup = "" .. date_value().day .. date_value().ordinal .. " of " ..
+ date_value().month .. "",
+ font = 'SF Pro Display Bold 20',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local circle_container = wibox.widget {
+ bg = '#f2f2f233',
+ forced_width = dpi(110),
+ forced_height = dpi(110),
+ shape = gears.shape.circle,
+ widget = wibox.container.background
+ }
+
+ local locker_arc = wibox.widget {
+ bg = beautiful.transparent,
+ forced_width = dpi(110),
+ forced_height = dpi(110),
+ shape = function(cr, width, height)
+ gears.shape.arc(cr, width, height, dpi(5), 0, math.pi/2, true, true)
+ end,
+ widget = wibox.container.background
+ }
+
+ -- 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)
+ status = stdout
+
+ if status:match('on') then
+ caps_text.opacity = 1.0
+ caps_text_shadow.opacity = 1.0
+ else
+ caps_text.opacity = 0.0
+ caps_text_shadow.opacity = 0.0
+ end
+ caps_text:emit_signal('widget::redraw_needed')
+ caps_text_shadow:emit_signal('widget::redraw_needed')
+ end
+ )
+ end
+
+ 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}
+
+
+ local locker_widget_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
+
+ local check_webcam = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ ls -l /dev/video* | grep /dev/video0
+ ]],
+ function(stdout)
+ if not 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()
+
+ local intruder_capture = function()
+ local capture_image = [[
+
+ save_dir=]] .. 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.groups_title_bg
+
+ -- Humiliate the intruder by showing his/her hideous face
+ wanted_image:set_image(stdout:gsub('%\n',''))
+ wanted_poster.visible= true
+ wanted_msg:set_markup(msg_table[math.random(#msg_table)])
+
+ awful.placement.bottom(wanted_poster,
+ {
+ margins =
+ {
+ bottom = dpi(10),
+ },
+ parent = screen.primary
+ }
+ )
+ wanted_image:emit_signal('widget::redraw_needed')
+
+ type_again = true
+ end
+ )
+ end
+
+ 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.groups_title_bg
+ type_again = true
+ end
+ )
+ end
+ end
+
+
+ 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.groups_title_bg
+
+ -- Enable locking again
+ lock_again = true
+
+ -- Enable validation again
+ 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
+ client.focus = c
+ c:raise()
+ end
+
+ end
+ )
+ end
+
+ -- A backdoor
+ local back_door = function()
+ generalkenobi_ohhellothere()
+ end
+
+ 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()
+ 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_widget_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 pam_auth = false
+ if input_password ~= nil then
+ pam_auth = pam:auth_current_user(input_password)
+ else
+ return
+ end
+
+ if pam_auth then
+ -- Come in!
+ self:stop()
+ generalkenobi_ohhellothere()
+ else
+ -- F*ck off, you [REDACTED]!
+ stoprightthereyoucriminalscum()
+ end
+
+ 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_shadow,
+ time,
+ vertical_offset = dpi(-1),
+ widget = wibox.layout.stack
+ },
+ nil
+
+ },
+ {
+ layout = wibox.layout.align.horizontal,
+ expand = 'none',
+ nil,
+ {
+ date_shadow,
+ date,
+ vertical_offset = dpi(-1),
+ widget = wibox.layout.stack
+ },
+ 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_shadow,
+ uname_text,
+ vertical_offset = dpi(-1),
+ widget = wibox.layout.stack
+ },
+ {
+ caps_text_shadow,
+ caps_text,
+ vertical_offset = dpi(-1),
+ widget = wibox.layout.stack
+ }
+ },
+ },
+ nil
+ },
+ nil
+ }
+
+ local show_lockscreen = function()
+
+ -- Unselect all tags and minimize the focused client
+ -- Will also 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
+
+ -- Why is there a lock_again variable?
+ -- Well, it fixes a bug.
+ -- What is the bug?
+ -- It's a secret.
+
+ if lock_again == true or lock_again == nil then
+
+ -- 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 key grabbing for password
+ password_grabber:start()
+
+ -- Dont lock again
+ lock_again = false
+
+ end
+
+ end
+
+ awesome.connect_signal(
+ "module::lockscreen_show",
+ function()
+ if lock_again == true or lock_again == nil then
+ 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
+
+local cycle_through_screens = function(s)
+ if s.index == 1 then
+ s.lockscreen = locker(s)
+ else
+ s.lockscreen_extended = locker_ext(s)
+ end
+end
+
+-- Create a lockscreen for each screen
+screen.connect_signal(
+ "request::desktop_decoration",
+ function(s)
+ cycle_through_screens(s)
+ end
+)
+
+-- Regenerate lockscreens if a screen was added to avoid errors
+screen.connect_signal(
+ 'added',
+ function(s)
+ cycle_through_screens(s)
+ end
+
+)
+
+-- Regenerate lockscreens if a screen was removed to avoid errors
+screen.connect_signal(
+ "removed",
+ function(s)
+ cycle_through_screens(s)
+ end
+)
+
+-- Dont 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
+
+naughty.connect_signal(
+ "request::display",
+ function(_)
+ if check_lockscreen_visibility() then
+ naughty.destroy_all_notifications(nil, 1)
+ end
+ end
+)
+
+-- Background Mode Processes
+local blur_resize_image = function(wall_name, index, ap, width, height)
+ local magic = [[
+ if [ ! -d ]] .. tmp_wall_dir ..[[ ]; then mkdir -p ]] .. tmp_wall_dir .. [[; fi
+
+ convert -quality 100 -filter Gaussian -blur 0x10 ]] .. wall_dir .. wall_name ..
+ [[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height ..
+ [[! ]] .. tmp_wall_dir .. index .. wall_name .. [[
+ ]]
+ return magic
+end
+
+local resize_image = function(wall_name, index, ap, width, height)
+ local magic = [[
+ if [ ! -d ]] .. tmp_wall_dir ..[[ ]; then mkdir -p ]] .. tmp_wall_dir .. [[; fi
+
+ convert -quality 100 ]] .. wall_dir .. wall_name ..
+ [[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height ..
+ [[! ]] .. tmp_wall_dir .. index .. wall_name .. [[
+ ]]
+ return magic
+end
+
+local apply_ls_bg_image = function(wall_name)
+ for s in screen do
+ local index = s.index .. '-'
+
+ local screen_width = s.geometry.width
+ local screen_height = s.geometry.height
+
+ local aspect_ratio = screen_width / screen_height
+
+ aspect_ratio = math.floor(aspect_ratio * 100) / 100
+
+ local cmd = nil
+ if background_mode == 'blur' then
+ cmd = blur_resize_image(wall_name, index, aspect_ratio, screen_width, screen_height)
+ else
+ cmd = resize_image(wall_name, index, aspect_ratio, screen_width, screen_height)
+ end
+
+ if s.index == 1 then
+ awful.spawn.easy_async_with_shell(
+ cmd,
+ function(stdout, stderr)
+ s.lockscreen.bgimage = tmp_wall_dir .. index .. wall_name
+ end
+ )
+ else
+ awful.spawn.easy_async_with_shell(
+ cmd,
+ function()
+ s.lockscreen_extended.bgimage = tmp_wall_dir .. index .. wall_name
+ end
+ )
+ end
+ end
+end
+
+local check_background_mode = function()
+
+ if background_mode == 'root' then
+
+ for s in screen do
+ if s.index == 1 then
+ s.lockscreen.bgimage = root.wallpaper()
+ else
+ s.lockscreen_extended.bgimage = root.wallpaper()
+ end
+ end
+
+ elseif background_mode == 'bg_color' then
+ for s in screen do
+ if s.index == 1 then
+ s.lockscreen.bg = beautiful.background
+ else
+ s.lockscreen_extended.bg = beautiful.background
+ end
+ end
+
+ elseif background_mode == 'blur' or background_mode == 'image' then
+ apply_ls_bg_image(default_wall_name)
+
+ else
+ for s in screen do
+ if s.index == 1 then
+ s.lockscreen.bgimage = root.wallpaper()
+ else
+ s.lockscreen_extended.bgimage = root.wallpaper()
+ end
+ end
+ end
+
+end
+
+check_background_mode()
+
+-- Regenerate lockscreen's background if a screen was added
+screen.connect_signal(
+ 'added',
+ function()
+ check_background_mode()
+ end
+
+)
+
+-- Regenerate lockscreen's background if a screen was removed
+screen.connect_signal(
+ "removed",
+ function()
+ check_background_mode()
+ end
+)
\ No newline at end of file
diff --git a/awesome/module/menu.lua b/awesome/module/menu.lua
new file mode 100644
index 0000000..6806d8e
--- /dev/null
+++ b/awesome/module/menu.lua
@@ -0,0 +1,206 @@
+-- An applications menu
+-- Required depends: awesome-freedesktop
+
+local awful = require("awful")
+local gears = require("gears")
+local beautiful = require("beautiful")
+local apps = require('configuration.apps')
+local menubar = require("menubar")
+
+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")
+
+local function is_module_available(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
+
+-- 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.bins.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.bins.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")
+ }
+}
+
+-- A menu generated by awesome-freedesktop
+-- https://github.com/lcpz/awesome-freedesktop
+
+if is_module_available("freedesktop") then
+
+ local freedesktop = require("freedesktop")
+
+ mymainmenu = freedesktop.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 })
+else
+
+ mymainmenu = awful.menu({
+
+ items = {
+ {
+ "Instructions",
+ function()
+ local naughty = require('naughty')
+
+ local open_github = naughty.action {
+ name = 'Open Github Page',
+ icon_only = false,
+ }
+
+ open_github:connect_signal('invoked', function()
+ awful.spawn.easy_async_with_shell("xdg-open https://github.com/lcpz/awesome-freedesktop")
+ end)
+
+ local open_aur = naughty.action {
+ name = 'Open AUR Page',
+ icon_only = false,
+ }
+
+ open_aur:connect_signal('invoked', function()
+ awful.spawn.easy_async_with_shell("xdg-open https://aur.archlinux.org/packages/awesome-freedesktop-git/")
+ end)
+
+ naughty.notification({
+ title = 'A dependency is missing!',
+ message = "You need to install awesome-freedesktop. " ..
+ "This will populate the menu with your installed applications automatically. " ..
+ "It is also available in AUR, it is called awesome-freedesktop-git.",
+ app_name = 'System Notification',
+ timeout = 0,
+ urgency = 'normal',
+ actions = { open_github, open_aur }
+ })
+ end,
+ menubar.utils.lookup_icon("accessories-text-editor")
+ },
+ {
+ "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")
+ }
+ }
+ })
+end
\ No newline at end of file
diff --git a/awesome/module/notifications.lua b/awesome/module/notifications.lua
new file mode 100644
index 0000000..b32baa1
--- /dev/null
+++ b/awesome/module/notifications.lua
@@ -0,0 +1,262 @@
+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 = 8
+naughty.config.spacing = 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 = 'SF Pro Text 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 = 'SF Pro Text 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 = 'SF Pro Text 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
+)
+
+-- Naughty template
+naughty.connect_signal("request::display", function(n)
+
+ -- naughty.actions template
+ 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 = 'SF Pro Text 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
+ }
+
+ -- Custom notification layout
+ 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 = 'SF Pro Text Bold 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+
+ },
+ margins = beautiful.notification_margin,
+ widget = wibox.container.margin,
+ },
+ bg = '#000000'.. '44',
+ 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,
+ },
+ -- Notification action list
+ -- naughty.list.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,
+ },
+ -- Anti-aliasing container
+ -- Real BG
+ bg = beautiful.background,
+ -- This will be the anti-aliased shape of the notification
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background
+ },
+ -- Margin of the fake BG to have a space between notification and the screen edge
+ margins = dpi(5),--beautiful.notification_margin,
+ widget = wibox.container.margin
+ }
+
+ }
+
+ -- 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/awesome/module/quake-terminal.lua b/awesome/module/quake-terminal.lua
new file mode 100644
index 0000000..6fa6633
--- /dev/null
+++ b/awesome/module/quake-terminal.lua
@@ -0,0 +1,73 @@
+local gears = require('gears')
+local spawn = require('awful.spawn')
+local app = require('configuration.apps').default.quake
+-- local awful = require('awful')
+
+local quake_id = 'notnil'
+local quake_client
+local opened = false
+function create_shell()
+ quake_id =
+ spawn(
+ app,
+ {
+ skip_decoration = true
+ }
+ )
+end
+
+function open_quake()
+ quake_client.hidden = false
+ quake_client:emit_signal('request::activate')
+end
+
+function close_quake()
+ quake_client.hidden = true
+end
+
+toggle_quake = function()
+ opened = not opened
+ if not quake_client then
+ create_shell()
+ else
+ if opened then
+ open_quake()
+ else
+ close_quake()
+ end
+ end
+end
+
+client.connect_signal(
+ 'manage',
+ function(c)
+ if c.pid == quake_id then
+ quake_client = c
+ c.opacity = 0.95
+ c.floating = true
+ c.skip_taskbar = true
+ c.ontop = true
+ c.above = true
+ c.sticky = true
+ c.hidden = not opened
+ c.maximized_horizontal = true
+ c.hide_titlebars = true
+ c.skip_center = true
+ c.round_corners = false
+ c.shape = function(cr, w, h)
+ gears.shape.rectangle(cr, w, h)
+ end
+ -- awful.placement.top(c)
+ end
+ end
+)
+
+client.connect_signal(
+ 'unmanage',
+ function(c)
+ if c.pid == quake_id then
+ opened = false
+ quake_client = nil
+ end
+ end
+)
\ No newline at end of file
diff --git a/awesome/module/test.lua b/awesome/module/test.lua
new file mode 100644
index 0000000..6785ed0
--- /dev/null
+++ b/awesome/module/test.lua
@@ -0,0 +1,30 @@
+-- Load these libraries (if you haven't already)
+local awful = require("awful")
+local gears = require("gears")
+local wibox = require("wibox")
+
+-- Create the box
+local anti_aliased_wibox = wibox({visible = true, ontop = true, type = "normal", height = 100, width = 100})
+
+-- Place it at the center of the screen
+awful.placement.centered(anti_aliased_wibox)
+
+-- Set transparent bg
+anti_aliased_wibox.bg = beautiful.transparent
+
+-- Put its items in a shaped container
+anti_aliased_wibox:setup {
+ -- Container
+ {
+ -- Items go here
+ --wibox.widget.textbox("Hello!"),
+ awful.spawn('urxvt'),
+ -- ...
+ layout = wibox.layout.fixed.vertical
+ },
+ -- The real background color
+ bg = "#111111",
+ -- The real, anti-aliased shape
+ shape = gears.shape.rounded_rect,
+ widget = wibox.container.background()
+}
diff --git a/awesome/module/titlebar.lua b/awesome/module/titlebar.lua
new file mode 100644
index 0000000..2794a54
--- /dev/null
+++ b/awesome/module/titlebar.lua
@@ -0,0 +1,282 @@
+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 = false
+awful.titlebar.fallback_name = 'Client\'s name'
+
+
+local titlebar_size = beautiful.titlebar_size
+
+
+-- ▄▄▄▄▄▄▄ ▀ ▄ ▀▀█ █
+-- █ ▄▄▄ ▄▄█▄▄ █ ▄▄▄ █▄▄▄ ▄▄▄ ▄ ▄▄
+-- █ █ █ █ █▀ █ █▀ ▀█ ▀ █ █▀ ▀
+-- █ █ █ █ █▀▀▀▀ █ █ ▄▀▀▀█ █
+-- █ ▄▄█▄▄ ▀▄▄ ▀▄▄ ▀█▄▄▀ ██▄█▀ ▀▄▄▀█ █
+
+
+
+function double_click_event_handler(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
+
+
+
+client.connect_signal("request::titlebars", function(c)
+
+ -- Buttons for moving/resizing functionality
+ 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
+ )
+ )
+
+
+ local decorate_titlebar = function(c, pos, bg, size)
+
+ c.titlebar_position = pos
+
+ if pos == 'left' or pos == 'right' then
+
+ -- Creates left or right titlebars
+ awful.titlebar(c, {position = pos, bg = bg, size = size or titlebar_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 = buttons,
+ layout = wibox.layout.flex.vertical
+ },
+ {
+ awful.titlebar.widget.floatingbutton (c),
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ layout = wibox.layout.align.vertical
+
+ }
+
+ elseif pos == 'top' or pos == 'bottom' then
+
+ -- Creates top or bottom titlebars
+ awful.titlebar(c, {position = pos, bg = bg, size = size or titlebar_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 = buttons,
+ layout = wibox.layout.flex.horizontal
+ },
+ {
+ awful.titlebar.widget.floatingbutton (c),
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ layout = wibox.layout.align.horizontal
+ }
+
+ else
+
+ -- Create a left titlebar (default in this setup)
+ awful.titlebar(c, {position = 'left', size = titlebar_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 = buttons,
+ layout = wibox.layout.flex.vertical
+ },
+ {
+ awful.titlebar.widget.floatingbutton (c),
+ margins = dpi(10),
+ widget = wibox.container.margin
+ },
+ layout = wibox.layout.align.vertical
+ }
+
+ end
+
+ end
+
+ -- ▄▄▄ ▄ ▀
+ -- ▄▀ ▀ ▄ ▄ ▄▄▄ ▄▄█▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄
+ -- █ █ █ █ ▀ █ █▀ ▀█ █ █ █ █ ▄▀ █▀ █
+ -- █ █ █ ▀▀▀▄ █ █ █ █ █ █ █ ▄▀ █▀▀▀▀
+ -- ▀▄▄▄▀ ▀▄▄▀█ ▀▄▄▄▀ ▀▄▄ ▀█▄█▀ █ █ █ ▄▄█▄▄ █▄▄▄▄ ▀█▄▄▀
+
+ -- Generate a custom titlabar for each class, roles, type, etc., etc.
+ -- The titlebar's position can now be set differently
+
+ if c.class == 'dolphin' or c.class == 'firefox' or c.class == 'pavucontrol-qt' or
+ c.instance == 'transmission-qt' or c.class == 'ark' or c.class == 'polkit-kde-authentication-agent-1' or
+ c.class == 'partitionmanager' or c.class == 'discord' or c.class == 'kdesu' then
+
+ if c.type == 'dialog' or c.type == 'modal' then
+ decorate_titlebar(c, 'top', beautiful.background, titlebar_size)
+ else
+ decorate_titlebar(c, 'left', beautiful.background, titlebar_size)
+ end
+
+ elseif c.role == "GtkFileChooserDialog" or c.type == 'dialog' or c.type == 'modal' then
+
+ -- Let's use the gtk theme's bg_color as titlebar's bg then add some transparency
+ -- Let's set the titlebar's position to top
+ -- Isn't it neat? lol
+ decorate_titlebar(c, 'top', beautiful.gtk.get_theme_variables().bg_color:sub(1,7) .. '66', titlebar_size)
+
+ elseif c.class == "kitty" then
+
+ decorate_titlebar(c, 'left', '#000000AA', titlebar_size)
+
+ elseif c.class == 'XTerm' or c.class == 'UXTerm' then
+
+ -- Let's use the xresources' background color as the titlebar color for xterm
+ -- awesome is the shit boi!
+ decorate_titlebar(c, 'top', beautiful.xresources.get_current_theme().background, titlebar_size)
+
+ elseif c.class == 'Nemo' then
+
+ decorate_titlebar(c, 'left', beautiful.xresources.get_current_theme().background, titlebar_size)
+
+ else
+
+ -- Default titlebar
+ decorate_titlebar(c, 'left', beautiful.background, titlebar_size)
+
+ end
+
+end)
+
+
+-- ▄▄▄▄ ▀ ▀▀█
+-- █▀ ▀ ▄▄▄ ▄▄▄▄ ▄ ▄▄ ▄▄▄ █ ▄▄▄
+-- ▀█▄▄▄ █ █▀ ▀█ █▀ █ ▀ █ █ █ ▀
+-- ▀█ █ █ █ █ █ ▄▀▀▀█ █ ▀▀▀▄
+-- ▀▄▄▄█▀ ▄▄█▄▄ ▀█▄▀█ █ █ ▀▄▄▀█ ▀▄▄ ▀▄▄▄▀
+-- ▄ █
+-- ▀▀
+
+
+client.connect_signal(
+ "manage",
+ function(c)
+
+ if not c.max and not c.hide_titlebars then
+ awful.titlebar.show(c, c.titlebar_position or 'left')
+ else
+ awful.titlebar.hide(c, c.titlebar_position or 'left')
+ end
+
+ end
+)
+
+-- Catch the signal when a client's layout is changed
+screen.connect_signal(
+ "arrange",
+ function(s)
+ for _, c in pairs(s.clients) do
+
+ if (#s.tiled_clients > 1 or c.floating) and c.first_tag.layout.name ~= 'max' then
+
+ if not c.hide_titlebars then
+ awful.titlebar.show(c, c.titlebar_position or 'left')
+ else
+ awful.titlebar.hide(c, c.titlebar_position or 'left')
+ end
+
+ if c.maximized or not c.round_corners or c.fullscreen then
+ c.shape = function(cr, w, h)
+ gears.shape.rectangle(cr, w, h)
+ end
+ else
+ c.shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
+ end
+ end
+
+ elseif (#s.tiled_clients == 1 or c.first_tag.layout.name == 'max') and not c.fullscreen then
+
+ awful.titlebar.hide(c, c.titlebar_position or 'left')
+
+ c.shape = function(cr, w, h)
+ gears.shape.rectangle(cr, w, h)
+ end
+
+ end
+
+ end
+ end
+)
+
+
+client.connect_signal("property::maximized", function(c)
+ c.shape = gears.shape.rectangle
+
+ if not c.maximized then
+ c.shape = function(cr, width, height)
+ gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
+ end
+ end
+end)
\ No newline at end of file
diff --git a/awesome/module/volume-osd.lua b/awesome/module/volume-osd.lua
new file mode 100644
index 0000000..681fdec
--- /dev/null
+++ b/awesome/module/volume-osd.lua
@@ -0,0 +1,272 @@
+local awful = require("awful")
+local gears = require("gears")
+local wibox = require("wibox")
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+local spawn = require('awful.spawn')
+
+screen.connect_signal("request::desktop_decoration", function(s)
+
+ s.show_vol_osd = false
+
+ local osd_header = wibox.widget {
+ text = 'Volume',
+ font = 'VictorMono Nerd Font 12',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ }
+
+ local osd_value = wibox.widget {
+ text = '0%',
+ font = 'VictorMono Nerd Font 11',
+ 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
+
+ -- Update volume level using slider value
+ vol_osd_slider:connect_signal(
+ 'property::value',
+ function()
+
+ local volume_level = vol_osd_slider:get_value()
+
+ 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 s.show_vol_osd then
+ awesome.emit_signal(
+ 'module::volume_osd:show',
+ true
+ )
+ end
+
+ end
+ )
+
+ vol_osd_slider:connect_signal(
+ 'button::press',
+ function()
+ s.show_vol_osd = true
+ end
+ )
+ vol_osd_slider:connect_signal(
+ 'button::release',
+ function()
+ s.show_vol_osd = false
+ end
+ )
+ vol_osd_slider:connect_signal(
+ 'mouse::enter',
+ function()
+ s.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
+ }
+
+ -- Create the box
+ local osd_height = dpi(100)
+ local osd_width = dpi(300)
+
+ local osd_margin = dpi(10)
+
+ 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()
+ }
+
+
+ local hide_osd = gears.timer {
+ timeout = 2,
+ autostart = true,
+ callback = function()
+ awful.screen.focused().volume_osd_overlay.visible = false
+ end
+ }
+
+ local timer_rerun = function()
+ if hide_osd.started then
+ hide_osd:again()
+ else
+ hide_osd:start()
+ end
+ end
+
+ -- Reset timer on mouse hover
+ s.volume_osd_overlay:connect_signal(
+ 'mouse::enter',
+ function()
+ s.show_vol_osd = true
+ timer_rerun()
+ end
+ )
+ s.volume_osd_overlay:connect_signal(
+ 'mouse::leave',
+ function()
+ s.show_vol_osd = false
+ 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(focused.volume_osd_overlay, { margins = {
+ left = osd_margin + left_panel.width,
+ right = 0,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ return
+ end
+ end
+
+ if right_panel then
+ if right_panel.visible then
+ awful.placement.bottom_left(focused.volume_osd_overlay, { margins = {
+ left = osd_margin,
+ right = 0,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ return
+ end
+ end
+
+ awful.placement.bottom_right(focused.volume_osd_overlay, { margins = {
+ left = 0,
+ right = osd_margin,
+ top = 0,
+ bottom = osd_margin,
+ },
+ parent = focused }
+ )
+ end
+
+ awesome.connect_signal(
+ 'module::volume_osd:show',
+ function(bool)
+ placement_placer()
+ awful.screen.focused().volume_osd_overlay.visible = bool
+ if bool then
+ timer_rerun()
+ awesome.emit_signal(
+ 'module::brightness_osd:show',
+ false
+ )
+ else
+ if hide_osd.started then
+ hide_osd:stop()
+ end
+ end
+ end
+ )
+
+end)
diff --git a/awesome/rc.lua b/awesome/rc.lua
index 4b79bc9..d94e53e 100644
--- a/awesome/rc.lua
+++ b/awesome/rc.lua
@@ -18,6 +18,39 @@ local hotkeys_popup = require("awful.hotkeys_popup")
-- when client with a matching name is opened:
require("awful.hotkeys_popup.keys")
+
+-- Widgets to add
+-- local batteryarc_widget = require("awesome-wm-widget.batteryarc-widget.batteryarc")
+
+-- >> Daemons
+-- Most widgets that display system/external info depend on evil.
+-- Make sure to initialize it last in order to allow all widgets to connect to
+-- their needed evil signals.
+-- require("evil")
+-- ===================================================================
+-- ===================================================================
+
+
+-- ========================================
+-- Modules
+-- Load all the modules
+-- ========================================
+
+require('module.notifications')
+-- require('module.auto-start')
+require('module.decorate-client')
+require('module.backdrop')
+-- require('module.exit-screen')
+-- require('module.quake-terminal')
+-- require('module.titlebar')
+-- require('module.menu')
+require('module.volume-osd')
+require('module.brightness-osd')
+require('module.dynamic-wallpaper')
+-- require('module.battery-notifier')
+-- require('module.lockscreen')
+
+
-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
@@ -107,7 +140,7 @@ mykeyboardlayout = awful.widget.keyboardlayout()
-- {{{ Wibar
-- Create a textclock widget
-mytextclock = wibox.widget.textclock()
+mytextclock = wibox.widget.textclock(" %a %b %d, %l:%M %p ")
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
@@ -192,30 +225,91 @@ awful.screen.connect_for_each_screen(function(s)
s.mysystray = wibox.widget.systray()
-- Create a tasklist widget
- s.mytasklist = awful.widget.tasklist {
- screen = s,
- filter = awful.widget.tasklist.filter.currenttags,
- buttons = tasklist_buttons
- }
+ -- s.mytasklist = awful.widget.tasklist {
+ -- screen = s,
+ -- filter = awful.widget.tasklist.filter.currenttags,
+ -- buttons = tasklist_buttons
+ -- style =
+ -- }
+ s.mytasklist = awful.widget.tasklist {
+ screen = s,
+ filter = awful.widget.tasklist.filter.currenttags,
+ buttons = tasklist_buttons,
+ style = {
+ border_width = 0,
+ border_color = '#777777',
+ shape = gears.shape.rounded_bar,
+
+ },
+ layout = {
+ spacing = 20,
+ spacing_widget = {
+ {
+ forced_width = 5,
+ forced_height = 30,
+ -- shape = gears.shape.circle,
+ widget = wibox.widget.separator
+ },
+ valign = 'center',
+ halign = 'center',
+ widget = wibox.container.place,
+ },
+ layout = wibox.layout.flex.horizontal
+ },
+ -- notice that there is *no* wibox.wibox prefix, it is a template,
+ -- not a widget instance.
+ widget_template = {
+ {
+ {
+ {
+ {
+ id = 'icon_role',
+ widget = wibox.widget.imagebox,
+ },
+ margins = 4,
+ widget = wibox.container.margin,
+ },
+ {
+ id = 'text_role',
+ widget = wibox.widget.textbox,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ left = 10,
+ right = 10,
+ widget = wibox.container.margin
+ },
+ id = 'background_role',
+ widget = wibox.container.background,
+ },
+ }
-- Create the wibox
s.mywibox = awful.wibar({ position = "bottom", screen = s })
+ -- Create Battery, Network, and Volume widget
+ s.battery = require('widget.battery')()
+ s.network = require('widget.network')()
+ -- s.volume = require('widget.volume-slider')()
+ s.updater = require('widget.package-updater')()
-- Add widgets to the wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
- mylauncher,
- s.mytaglist,
+ wibox.container.margin (s.mytaglist,25,0,0,0),
s.mypromptbox,
},
- s.mytasklist, -- Middle widget
+ wibox.container.margin (s.mytasklist,35,35,0,0), -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
s.mysystray,
+ -- s.volume,
+ s.updater,
+ s.network,
+ s.battery,
mytextclock,
- s.mylayoutbox,
+ wibox.container.margin (s.mylayoutbox,0,25,0,0),
},
}
end)
@@ -275,6 +369,11 @@ globalkeys = gears.table.join(
end,
{description = "go back", group = "client"}),
+
+ -- Screenshots
+ awful.key({}, "Print", function() awful.util.spawn("flameshot gui") end,
+ {description = "take a screenshot", group = "screen"}),
+
-- Increase-Decrease Gap
awful.key({ modkey, Mod1 }, "k", function () awful.tag.incgap ( 1, null) end,
@@ -321,8 +420,42 @@ globalkeys = gears.table.join(
end,
{description = "restore minimized", group = "client"}),
+ -- Volume Keys
+ awful.key({}, "XF86AudioLowerVolume", function ()
+ awful.util.spawn("amixer -q -D pulse sset Master 5%-", false)
+ end),
+ awful.key({}, "XF86AudioRaiseVolume", function ()
+ awful.util.spawn("amixer -q -D pulse sset Master 5%+", false)
+ end),
+ awful.key({}, "XF86AudioMute", function ()
+ awful.util.spawn("amixer -D pulse set Master 1+ toggle", false)
+ end),
+ -- Media Keys
+ awful.key({}, "XF86AudioPlay", function()
+ awful.util.spawn("playerctl play-pause", false)
+ end),
+ awful.key({}, "XF86AudioNext", function()
+ awful.util.spawn("playerctl next", false)
+ end),
+ awful.key({}, "XF86AudioPrev", function()
+ awful.util.spawn("playerctl previous", false)
+ end),
+
+ -- Brightness Keys
+ awful.key({}, "XF86MonBrightnessUp", function()
+ awful.util.spawn("brightnessctl set +10%", false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show', true)
+ end),
+
+ awful.key({}, "XF86MonBrightnessDown", function()
+ awful.util.spawn("brightnessctl set 10%-", false)
+ awesome.emit_signal('widget::brightness')
+ awesome.emit_signal('module::brightness_osd:show', true)
+ end),
+
-- Prompt
- awful.key({ modkey }, "r", function ()
+ awful.key({ }, "Menu", function ()
awful.util.spawn("/home/chris/.dotfiles/rofi/launchers-git/launcher.sh") end,
{description = "launch rofi", group = "launcher"}),
@@ -502,12 +635,15 @@ awful.rules.rules = {
-- Add titlebars to normal clients and dialogs
{ rule_any = {type = { "normal", "dialog" }
- }, properties = { titlebars_enabled = true }
+ }, properties = { titlebars_enabled = false }
},
-- Set Firefox to always map on the tag named "2" on screen 1.
- -- { rule = { class = "Firefox" },
- -- properties = { screen = 1, tag = "2" } },
+ { rule = { class = "Firefox" },
+ properties = { screen = 1, tag = "2",
+ maximized_vertical = true,
+ maximized_horizontal = true,
+ } },
}
-- }}}
@@ -578,5 +714,6 @@ client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_n
-- Autostart Applications
awful.spawn.with_shell("picom")
-awful.spawn.with_shell("nitrogen --restore")
--- awful.spawn.with_shell("polybarstart")
+awful.spawn.with_shell("feh --bg-fill /home/chris/Pictures/royalking.png")
+awful.spawn.with_shell("libinput-gestures-setup start")
+awful.spawn.with_shell("flameshot")
diff --git a/awesome/theme.lua b/awesome/theme.lua
index 919bc48..fe6ce56 100644
--- a/awesome/theme.lua
+++ b/awesome/theme.lua
@@ -9,10 +9,12 @@ local gears = require('gears')
local gfs = require("gears.filesystem")
local themes_path = gfs.get_themes_dir()
+-- local theme_dir = filesystem.get_configuration_dir() .. '/theme'
local theme = {}
-theme.font = "Rec Mono Linear 10"
+theme.font = "VictorMono Nerd Font 10"
+-- theme.icons = theme_dir .. '/icons/'
theme.bg_normal = "#282a36"
theme.bg_focus = "#43454f"
@@ -25,8 +27,10 @@ theme.fg_focus = "#e2e4e5"
theme.fg_urgent = "#e2e4e5"
theme.fg_minimize = "#e2e4e5"
+theme.red = "#ff5c57"
+
theme.useless_gap = dpi(8)
-theme.border_width = dpi(1)
+theme.border_width = dpi(0)
theme.border_normal = "#00000000"
theme.border_focus = "#00000000"
theme.border_marked = "#00000000"
@@ -45,7 +49,7 @@ theme.border_marked = "#00000000"
--theme.taglist_bg_focus = "#ff0000"
-- Generate taglist squares:
-local taglist_square_size = dpi(4)
+local taglist_square_size = dpi(8)
theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
taglist_square_size, theme.fg_normal
)
@@ -53,6 +57,14 @@ theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
taglist_square_size, theme.fg_normal
)
+-- Tasklists
+theme.tasklist_shape = gears.shape.rounded_bar
+theme.tasklist_spacing = 40
+theme.tasklist_align = "center"
+
+theme.tasklist_bg = theme.red
+
+
-- Variables set for theming notifications:
-- notification_font
-- notification_[bg|fg]
@@ -77,7 +89,7 @@ theme.wibar_bg = theme.bg_normal
-- theme.wibar_y = 1030
theme.wibar_x = 0
-- theme.wibar_stretch = false
-theme.wibar_border_width = 3
+theme.wibar_border_width = dpi(5)
theme.wibar_border_color = nil
-- theme.wibar_ontop = nil
-- theme.wibar_cursor = nil
@@ -142,6 +154,7 @@ theme.awesome_icon = theme_assets.awesome_icon(
theme.menu_height, theme.bg_focus, theme.fg_focus
)
+-- theme.awesome_icon = theme.icons .. 'awesome.svg'
-- Define the icon theme for application icons. If not set then the icons
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = nil
diff --git a/awesome/theme/default-theme.lua b/awesome/theme/default-theme.lua
new file mode 100644
index 0000000..ceca1fc
--- /dev/null
+++ b/awesome/theme/default-theme.lua
@@ -0,0 +1,231 @@
+local gears = require('gears')
+local beautiful = require('beautiful')
+
+local filesystem = require('gears.filesystem')
+local dpi = require('beautiful').xresources.apply_dpi
+
+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
+
+
+local theme = {}
+theme.icons = theme_dir .. '/icons/'
+
+-- Font
+theme.font = 'SF Pro Text Regular 10'
+theme.font_bold = 'SF Pro Text 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/'
+
+ -- Wallpaper
+
+ theme.wallpaper = theme.dir .. '/wallpapers/morning-wallpaper.jpg'
+
+ -- Foreground
+
+ theme.font = 'SF Pro Text Regular 10'
+ theme.title_font = 'SF Pro Text Bold 14'
+
+
+ theme.fg_normal = '#ffffffde'
+ theme.fg_focus = '#e4e4e4'
+ theme.fg_urgent = '#CC9393'
+
+ theme.bat_fg_critical = '#232323'
+
+ 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 = beautiful.gtk.get_theme_variables().bg_color:sub(1,7) .. '66'
+ theme.titlebar_bg_normal = beautiful.gtk.get_theme_variables().base_color:sub(1,7) .. '66'
+ theme.titlebar_fg_focus = beautiful.gtk.get_theme_variables().fg_color .. '00'
+ theme.titlebar_fg_normal = beautiful.gtk.get_theme_variables().fg_color .. '00'
+
+ -- 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)
+
+ -- Client Decorations
+
+ -- Borders
+ theme.border_focus = beautiful.gtk.get_theme_variables().bg_color
+ theme.border_normal = beautiful.gtk.get_theme_variables().base_color
+ theme.border_marked = '#CC9393'
+ theme.border_width = dpi(0)
+ theme.border_radius = dpi(0)
+
+ -- Decorations
+ theme.client_radius = dpi(9)
+ theme.useless_gap = dpi(4)
+
+ -- Menu
+ theme.menu_font = "SF Pro Text 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 = 'SF Pro Text 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(0)
+ 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 = 'SF Pro Text Bold'
+ theme.hotkeys_description_font = 'SF Pro Text Regular Regular'
+ theme.hotkeys_bg = theme.background
+ theme.hotkeys_group_margin = dpi(20)
+
+
+end
+
+return {
+ theme = theme,
+ awesome_overrides = awesome_overrides
+}
diff --git a/awesome/theme/floppy-theme/init.lua b/awesome/theme/floppy-theme/init.lua
new file mode 100644
index 0000000..82e2364
--- /dev/null
+++ b/awesome/theme/floppy-theme/init.lua
@@ -0,0 +1,54 @@
+local filesystem = require('gears.filesystem')
+local theme_dir = filesystem.get_configuration_dir() .. '/theme'
+
+local theme = {}
+
+theme.icons = theme_dir .. '/icons/'
+theme.font = 'SF Pro Text Regular 10'
+theme.font_bold = 'SF Pro Text 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/awesome/theme/icons/awesome.svg b/awesome/theme/icons/awesome.svg
new file mode 100644
index 0000000..31d715c
--- /dev/null
+++ b/awesome/theme/icons/awesome.svg
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/awesome/theme/icons/battery-charge.svg b/awesome/theme/icons/battery-charge.svg
new file mode 100644
index 0000000..f8efe9c
--- /dev/null
+++ b/awesome/theme/icons/battery-charge.svg
@@ -0,0 +1,58 @@
+
+
\ No newline at end of file
diff --git a/awesome/theme/icons/battery-discharge.svg b/awesome/theme/icons/battery-discharge.svg
new file mode 100644
index 0000000..908ce15
--- /dev/null
+++ b/awesome/theme/icons/battery-discharge.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/awesome/theme/icons/brightness-7.svg b/awesome/theme/icons/brightness-7.svg
new file mode 100644
index 0000000..862549e
--- /dev/null
+++ b/awesome/theme/icons/brightness-7.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/chart-areaspline.svg b/awesome/theme/icons/chart-areaspline.svg
new file mode 100644
index 0000000..58bf0d3
--- /dev/null
+++ b/awesome/theme/icons/chart-areaspline.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/close.svg b/awesome/theme/icons/close.svg
new file mode 100644
index 0000000..bd89d79
--- /dev/null
+++ b/awesome/theme/icons/close.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/effects.svg b/awesome/theme/icons/effects.svg
new file mode 100644
index 0000000..e6c514b
--- /dev/null
+++ b/awesome/theme/icons/effects.svg
@@ -0,0 +1,91 @@
+
+
diff --git a/awesome/theme/icons/harddisk.svg b/awesome/theme/icons/harddisk.svg
new file mode 100644
index 0000000..4c23f54
--- /dev/null
+++ b/awesome/theme/icons/harddisk.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/init.lua b/awesome/theme/icons/init.lua
new file mode 100644
index 0000000..5cf636b
--- /dev/null
+++ b/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/awesome/theme/icons/layouts/dwindle.svg b/awesome/theme/icons/layouts/dwindle.svg
new file mode 100644
index 0000000..9e59058
--- /dev/null
+++ b/awesome/theme/icons/layouts/dwindle.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/layouts/floating.svg b/awesome/theme/icons/layouts/floating.svg
new file mode 100644
index 0000000..5dcd846
--- /dev/null
+++ b/awesome/theme/icons/layouts/floating.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/layouts/fullscreen.svg b/awesome/theme/icons/layouts/fullscreen.svg
new file mode 100644
index 0000000..6ba320b
--- /dev/null
+++ b/awesome/theme/icons/layouts/fullscreen.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/awesome/theme/icons/layouts/max.svg b/awesome/theme/icons/layouts/max.svg
new file mode 100644
index 0000000..f1b2b2d
--- /dev/null
+++ b/awesome/theme/icons/layouts/max.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/awesome/theme/icons/layouts/tile.svg b/awesome/theme/icons/layouts/tile.svg
new file mode 100644
index 0000000..ea62c5d
--- /dev/null
+++ b/awesome/theme/icons/layouts/tile.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/lock.svg b/awesome/theme/icons/lock.svg
new file mode 100644
index 0000000..ac383ed
--- /dev/null
+++ b/awesome/theme/icons/lock.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/logout.svg b/awesome/theme/icons/logout.svg
new file mode 100644
index 0000000..4689c49
--- /dev/null
+++ b/awesome/theme/icons/logout.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/magnify.svg b/awesome/theme/icons/magnify.svg
new file mode 100644
index 0000000..40d9c1a
--- /dev/null
+++ b/awesome/theme/icons/magnify.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/memory.svg b/awesome/theme/icons/memory.svg
new file mode 100644
index 0000000..0cf4b10
--- /dev/null
+++ b/awesome/theme/icons/memory.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/plus.svg b/awesome/theme/icons/plus.svg
new file mode 100644
index 0000000..737cad4
--- /dev/null
+++ b/awesome/theme/icons/plus.svg
@@ -0,0 +1,58 @@
+
+
diff --git a/awesome/theme/icons/power-sleep.svg b/awesome/theme/icons/power-sleep.svg
new file mode 100644
index 0000000..a4dbfc0
--- /dev/null
+++ b/awesome/theme/icons/power-sleep.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/power.svg b/awesome/theme/icons/power.svg
new file mode 100644
index 0000000..770943b
--- /dev/null
+++ b/awesome/theme/icons/power.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/restart.svg b/awesome/theme/icons/restart.svg
new file mode 100644
index 0000000..f0c3367
--- /dev/null
+++ b/awesome/theme/icons/restart.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/ship-wheel.svg b/awesome/theme/icons/ship-wheel.svg
new file mode 100644
index 0000000..5237ed3
--- /dev/null
+++ b/awesome/theme/icons/ship-wheel.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/tag-list/close-small.svg b/awesome/theme/icons/tag-list/close-small.svg
new file mode 100644
index 0000000..f244bae
--- /dev/null
+++ b/awesome/theme/icons/tag-list/close-small.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/awesome/theme/icons/tag-list/development.svg b/awesome/theme/icons/tag-list/development.svg
new file mode 100644
index 0000000..773a538
--- /dev/null
+++ b/awesome/theme/icons/tag-list/development.svg
@@ -0,0 +1,174 @@
+
+
diff --git a/awesome/theme/icons/tag-list/file-manager.svg b/awesome/theme/icons/tag-list/file-manager.svg
new file mode 100644
index 0000000..ba04747
--- /dev/null
+++ b/awesome/theme/icons/tag-list/file-manager.svg
@@ -0,0 +1,138 @@
+
+
diff --git a/awesome/theme/icons/tag-list/games.svg b/awesome/theme/icons/tag-list/games.svg
new file mode 100644
index 0000000..6314387
--- /dev/null
+++ b/awesome/theme/icons/tag-list/games.svg
@@ -0,0 +1,103 @@
+
+
diff --git a/awesome/theme/icons/tag-list/graphics.svg b/awesome/theme/icons/tag-list/graphics.svg
new file mode 100644
index 0000000..caefefb
--- /dev/null
+++ b/awesome/theme/icons/tag-list/graphics.svg
@@ -0,0 +1,150 @@
+
+
diff --git a/awesome/theme/icons/tag-list/menu.svg b/awesome/theme/icons/tag-list/menu.svg
new file mode 100644
index 0000000..c95ecd7
--- /dev/null
+++ b/awesome/theme/icons/tag-list/menu.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/theme/icons/tag-list/menu2.svg b/awesome/theme/icons/tag-list/menu2.svg
new file mode 100644
index 0000000..3e82e3d
--- /dev/null
+++ b/awesome/theme/icons/tag-list/menu2.svg
@@ -0,0 +1,123 @@
+
+
diff --git a/awesome/theme/icons/tag-list/multimedia.svg b/awesome/theme/icons/tag-list/multimedia.svg
new file mode 100644
index 0000000..ff5f5b0
--- /dev/null
+++ b/awesome/theme/icons/tag-list/multimedia.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/awesome/theme/icons/tag-list/sandbox.svg b/awesome/theme/icons/tag-list/sandbox.svg
new file mode 100644
index 0000000..67c1921
--- /dev/null
+++ b/awesome/theme/icons/tag-list/sandbox.svg
@@ -0,0 +1,80 @@
+
+
diff --git a/awesome/theme/icons/tag-list/social.svg b/awesome/theme/icons/tag-list/social.svg
new file mode 100644
index 0000000..7217709
--- /dev/null
+++ b/awesome/theme/icons/tag-list/social.svg
@@ -0,0 +1,92 @@
+
+
diff --git a/awesome/theme/icons/tag-list/terminal.svg b/awesome/theme/icons/tag-list/terminal.svg
new file mode 100644
index 0000000..3c4fc1f
--- /dev/null
+++ b/awesome/theme/icons/tag-list/terminal.svg
@@ -0,0 +1,101 @@
+
+
diff --git a/awesome/theme/icons/tag-list/text-editor.svg b/awesome/theme/icons/tag-list/text-editor.svg
new file mode 100644
index 0000000..4aa63b8
--- /dev/null
+++ b/awesome/theme/icons/tag-list/text-editor.svg
@@ -0,0 +1,76 @@
+
+
diff --git a/awesome/theme/icons/tag-list/web-browser.svg b/awesome/theme/icons/tag-list/web-browser.svg
new file mode 100644
index 0000000..4b97514
--- /dev/null
+++ b/awesome/theme/icons/tag-list/web-browser.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/awesome/theme/icons/thermometer.svg b/awesome/theme/icons/thermometer.svg
new file mode 100644
index 0000000..5c25a1e
--- /dev/null
+++ b/awesome/theme/icons/thermometer.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/close_focus.svg b/awesome/theme/icons/titlebar/stoplight/close_focus.svg
new file mode 100644
index 0000000..8b63331
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/close_focus.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg b/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg
new file mode 100644
index 0000000..2d77a2f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/close_normal.svg b/awesome/theme/icons/titlebar/stoplight/close_normal.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/close_normal.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg b/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg
new file mode 100644
index 0000000..2d77a2f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg b/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg
new file mode 100644
index 0000000..ae9727f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg b/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg
new file mode 100644
index 0000000..ae9727f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg b/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg b/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..2faad37
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg b/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg
new file mode 100644
index 0000000..e522d74
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg b/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg
new file mode 100644
index 0000000..e522d74
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg b/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg b/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..7a5c055
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg b/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg
new file mode 100644
index 0000000..215d91c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg b/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg
new file mode 100644
index 0000000..282d8b0
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg b/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg b/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg
new file mode 100644
index 0000000..282d8b0
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg b/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg
new file mode 100644
index 0000000..432f74f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg b/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg
new file mode 100644
index 0000000..432f74f
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg b/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg b/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg
new file mode 100644
index 0000000..a3da6d2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg b/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg
new file mode 100644
index 0000000..47248cb
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg b/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg
new file mode 100644
index 0000000..47248cb
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg b/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg b/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg b/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg
new file mode 100644
index 0000000..6acee08
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg
new file mode 100644
index 0000000..fe22df2
--- /dev/null
+++ b/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/close_focus.svg b/awesome/theme/icons/titlebar/win10/close_focus.svg
new file mode 100644
index 0000000..d1bc232
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/close_focus.svg
@@ -0,0 +1,116 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/close_normal.svg b/awesome/theme/icons/titlebar/win10/close_normal.svg
new file mode 100644
index 0000000..d013ac8
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/close_normal.svg
@@ -0,0 +1,114 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/close_normal_hover.svg b/awesome/theme/icons/titlebar/win10/close_normal_hover.svg
new file mode 100644
index 0000000..d1bc232
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/close_normal_hover.svg
@@ -0,0 +1,116 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_focus_active.svg b/awesome/theme/icons/titlebar/win10/floating_focus_active.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_focus_active.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg b/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg b/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_normal_active.svg b/awesome/theme/icons/titlebar/win10/floating_normal_active.svg
new file mode 100644
index 0000000..6f0faf1
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_normal_active.svg
@@ -0,0 +1,108 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg b/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg b/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg
new file mode 100644
index 0000000..6f0faf1
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg
@@ -0,0 +1,108 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg
new file mode 100644
index 0000000..cdda009
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg b/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg b/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg b/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg b/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg b/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg
new file mode 100644
index 0000000..d9dea80
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg
@@ -0,0 +1,113 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg b/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg b/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg
new file mode 100644
index 0000000..d9dea80
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg
@@ -0,0 +1,113 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg b/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg
new file mode 100644
index 0000000..6b6452c
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/minimize_focus.svg b/awesome/theme/icons/titlebar/win10/minimize_focus.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/minimize_focus.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg b/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/minimize_normal.svg b/awesome/theme/icons/titlebar/win10/minimize_normal.svg
new file mode 100644
index 0000000..a3efb9b
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/minimize_normal.svg
@@ -0,0 +1,119 @@
+
+
+
+
diff --git a/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg b/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg
new file mode 100644
index 0000000..b8a5cc7
--- /dev/null
+++ b/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/awesome/theme/icons/toggled-off.svg b/awesome/theme/icons/toggled-off.svg
new file mode 100644
index 0000000..a73de49
--- /dev/null
+++ b/awesome/theme/icons/toggled-off.svg
@@ -0,0 +1,74 @@
+
+
+
+
diff --git a/awesome/theme/icons/toggled-on.svg b/awesome/theme/icons/toggled-on.svg
new file mode 100644
index 0000000..a75ef1c
--- /dev/null
+++ b/awesome/theme/icons/toggled-on.svg
@@ -0,0 +1,74 @@
+
+
+
+
diff --git a/awesome/theme/icons/volume-high.svg b/awesome/theme/icons/volume-high.svg
new file mode 100644
index 0000000..7a59aa1
--- /dev/null
+++ b/awesome/theme/icons/volume-high.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/theme/init.lua b/awesome/theme/init.lua
new file mode 100644
index 0000000..23b0af5
--- /dev/null
+++ b/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/awesome/theme/wallpapers/LICENSE b/awesome/theme/wallpapers/LICENSE
new file mode 100644
index 0000000..730138d
--- /dev/null
+++ b/awesome/theme/wallpapers/LICENSE
@@ -0,0 +1,2 @@
+THESE WALLPAPERS ARE NOT MINE IT IS OWNED BY THEIR RESPECTIVE OWNERS.
+CREDITS TO THE OWNERS.
diff --git a/awesome/theme/wallpapers/midnight-wallpaper.jpg b/awesome/theme/wallpapers/midnight-wallpaper.jpg
new file mode 100644
index 0000000..0a50832
Binary files /dev/null and b/awesome/theme/wallpapers/midnight-wallpaper.jpg differ
diff --git a/awesome/theme/wallpapers/morning-wallpaper.jpg b/awesome/theme/wallpapers/morning-wallpaper.jpg
new file mode 100644
index 0000000..a31cb9b
Binary files /dev/null and b/awesome/theme/wallpapers/morning-wallpaper.jpg differ
diff --git a/awesome/theme/wallpapers/night-wallpaper.jpg b/awesome/theme/wallpapers/night-wallpaper.jpg
new file mode 100644
index 0000000..95408ec
Binary files /dev/null and b/awesome/theme/wallpapers/night-wallpaper.jpg differ
diff --git a/awesome/theme/wallpapers/noon-wallpaper.jpg b/awesome/theme/wallpapers/noon-wallpaper.jpg
new file mode 100644
index 0000000..81382cb
Binary files /dev/null and b/awesome/theme/wallpapers/noon-wallpaper.jpg differ
diff --git a/awesome/widget/battery/icons/battery-100.svg b/awesome/widget/battery/icons/battery-100.svg
new file mode 100644
index 0000000..b3d3337
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-100.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-20.svg b/awesome/widget/battery/icons/battery-20.svg
new file mode 100644
index 0000000..116a7f9
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-20.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-30.svg b/awesome/widget/battery/icons/battery-30.svg
new file mode 100644
index 0000000..d1f4463
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-30.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-50.svg b/awesome/widget/battery/icons/battery-50.svg
new file mode 100644
index 0000000..8dca81e
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-50.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-60.svg b/awesome/widget/battery/icons/battery-60.svg
new file mode 100644
index 0000000..25eaca0
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-60.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-80.svg b/awesome/widget/battery/icons/battery-80.svg
new file mode 100644
index 0000000..5612658
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-80.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-90.svg b/awesome/widget/battery/icons/battery-90.svg
new file mode 100644
index 0000000..d11ab44
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-90.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-alert-red.svg b/awesome/widget/battery/icons/battery-alert-red.svg
new file mode 100644
index 0000000..469b0ba
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-alert-red.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-alert.svg b/awesome/widget/battery/icons/battery-alert.svg
new file mode 100644
index 0000000..6ec71c1
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-alert.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-10.svg b/awesome/widget/battery/icons/battery-charging-10.svg
new file mode 100644
index 0000000..4de288a
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-10.svg
@@ -0,0 +1,75 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-20.svg b/awesome/widget/battery/icons/battery-charging-20.svg
new file mode 100644
index 0000000..af759b5
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-20.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-30.svg b/awesome/widget/battery/icons/battery-charging-30.svg
new file mode 100644
index 0000000..f721545
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-30.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-50.svg b/awesome/widget/battery/icons/battery-charging-50.svg
new file mode 100644
index 0000000..42bb375
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-50.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-60.svg b/awesome/widget/battery/icons/battery-charging-60.svg
new file mode 100644
index 0000000..4057d33
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-60.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-80.svg b/awesome/widget/battery/icons/battery-charging-80.svg
new file mode 100644
index 0000000..5febc30
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-80.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-charging-90.svg b/awesome/widget/battery/icons/battery-charging-90.svg
new file mode 100644
index 0000000..544aa5d
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-charging-90.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-fully-charged.svg b/awesome/widget/battery/icons/battery-fully-charged.svg
new file mode 100644
index 0000000..7e923fc
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-fully-charged.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-standard.svg b/awesome/widget/battery/icons/battery-standard.svg
new file mode 100644
index 0000000..adba7ac
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-standard.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/icons/battery-unknown.svg b/awesome/widget/battery/icons/battery-unknown.svg
new file mode 100644
index 0000000..ad67bdf
--- /dev/null
+++ b/awesome/widget/battery/icons/battery-unknown.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/battery/init.lua b/awesome/widget/battery/init.lua
new file mode 100644
index 0000000..1a0f988
--- /dev/null
+++ b/awesome/widget/battery/init.lua
@@ -0,0 +1,264 @@
+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-standard' .. '.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 = 'VictorMono Nerd Font 10',
+ 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'}
+ }
+
+ -- Get battery info script
+ 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
+
+ -- Update tooltip on startup
+ get_battery_info()
+
+ -- Update tooltip on hover
+ battery_widget:connect_signal('mouse::enter', function()
+ get_battery_info()
+ end)
+
+
+ local check_percentage_cmd = [[
+ upower -i $(upower -e | grep BAT) | grep percentage | awk '{print $2}' | tr -d '\n%'
+ ]]
+
+ local check_status_cmd = [[bash -c "
+ upower -i $(upower -e | grep BAT) | grep state | awk '{print $2}' | tr -d '\n'
+ "]]
+
+ local last_battery_check = os.time()
+ local notify_critcal_battery = true
+
+ local function show_battery_warning()
+ 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)
+
+ local status = status:gsub('%\n', '')
+
+ awful.spawn.easy_async_with_shell(check_percentage_cmd, function(stdout)
+
+ local battery_percentage = tonumber(stdout)
+
+ battery_widget.spacing = dpi(5)
+ battery_percentage_text.visible = true
+ battery_percentage_text:set_text(battery_percentage .. '%')
+
+ local icon_name = 'battery'
+
+
+ if status:match('discharging') then
+
+ if battery_percentage >= 0 and battery_percentage < 10 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
+
+ elseif battery_percentage > 10 and battery_percentage < 20 then
+
+ icon_name = icon_name .. '-' .. '10'
+
+ elseif battery_percentage >= 20 and battery_percentage < 30 then
+
+ icon_name = icon_name .. '-' .. '20'
+
+ elseif battery_percentage >= 30 and battery_percentage < 50 then
+
+ icon_name = icon_name .. '-' .. '30'
+
+ elseif battery_percentage >= 50 and battery_percentage < 60 then
+
+ icon_name = icon_name .. '-' .. '50'
+
+ elseif battery_percentage >= 60 and battery_percentage < 80 then
+
+ icon_name = icon_name .. '-' .. '60'
+
+ elseif battery_percentage >= 80 and battery_percentage < 90 then
+
+ icon_name = icon_name .. '-' .. '80'
+
+ elseif battery_percentage >= 90 and battery_percentage < 100 then
+
+ icon_name = icon_name .. '-' .. '90'
+
+ elseif battery_percentage == 100 then
+
+ icon_name = icon_name .. '-' .. battery_percentage
+ end
+
+ elseif status:match('charging') then
+
+ 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'
+
+ else
+ icon_name = icon_name .. '-' .. 'fully-charged'
+ end
+
+ elseif status:match('fully') then
+
+ icon_name = icon_name .. '-' .. '100'
+
+ end
+
+ -- Debugger ;)
+ -- naughty.notification({message=widget_icon_dir .. icon_name .. '.svg'})
+
+ battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg'))
+
+ collectgarbage('collect')
+ end)
+ end
+
+ -- Watch status if charging, discharging, fully-charged
+ watch(check_status_cmd, 5, function(widget, stdout)
+
+ -- If no output or battery detected
+ if (stdout == nil or stdout == '') 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(stdout)
+
+ end)
+
+ return battery_button
+
+
+end
+
+
+return return_button
diff --git a/awesome/widget/blue-light/init.lua b/awesome/widget/blue-light/init.lua
new file mode 100644
index 0000000..62f914b
--- /dev/null
+++ b/awesome/widget/blue-light/init.lua
@@ -0,0 +1,127 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+
+local dpi = require('beautiful').xresources.apply_dpi
+local clickable_container = require('widget.window-effects.clickable-container')
+
+local icons = require('theme.icons')
+
+local blue_light_state = nil
+
+local action_name = wibox.widget {
+ text = 'Blue Light Filter',
+ font = 'SF Pro Text 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/awesome/widget/bluetooth/bluetooth-toggle.lua b/awesome/widget/bluetooth/bluetooth-toggle.lua
new file mode 100644
index 0000000..b36cdd0
--- /dev/null
+++ b/awesome/widget/bluetooth/bluetooth-toggle.lua
@@ -0,0 +1,174 @@
+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.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_icon_dir = config_dir .. 'widget/bluetooth/icons/'
+
+local icons = require('theme.icons')
+
+local device_state = false
+
+
+
+
+local action_name = wibox.widget {
+ text = 'Bluetooth Connection',
+ font = 'SF Pro Text 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) end
+ )
+ else
+ device_state = true
+ awful.spawn.easy_async_with_shell(
+ power_on_cmd,
+ function(stdout) end
+ )
+ end
+
+ update_imagebox()
+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/awesome/widget/bluetooth/clickable-container.lua b/awesome/widget/bluetooth/clickable-container.lua
new file mode 100644
index 0000000..f531740
--- /dev/null
+++ b/awesome/widget/bluetooth/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/awesome/widget/bluetooth/icons/bluetooth-connected.svg b/awesome/widget/bluetooth/icons/bluetooth-connected.svg
new file mode 100644
index 0000000..bbda6ad
--- /dev/null
+++ b/awesome/widget/bluetooth/icons/bluetooth-connected.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/bluetooth/icons/bluetooth-off.svg b/awesome/widget/bluetooth/icons/bluetooth-off.svg
new file mode 100644
index 0000000..f3e52ab
--- /dev/null
+++ b/awesome/widget/bluetooth/icons/bluetooth-off.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/bluetooth/icons/bluetooth-scanning.svg b/awesome/widget/bluetooth/icons/bluetooth-scanning.svg
new file mode 100644
index 0000000..029f145
--- /dev/null
+++ b/awesome/widget/bluetooth/icons/bluetooth-scanning.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/bluetooth/icons/bluetooth.svg b/awesome/widget/bluetooth/icons/bluetooth.svg
new file mode 100644
index 0000000..32fbc3e
--- /dev/null
+++ b/awesome/widget/bluetooth/icons/bluetooth.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/bluetooth/icons/loading.svg b/awesome/widget/bluetooth/icons/loading.svg
new file mode 100644
index 0000000..cd7bc0e
--- /dev/null
+++ b/awesome/widget/bluetooth/icons/loading.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/bluetooth/init.lua b/awesome/widget/bluetooth/init.lua
new file mode 100644
index 0000000..e852844
--- /dev/null
+++ b/awesome/widget/bluetooth/init.lua
@@ -0,0 +1,90 @@
+-------------------------------------------------
+-- Bluetooth Widget for Awesome Window Manager
+-- Shows the bluetooth status using the bluetoothctl command
+-- Better with Blueman Manager
+-------------------------------------------------
+
+local awful = require('awful')
+local gears = require('gears')
+local naughty = require('naughty')
+local wibox = require('wibox')
+
+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/awesome/widget/brightness/brightness-slider.lua b/awesome/widget/brightness/brightness-slider.lua
new file mode 100644
index 0000000..ebc95ec
--- /dev/null
+++ b/awesome/widget/brightness/brightness-slider.lua
@@ -0,0 +1,140 @@
+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 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',
+ 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('brightnessctl 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(
+ "brightnessctl g",
+ function(stdout)
+
+ local brightness = string.match(stdout, '(%d+)')
+
+ brightness_slider:set_value(tonumber(stdout) / 75)
+ end
+ )
+end
+
+-- Update on startup
+update_slider()
+
+-- 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 {
+ {
+ {
+ {
+ image = icons.brightness,
+ 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 brightness_setting
diff --git a/awesome/widget/calculator/icons/kb-off.svg b/awesome/widget/calculator/icons/kb-off.svg
new file mode 100644
index 0000000..0bcea86
--- /dev/null
+++ b/awesome/widget/calculator/icons/kb-off.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/awesome/widget/calculator/icons/kb.svg b/awesome/widget/calculator/icons/kb.svg
new file mode 100644
index 0000000..edccdc8
--- /dev/null
+++ b/awesome/widget/calculator/icons/kb.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/awesome/widget/calculator/init.lua b/awesome/widget/calculator/init.lua
new file mode 100644
index 0000000..91dec20
--- /dev/null
+++ b/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 = 'SF Pro Text 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 = 'SF Pro Text 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/awesome/widget/clickable-container/init.lua b/awesome/widget/clickable-container/init.lua
new file mode 100644
index 0000000..0ebff66
--- /dev/null
+++ b/awesome/widget/clickable-container/init.lua
@@ -0,0 +1,53 @@
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+
+function build(widget)
+ local container =
+ wibox.widget {
+ widget,
+ widget = wibox.container.background
+ }
+ local old_cursor, old_wibox
+
+ 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
+ )
+
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ container.bg = beautiful.transparent
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ container:connect_signal(
+ 'button::press',
+ function()
+ container.bg = beautiful.groups_title_bg
+ end
+ )
+
+ container:connect_signal(
+ 'button::release',
+ function()
+ container.bg = beautiful.groups_bg
+ end
+ )
+
+ return container
+end
+
+return build
diff --git a/awesome/widget/cpu/cpu-meter.lua b/awesome/widget/cpu/cpu-meter.lua
new file mode 100644
index 0000000..53f6d69
--- /dev/null
+++ b/awesome/widget/cpu/cpu-meter.lua
@@ -0,0 +1,74 @@
+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 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 '"]],
+ 5,
+ 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/awesome/widget/email/icons/email-1.svg b/awesome/widget/email/icons/email-1.svg
new file mode 100644
index 0000000..9170d0b
--- /dev/null
+++ b/awesome/widget/email/icons/email-1.svg
@@ -0,0 +1,109 @@
+
+
diff --git a/awesome/widget/email/icons/email-2.svg b/awesome/widget/email/icons/email-2.svg
new file mode 100644
index 0000000..58406a7
--- /dev/null
+++ b/awesome/widget/email/icons/email-2.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-3.svg b/awesome/widget/email/icons/email-3.svg
new file mode 100644
index 0000000..597b144
--- /dev/null
+++ b/awesome/widget/email/icons/email-3.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-4.svg b/awesome/widget/email/icons/email-4.svg
new file mode 100644
index 0000000..dc915fb
--- /dev/null
+++ b/awesome/widget/email/icons/email-4.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-5.svg b/awesome/widget/email/icons/email-5.svg
new file mode 100644
index 0000000..935140c
--- /dev/null
+++ b/awesome/widget/email/icons/email-5.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-6.svg b/awesome/widget/email/icons/email-6.svg
new file mode 100644
index 0000000..edf1298
--- /dev/null
+++ b/awesome/widget/email/icons/email-6.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-7.svg b/awesome/widget/email/icons/email-7.svg
new file mode 100644
index 0000000..980d79c
--- /dev/null
+++ b/awesome/widget/email/icons/email-7.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-8.svg b/awesome/widget/email/icons/email-8.svg
new file mode 100644
index 0000000..4c6618a
--- /dev/null
+++ b/awesome/widget/email/icons/email-8.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-9+.svg b/awesome/widget/email/icons/email-9+.svg
new file mode 100644
index 0000000..53a0a68
--- /dev/null
+++ b/awesome/widget/email/icons/email-9+.svg
@@ -0,0 +1,104 @@
+
+
diff --git a/awesome/widget/email/icons/email-9.svg b/awesome/widget/email/icons/email-9.svg
new file mode 100644
index 0000000..9c65b74
--- /dev/null
+++ b/awesome/widget/email/icons/email-9.svg
@@ -0,0 +1,100 @@
+
+
diff --git a/awesome/widget/email/icons/email-unread.svg b/awesome/widget/email/icons/email-unread.svg
new file mode 100644
index 0000000..829d3a9
--- /dev/null
+++ b/awesome/widget/email/icons/email-unread.svg
@@ -0,0 +1,117 @@
+
+
diff --git a/awesome/widget/email/icons/email.svg b/awesome/widget/email/icons/email.svg
new file mode 100644
index 0000000..a8860b4
--- /dev/null
+++ b/awesome/widget/email/icons/email.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/email/init.lua b/awesome/widget/email/init.lua
new file mode 100644
index 0000000..9c450c9
--- /dev/null
+++ b/awesome/widget/email/init.lua
@@ -0,0 +1,412 @@
+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 secrets = require('configuration.secrets')
+
+local email_account = secrets.email.address
+local app_password = secrets.email.app_password
+local imap_server = secrets.email.imap_server
+local port = secrets.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 = 'SF Pro Text Bold 10',
+ markup = 'From:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+
+local email_recent_from = wibox.widget {
+ font = 'SF Pro Text Regular 10',
+ markup = 'loading@stdout.sh',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_subject_text = wibox.widget {
+ font = 'SF Pro Text Regular 10',
+ markup = 'Subject:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_recent_subject = wibox.widget {
+ font = 'SF Pro Text Regular 10',
+ markup = 'Loading data',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_date_text = wibox.widget {
+ font = 'SF Pro Text Regular 10',
+ markup = 'Local Date:',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local email_recent_date = wibox.widget {
+ font = 'SF Pro Text 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 email_account == '' or app_password == '' or imap_server == '' or 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::wifi_connected',
+ function()
+ gears.timer.start_new(
+ 5,
+ function()
+ check_secrets()
+ end
+ )
+ end
+)
+
+return email_report
diff --git a/awesome/widget/harddrive/harddrive-meter.lua b/awesome/widget/harddrive/harddrive-meter.lua
new file mode 100644
index 0000000..b3972c3
--- /dev/null
+++ b/awesome/widget/harddrive/harddrive-meter.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/awesome/widget/music/content/album-cover.lua b/awesome/widget/music/content/album-cover.lua
new file mode 100755
index 0000000..135aaa7
--- /dev/null
+++ b/awesome/widget/music/content/album-cover.lua
@@ -0,0 +1,22 @@
+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/music/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
\ No newline at end of file
diff --git a/awesome/widget/music/content/init.lua b/awesome/widget/music/content/init.lua
new file mode 100644
index 0000000..ff0be29
--- /dev/null
+++ b/awesome/widget/music/content/init.lua
@@ -0,0 +1,9 @@
+-- Return UI Table
+return {
+ album_cover = require('widget.music.content.album-cover'),
+ progress_bar = require('widget.music.content.progress-bar'),
+ track_time = require('widget.music.content.track-time'),
+ song_info = require('widget.music.content.song-info'),
+ media_buttons = require('widget.music.content.media-buttons'),
+ volume_slider = require('widget.music.content.volume-slider'),
+}
\ No newline at end of file
diff --git a/awesome/widget/music/content/media-buttons.lua b/awesome/widget/music/content/media-buttons.lua
new file mode 100755
index 0000000..260230f
--- /dev/null
+++ b/awesome/widget/music/content/media-buttons.lua
@@ -0,0 +1,124 @@
+local beautiful = require('beautiful')
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+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/music/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/awesome/widget/music/content/progress-bar.lua b/awesome/widget/music/content/progress-bar.lua
new file mode 100755
index 0000000..7069011
--- /dev/null
+++ b/awesome/widget/music/content/progress-bar.lua
@@ -0,0 +1,22 @@
+local beautiful = require('beautiful')
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+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
\ No newline at end of file
diff --git a/awesome/widget/music/content/song-info.lua b/awesome/widget/music/content/song-info.lua
new file mode 100755
index 0000000..9570e00
--- /dev/null
+++ b/awesome/widget/music/content/song-info.lua
@@ -0,0 +1,63 @@
+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 = 'SF Pro Text 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 = 'SF Pro Text 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
\ No newline at end of file
diff --git a/awesome/widget/music/content/track-time.lua b/awesome/widget/music/content/track-time.lua
new file mode 100755
index 0000000..db2abe6
--- /dev/null
+++ b/awesome/widget/music/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 = 'SF Pro Text 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 = 'SF Pro Text 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
\ No newline at end of file
diff --git a/awesome/widget/music/content/volume-slider.lua b/awesome/widget/music/content/volume-slider.lua
new file mode 100755
index 0000000..e417893
--- /dev/null
+++ b/awesome/widget/music/content/volume-slider.lua
@@ -0,0 +1,24 @@
+local beautiful = require('beautiful')
+local gears = require('gears')
+local awful = require('awful')
+local wibox = require('wibox')
+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/awesome/widget/music/icons/music.svg b/awesome/widget/music/icons/music.svg
new file mode 100755
index 0000000..a2aa04e
--- /dev/null
+++ b/awesome/widget/music/icons/music.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/awesome/widget/music/icons/next.svg b/awesome/widget/music/icons/next.svg
new file mode 100644
index 0000000..7df5063
--- /dev/null
+++ b/awesome/widget/music/icons/next.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/music/icons/pause.svg b/awesome/widget/music/icons/pause.svg
new file mode 100644
index 0000000..9fc7767
--- /dev/null
+++ b/awesome/widget/music/icons/pause.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/awesome/widget/music/icons/play.svg b/awesome/widget/music/icons/play.svg
new file mode 100755
index 0000000..3a56779
--- /dev/null
+++ b/awesome/widget/music/icons/play.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/music/icons/prev.svg b/awesome/widget/music/icons/prev.svg
new file mode 100644
index 0000000..0e39d34
--- /dev/null
+++ b/awesome/widget/music/icons/prev.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/music/icons/random-off.svg b/awesome/widget/music/icons/random-off.svg
new file mode 100755
index 0000000..76f2e06
--- /dev/null
+++ b/awesome/widget/music/icons/random-off.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/music/icons/random-on.svg b/awesome/widget/music/icons/random-on.svg
new file mode 100755
index 0000000..3baf2ed
--- /dev/null
+++ b/awesome/widget/music/icons/random-on.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/music/icons/repeat-off.svg b/awesome/widget/music/icons/repeat-off.svg
new file mode 100644
index 0000000..00a4c06
--- /dev/null
+++ b/awesome/widget/music/icons/repeat-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/music/icons/repeat-on.svg b/awesome/widget/music/icons/repeat-on.svg
new file mode 100644
index 0000000..6917ca6
--- /dev/null
+++ b/awesome/widget/music/icons/repeat-on.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/music/icons/vinyl.svg b/awesome/widget/music/icons/vinyl.svg
new file mode 100755
index 0000000..d26a4a8
--- /dev/null
+++ b/awesome/widget/music/icons/vinyl.svg
@@ -0,0 +1,5698 @@
+
+
+
+
diff --git a/awesome/widget/music/init.lua b/awesome/widget/music/init.lua
new file mode 100755
index 0000000..d79a84a
--- /dev/null
+++ b/awesome/widget/music/init.lua
@@ -0,0 +1,92 @@
+-- # #
+-- ## ## # # #### # ####
+-- # # # # # # # # # #
+-- # # # # # #### # #
+-- # # # # # # #
+-- # # # # # # # # #
+-- # # #### #### # ####
+
+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/music/icons/'
+
+local clickable_container = require('widget.clickable-container')
+
+local music_box = require('widget.music.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
\ No newline at end of file
diff --git a/awesome/widget/music/mpd-music-updater.lua b/awesome/widget/music/mpd-music-updater.lua
new file mode 100755
index 0000000..c8229b0
--- /dev/null
+++ b/awesome/widget/music/mpd-music-updater.lua
@@ -0,0 +1,506 @@
+-- Update Music info using mpd/mpc
+-- Depends mpd, mpc
+
+local gears = require('gears')
+local awful = require('awful')
+
+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
+
+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
+
+ # Extract album cover using perl-image-exiftool
+ exiftool -b -Picture \
+ "$MUSIC_DIR/$(mpc -p 6600 --format "%file%" current)" > "$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(tostring("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(tostring("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")
+
+ collectgarbage('collect')
+ 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
+
+
+local startup_update_quota = 0
+
+gears.timer.start_new(3, function()
+
+ update_all_content()
+
+ startup_update_quota = startup_update_quota + 1
+
+ if startup_update_quota <= 5 then
+ return true
+ else
+ return false
+ end
+end)
+
+
+gears.timer.start_new(
+ 5,
+ 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 ()
+ 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
+ )
+ )
+)
\ No newline at end of file
diff --git a/awesome/widget/music/music-box.lua b/awesome/widget/music/music-box.lua
new file mode 100755
index 0000000..20bba0a
--- /dev/null
+++ b/awesome/widget/music/music-box.lua
@@ -0,0 +1,171 @@
+-- # # ######
+-- ## ## # # #### # #### # # #### # #
+-- # # # # # # # # # # # # # # # #
+-- # # # # # #### # # ###### # # ##
+-- # # # # # # # # # # # ##
+-- # # # # # # # # # # # # # # #
+-- # # #### #### # #### ###### #### # #
+
+-- Creates the music box widget here
+
+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.music.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.music.mpd-music-updater')
+
+return music_func
\ No newline at end of file
diff --git a/awesome/widget/music/spotify-music-updater.lua b/awesome/widget/music/spotify-music-updater.lua
new file mode 100644
index 0000000..40331f6
--- /dev/null
+++ b/awesome/widget/music/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/awesome/widget/network/airplane_mode b/awesome/widget/network/airplane_mode
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/awesome/widget/network/airplane_mode
@@ -0,0 +1 @@
+false
diff --git a/awesome/widget/network/clickable-container.lua b/awesome/widget/network/clickable-container.lua
new file mode 100755
index 0000000..f531740
--- /dev/null
+++ b/awesome/widget/network/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/awesome/widget/network/icons/airplane-mode-off.svg b/awesome/widget/network/icons/airplane-mode-off.svg
new file mode 100644
index 0000000..7a4c91c
--- /dev/null
+++ b/awesome/widget/network/icons/airplane-mode-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/airplane-mode.svg b/awesome/widget/network/icons/airplane-mode.svg
new file mode 100644
index 0000000..70fc89d
--- /dev/null
+++ b/awesome/widget/network/icons/airplane-mode.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/awesome/widget/network/icons/loading.svg b/awesome/widget/network/icons/loading.svg
new file mode 100755
index 0000000..cd7bc0e
--- /dev/null
+++ b/awesome/widget/network/icons/loading.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-off.svg b/awesome/widget/network/icons/wifi-off.svg
new file mode 100755
index 0000000..dbcbc7a
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-off.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-1-alert.svg b/awesome/widget/network/icons/wifi-strength-1-alert.svg
new file mode 100755
index 0000000..7a8de11
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-1-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-1-lock.svg b/awesome/widget/network/icons/wifi-strength-1-lock.svg
new file mode 100755
index 0000000..9bcf910
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-1-lock.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-1.svg b/awesome/widget/network/icons/wifi-strength-1.svg
new file mode 100755
index 0000000..9e90049
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-1.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-2-alert.svg b/awesome/widget/network/icons/wifi-strength-2-alert.svg
new file mode 100755
index 0000000..970987a
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-2-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-2-lock.svg b/awesome/widget/network/icons/wifi-strength-2-lock.svg
new file mode 100755
index 0000000..cbedd27
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-2-lock.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-2.svg b/awesome/widget/network/icons/wifi-strength-2.svg
new file mode 100755
index 0000000..e65871e
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-2.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-3-alert.svg b/awesome/widget/network/icons/wifi-strength-3-alert.svg
new file mode 100755
index 0000000..e1b5a5f
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-3-alert.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-3-lock.svg b/awesome/widget/network/icons/wifi-strength-3-lock.svg
new file mode 100755
index 0000000..865d01a
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-3-lock.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-3.svg b/awesome/widget/network/icons/wifi-strength-3.svg
new file mode 100755
index 0000000..cec90d5
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-3.svg
@@ -0,0 +1,61 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-4-alert.svg b/awesome/widget/network/icons/wifi-strength-4-alert.svg
new file mode 100755
index 0000000..2d9d47d
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-4-alert.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-4-lock.svg b/awesome/widget/network/icons/wifi-strength-4-lock.svg
new file mode 100755
index 0000000..fb51f35
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-4-lock.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-4.svg b/awesome/widget/network/icons/wifi-strength-4.svg
new file mode 100755
index 0000000..259a3a9
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-4.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-alert-outline.svg b/awesome/widget/network/icons/wifi-strength-alert-outline.svg
new file mode 100755
index 0000000..3e4c33a
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-alert-outline.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/network/icons/wifi-strength-alert.svg b/awesome/widget/network/icons/wifi-strength-alert.svg
new file mode 100755
index 0000000..ca80f6c
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-alert.svg
@@ -0,0 +1,65 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-empty.svg b/awesome/widget/network/icons/wifi-strength-empty.svg
new file mode 100755
index 0000000..0a1380a
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-empty.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-lock-outline.svg b/awesome/widget/network/icons/wifi-strength-lock-outline.svg
new file mode 100755
index 0000000..3edc636
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-lock-outline.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-off-outline.svg b/awesome/widget/network/icons/wifi-strength-off-outline.svg
new file mode 100755
index 0000000..2f9b636
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-off-outline.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/network/icons/wifi-strength-off.svg b/awesome/widget/network/icons/wifi-strength-off.svg
new file mode 100755
index 0000000..12cb043
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-off.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/awesome/widget/network/icons/wifi-strength-outline.svg b/awesome/widget/network/icons/wifi-strength-outline.svg
new file mode 100755
index 0000000..00fcd26
--- /dev/null
+++ b/awesome/widget/network/icons/wifi-strength-outline.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/network/icons/wifi.svg b/awesome/widget/network/icons/wifi.svg
new file mode 100755
index 0000000..7887868
--- /dev/null
+++ b/awesome/widget/network/icons/wifi.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/awesome/widget/network/icons/wired-alert.svg b/awesome/widget/network/icons/wired-alert.svg
new file mode 100755
index 0000000..35481c0
--- /dev/null
+++ b/awesome/widget/network/icons/wired-alert.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/wired-off.svg b/awesome/widget/network/icons/wired-off.svg
new file mode 100755
index 0000000..f7c586a
--- /dev/null
+++ b/awesome/widget/network/icons/wired-off.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/icons/wired.svg b/awesome/widget/network/icons/wired.svg
new file mode 100755
index 0000000..00441ac
--- /dev/null
+++ b/awesome/widget/network/icons/wired.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/network/init.lua b/awesome/widget/network/init.lua
new file mode 100755
index 0000000..38dc463
--- /dev/null
+++ b/awesome/widget/network/init.lua
@@ -0,0 +1,376 @@
+----------------------------------------------------------------------------
+--- Simple Network Widget
+--
+-- Depends: iproute2, iw
+--
+-- For more details check `man maim`
+--
+-- @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 wlan_interface = 'wlp3s0'
+local lan_interface = 'enp0s25'
+
+local return_button = function()
+
+ local wifi_strength = nil
+
+ local connected_to_network = false
+ local conn_status = 'disconnected'
+ local essid = nil
+
+ local update_notify_no_access = true
+ local notify_no_access_quota = 0
+
+ local startup = true
+ local notify_new_wifi_conn = false
+
+ local net_speed = 'N/A'
+
+ 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 notify_not_connected = function()
+ local message = 'The network has been disconnected'
+ local title = 'Connection Disconnected'
+
+ if conn_status == 'wireless' then
+ icon = widget_icon_dir .. 'wifi-strength-off.svg'
+ elseif conn_status == 'wired' then
+ icon = widget_icon_dir .. 'wired-off.svg'
+ else
+ icon = widget_icon_dir .. 'wifi-strength-off.svg'
+ end
+
+ naughty.notification({
+ message = message,
+ title = title,
+ app_name = 'System Notification',
+ icon = icon
+ })
+
+ conn_status = 'disconnected'
+ end
+
+ local update_disconnected = function()
+ if conn_status == 'wireless' or conn_status == 'wired' then
+
+ local widget_icon_name = nil
+
+ connected_to_network = false
+ notify_new_wifi_conn = true
+ essid = nil
+ update_notify_no_access = true
+
+ if conn_status == 'wireless' then
+ widget_icon_name = 'wifi-strength-off'
+ elseif conn_status == 'wired' then
+ widget_icon_name = 'wired-off'
+ end
+
+ notify_not_connected()
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+ end
+
+ local notify_no_access = function(strength)
+ if conn_status == 'wireless' or conn_status == 'wired' then
+
+ local message = 'Internet may not be available or it is too slow right now'
+
+ if conn_status == 'wireless' then
+ icon = widget_icon_dir .. 'wifi-strength-' .. tostring(strength) .. '-alert.svg'
+ elseif conn_status == 'wired' then
+ icon = widget_icon_dir .. 'wired-off.svg'
+ end
+
+ naughty.notification({
+ message = message,
+ title = 'Connection Status',
+ app_name = 'System Notification',
+ icon = icon
+ })
+
+ end
+ end
+
+ local update_no_access = function(strength)
+
+ if not update_notify_no_access then
+ return
+ end
+
+ local widget_icon_name = nil
+
+ if conn_status == 'wireless' then
+ widget_icon_name = 'wifi-strength-' .. tostring(strength) .. '-alert'
+ elseif conn_status == 'wired' then
+ widget_icon_name = 'wired-alert'
+ end
+ notify_no_access(strength)
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+
+ update_notify_no_access = false
+
+ end
+
+
+ local notify_wifi_conn = function()
+ if startup then
+ startup = false
+ return
+ end
+
+ if not notify_new_wifi_conn then
+ return
+ end
+
+ local message = "You are now connected to \"" .. essid .. "\""
+ local title = "Connection Established"
+ local app_name = "System Notification"
+ local icon = widget_icon_dir .. 'wifi.svg'
+
+ naughty.notification({
+ message = message,
+ title = title,
+ app_name = app_name,
+ icon = icon
+ })
+
+ notify_new_wifi_conn = false
+ end
+
+
+ local update_essid = function()
+ if not essid and connected_to_network == true then
+ awful.spawn.easy_async_with_shell(
+ [[
+ iw dev ]] .. wlan_interface .. [[ link
+ ]],
+ function(stdout)
+ essid = stdout:match('SSID: (.-)\n')
+ if essid == nil then
+ essid = 'N/A'
+ end
+ notify_wifi_conn()
+ end
+ )
+ end
+ end
+
+ local check_internet_health = [[
+ status_curl=0
+ status_ping=0
+
+ ip="$(curl --connect-timeout 5 ifconfig.co)"
+ if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null;
+ then
+ status_curl=1
+ else
+ status_curl=0
+ fi
+
+ packets="$(ping -q -w4 -c4 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 ] && [ $status_curl -eq 0 ];
+ then
+ echo 'noaccess'
+ fi
+ ]]
+
+ local update_net_speed = function()
+
+ awful.spawn.easy_async_with_shell(
+ 'iw dev ' .. wlan_interface .. ' link',
+ function(stdout)
+ net_speed = stdout:match("tx bitrate: (.+/s)") or 'N/A'
+ end
+ )
+ end
+
+ local update_wireless = function()
+ conn_status = 'wireless'
+ connected_to_network = true
+
+ 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
+
+ local widget_icon_name = 'wifi-strength'
+
+ wifi_strength = tonumber(stdout)
+
+ local wifi_strength_rounded = math.floor(wifi_strength / 25 + 0.5)
+
+ awful.spawn.easy_async_with_shell(
+ check_internet_health,
+ function(stdout)
+ local widget_icon_name = widget_icon_name .. '-' .. wifi_strength_rounded
+ if stdout:match('noaccess') then
+ update_no_access(wifi_strength_rounded)
+ return
+ else
+ update_net_speed()
+ if startup then
+ awesome.emit_signal('system::wifi_connected')
+ end
+ update_notify_no_access = true
+ end
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+ )
+ end
+ )
+ update_essid()
+ end
+
+ local update_wired = function()
+ conn_status = 'wired'
+ connected_to_network = true
+
+ awful.spawn.easy_async_with_shell(
+ check_internet_health,
+ function(stdout)
+ widget_icon_name = 'wired'
+ if stdout:match('fail') then
+ update_no_access()
+ return
+ else
+ if startup then
+ awesome.emit_signal('system::wifi_connected')
+ startup = false
+ end
+ update_notify_no_access = true
+ end
+ widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg')
+ end
+ )
+
+ end
+
+ awful.tooltip(
+ {
+ objects = {widget_button},
+ mode = 'outside',
+ align = 'right',
+ timer_function = function()
+ if connected_to_network then
+ if conn_status == 'wireless' then
+ return 'Wireless Interface: ' .. wlan_interface ..
+ '\nConnected to: ' .. (essid or "*LOADING...*") ..
+ '\nWiFi-Strength: ' .. tostring(wifi_strength) .. '%' ..
+ '\nBit rate: ' .. tostring(net_speed) .. ''
+ else
+ return 'Ethernet Interface: ' .. lan_interface
+ end
+ else
+ return 'Network is currently disconnected'
+ end
+ end,
+ preferred_positions = {'left', 'right', 'top', 'bottom'},
+ margin_leftright = dpi(8),
+ margin_topbottom = dpi(8)
+ }
+ )
+
+ gears.timer {
+ timeout = 9,
+ autostart = true,
+ call_now = true,
+ callback = function()
+ awful.spawn.easy_async_with_shell(
+ [[
+ net_status="$(ip route get 8.8.8.8 2>&1 >/dev/null)"
+ if ]] .. "[[ " .. [[ "$(echo ${net_status} | awk -F ": " '{print $2}')" == *'unreachable'* ]] .. " ]];" .. [[
+ then
+ echo 'No internet connection'
+ exit;
+ fi
+
+ net_status="$(ip route get 8.8.8.8 | grep -Po 'dev \K\w+' | grep -Ff - /proc/net/wireless)"
+
+ if [ ! -z "${net_status}" ]
+ then
+ echo 'wireless'
+ else
+ echo 'wired'
+ fi
+ ]],
+ function(stdout)
+ if stdout:match('No internet connection') then
+ update_disconnected()
+ return
+ end
+
+ if stdout:match('wireless') then
+ update_wireless()
+ elseif stdout:match('wired') then
+ update_wired()
+ end
+ end
+ )
+ end
+ }
+
+ return widget_button
+
+end
+
+return return_button
diff --git a/awesome/widget/network/network-toggle.lua b/awesome/widget/network/network-toggle.lua
new file mode 100755
index 0000000..20f57be
--- /dev/null
+++ b/awesome/widget/network/network-toggle.lua
@@ -0,0 +1,173 @@
+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.network.clickable-container')
+
+local config_dir = gears.filesystem.get_configuration_dir()
+local widget_dir = config_dir .. 'widget/network/'
+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 = 'SF Pro Text 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/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua b/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua
new file mode 100644
index 0000000..877d241
--- /dev/null
+++ b/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 = 'SF Pro Text Bold 14',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+ },
+ {
+ text = 'Come back later.',
+ font = 'SF Pro Text 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/awesome/widget/notif-center/build-notifbox/init.lua b/awesome/widget/notif-center/build-notifbox/init.lua
new file mode 100644
index 0000000..46b779b
--- /dev/null
+++ b/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(5),
+ 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/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua b/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua
new file mode 100644
index 0000000..55bf6ee
--- /dev/null
+++ b/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 = 'SF Pro Text 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/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua b/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua
new file mode 100644
index 0000000..3fe79da
--- /dev/null
+++ b/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/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua b/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua
new file mode 100644
index 0000000..f05d323
--- /dev/null
+++ b/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/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua b/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua
new file mode 100644
index 0000000..2e1b30a
--- /dev/null
+++ b/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 = 'SF Pro Text 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 = 'SF Pro Text 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 = 'SF Pro Text 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 = 'SF Pro Text 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/awesome/widget/notif-center/clear-all/init.lua b/awesome/widget/notif-center/clear-all/init.lua
new file mode 100644
index 0000000..7c14657
--- /dev/null
+++ b/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/awesome/widget/notif-center/dont-disturb/disturb_status b/awesome/widget/notif-center/dont-disturb/disturb_status
new file mode 100644
index 0000000..c508d53
--- /dev/null
+++ b/awesome/widget/notif-center/dont-disturb/disturb_status
@@ -0,0 +1 @@
+false
diff --git a/awesome/widget/notif-center/dont-disturb/init.lua b/awesome/widget/notif-center/dont-disturb/init.lua
new file mode 100644
index 0000000..df9d952
--- /dev/null
+++ b/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/awesome/widget/notif-center/icons/clear_all.svg b/awesome/widget/notif-center/icons/clear_all.svg
new file mode 100644
index 0000000..3f5b9b4
--- /dev/null
+++ b/awesome/widget/notif-center/icons/clear_all.svg
@@ -0,0 +1,91 @@
+
+
+
+
diff --git a/awesome/widget/notif-center/icons/delete.svg b/awesome/widget/notif-center/icons/delete.svg
new file mode 100644
index 0000000..3f1f88c
--- /dev/null
+++ b/awesome/widget/notif-center/icons/delete.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/awesome/widget/notif-center/icons/dont-disturb-mode.svg b/awesome/widget/notif-center/icons/dont-disturb-mode.svg
new file mode 100644
index 0000000..d5dc170
--- /dev/null
+++ b/awesome/widget/notif-center/icons/dont-disturb-mode.svg
@@ -0,0 +1,64 @@
+
+
diff --git a/awesome/widget/notif-center/icons/empty-notification.svg b/awesome/widget/notif-center/icons/empty-notification.svg
new file mode 100644
index 0000000..df4154c
--- /dev/null
+++ b/awesome/widget/notif-center/icons/empty-notification.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/awesome/widget/notif-center/icons/new-notif.svg b/awesome/widget/notif-center/icons/new-notif.svg
new file mode 100644
index 0000000..630b90a
--- /dev/null
+++ b/awesome/widget/notif-center/icons/new-notif.svg
@@ -0,0 +1,15 @@
+
diff --git a/awesome/widget/notif-center/icons/notify-mode.svg b/awesome/widget/notif-center/icons/notify-mode.svg
new file mode 100644
index 0000000..92b960b
--- /dev/null
+++ b/awesome/widget/notif-center/icons/notify-mode.svg
@@ -0,0 +1,91 @@
+
+
diff --git a/awesome/widget/notif-center/init.lua b/awesome/widget/notif-center/init.lua
new file mode 100644
index 0000000..76c50f5
--- /dev/null
+++ b/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 = 'SF Pro Text 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/awesome/widget/package-updater/icons/package-up.svg b/awesome/widget/package-updater/icons/package-up.svg
new file mode 100644
index 0000000..2251baa
--- /dev/null
+++ b/awesome/widget/package-updater/icons/package-up.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/package-updater/icons/package.svg b/awesome/widget/package-updater/icons/package.svg
new file mode 100644
index 0000000..7d4b2f9
--- /dev/null
+++ b/awesome/widget/package-updater/icons/package.svg
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/package-updater/init.lua b/awesome/widget/package-updater/init.lua
new file mode 100644
index 0000000..c131f3b
--- /dev/null
+++ b/awesome/widget/package-updater/init.lua
@@ -0,0 +1,122 @@
+-------------------------------------------------
+-- Package Updater Widget for Awesome Window Manager
+-- Shows the package updates information in Arch Linux
+-- Will only show if there is/are updates available
+-------------------------------------------------
+
+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
+ )
+ )
+ )
+
+
+ -- Tooltip
+ 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
+
+ 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
\ No newline at end of file
diff --git a/awesome/widget/ram/ram-meter.lua b/awesome/widget/ram/ram-meter.lua
new file mode 100644
index 0000000..98cd68d
--- /dev/null
+++ b/awesome/widget/ram/ram-meter.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 = '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.*"',
+ 5,
+ 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/awesome/widget/screen-recorder/icons/audio.svg b/awesome/widget/screen-recorder/icons/audio.svg
new file mode 100644
index 0000000..2f8668f
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/audio.svg
@@ -0,0 +1,71 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/icons/back.svg b/awesome/widget/screen-recorder/icons/back.svg
new file mode 100644
index 0000000..f0e76e5
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/back.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/screen-recorder/icons/close-screen.svg b/awesome/widget/screen-recorder/icons/close-screen.svg
new file mode 100644
index 0000000..3f1f88c
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/close-screen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/icons/recorder-countdown.svg b/awesome/widget/screen-recorder/icons/recorder-countdown.svg
new file mode 100644
index 0000000..63134d5
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/recorder-countdown.svg
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/awesome/widget/screen-recorder/icons/recorder-off.svg b/awesome/widget/screen-recorder/icons/recorder-off.svg
new file mode 100644
index 0000000..8ade140
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/recorder-off.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/awesome/widget/screen-recorder/icons/recorder-on.svg b/awesome/widget/screen-recorder/icons/recorder-on.svg
new file mode 100644
index 0000000..29800ca
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/recorder-on.svg
@@ -0,0 +1,71 @@
+
+
+
+
diff --git a/awesome/widget/screen-recorder/icons/recording-button.svg b/awesome/widget/screen-recorder/icons/recording-button.svg
new file mode 100644
index 0000000..4caa7b3
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/recording-button.svg
@@ -0,0 +1,86 @@
+
+
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/icons/settings.svg b/awesome/widget/screen-recorder/icons/settings.svg
new file mode 100644
index 0000000..2c5a0b9
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/settings.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/screen-recorder/icons/start-recording-button.svg b/awesome/widget/screen-recorder/icons/start-recording-button.svg
new file mode 100644
index 0000000..986f9dd
--- /dev/null
+++ b/awesome/widget/screen-recorder/icons/start-recording-button.svg
@@ -0,0 +1,14 @@
+
+
diff --git a/awesome/widget/screen-recorder/init.lua b/awesome/widget/screen-recorder/init.lua
new file mode 100644
index 0000000..230924f
--- /dev/null
+++ b/awesome/widget/screen-recorder/init.lua
@@ -0,0 +1,23 @@
+local wibox = require('wibox')
+local awful = require('awful')
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local dpi = require('beautiful').xresources.apply_dpi
+
+local HOME = os.getenv('HOME')
+
+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
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/screen-recorder-config.lua b/awesome/widget/screen-recorder/screen-recorder-config.lua
new file mode 100644
index 0000000..8e0c2e2
--- /dev/null
+++ b/awesome/widget/screen-recorder/screen-recorder-config.lua
@@ -0,0 +1,10 @@
+local user_preferences = {}
+
+user_preferences.user_resolution = '1366x768' -- Screen WIDTHxHEIGHT
+user_preferences.user_offset = '0,0' -- Offset x,y
+user_preferences.user_audio = false -- bool true or false
+user_preferences.user_save_directory = '$(xdg-user-dir VIDEOS)/Recordings/' -- String $HOME
+user_preferences.user_mic_lvl = '20' -- String
+user_preferences.user_fps = '30' -- String
+
+return user_preferences
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/screen-recorder-scripts.lua b/awesome/widget/screen-recorder/screen-recorder-scripts.lua
new file mode 100644
index 0000000..12c7fa8
--- /dev/null
+++ b/awesome/widget/screen-recorder/screen-recorder-scripts.lua
@@ -0,0 +1,172 @@
+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()
+ awesome.kill(
+ ffmpeg_pid, awesome.unix_signal.SIGINT
+ )
+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 = 'Screenshot 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 .. [[ $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
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua b/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua
new file mode 100644
index 0000000..f1cbab5
--- /dev/null
+++ b/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua
@@ -0,0 +1,597 @@
+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)
+
+ -- naughty.notification({message=sr_active_tbox})
+
+ 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
+
+ -- screen_rec_audio_button
+
+ 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
+ )
+ )
+)
\ No newline at end of file
diff --git a/awesome/widget/screen-recorder/screen-recorder-ui.lua b/awesome/widget/screen-recorder/screen-recorder-ui.lua
new file mode 100644
index 0000000..df51f4f
--- /dev/null
+++ b/awesome/widget/screen-recorder/screen-recorder-ui.lua
@@ -0,0 +1,352 @@
+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 = 'SF Pro Text 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 = 'SF Pro Display 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 = 'SF Pro Display 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 = 'SF Pro Display 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 = 'SF Pro Display 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 = 'SF Pro Display 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
\ No newline at end of file
diff --git a/awesome/widget/search-apps/icons/app-launcher.svg b/awesome/widget/search-apps/icons/app-launcher.svg
new file mode 100644
index 0000000..616879f
--- /dev/null
+++ b/awesome/widget/search-apps/icons/app-launcher.svg
@@ -0,0 +1,257 @@
+
+
+
+
diff --git a/awesome/widget/search-apps/init.lua b/awesome/widget/search-apps/init.lua
new file mode 100644
index 0000000..d578091
--- /dev/null
+++ b/awesome/widget/search-apps/init.lua
@@ -0,0 +1,67 @@
+-------------------------------------------------
+-- Rofi toggler widget for Awesome Window Manager
+-- Shows the application list
+-- Use rofi-git master branch
+-------------------------------------------------
+
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+
+local filesystem = gears.filesystem
+local dpi = require('beautiful').xresources.apply_dpi
+
+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 .. '/widget/search-apps/icons/'
+
+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()
+ local focused = awful.screen.focused()
+
+ if focused.left_panel then
+ focused.left_panel:HideDashboard()
+ focused.left_panel.opened = false
+ end
+ if focused.right_panel then
+ focused.right_panel:HideDashboard()
+ end
+ awful.spawn(apps.default.rofiappmenu, false)
+ end
+ )
+ )
+ )
+
+
+ return widget_button
+end
+
+return return_button
\ No newline at end of file
diff --git a/awesome/widget/social-media/icons/facebook.svg b/awesome/widget/social-media/icons/facebook.svg
new file mode 100644
index 0000000..1052f58
--- /dev/null
+++ b/awesome/widget/social-media/icons/facebook.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/awesome/widget/social-media/icons/instagram.svg b/awesome/widget/social-media/icons/instagram.svg
new file mode 100644
index 0000000..afda8b7
--- /dev/null
+++ b/awesome/widget/social-media/icons/instagram.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/awesome/widget/social-media/icons/reddit.svg b/awesome/widget/social-media/icons/reddit.svg
new file mode 100644
index 0000000..b94ef6f
--- /dev/null
+++ b/awesome/widget/social-media/icons/reddit.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/awesome/widget/social-media/icons/twitter.svg b/awesome/widget/social-media/icons/twitter.svg
new file mode 100644
index 0000000..76840b2
--- /dev/null
+++ b/awesome/widget/social-media/icons/twitter.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/awesome/widget/social-media/init.lua b/awesome/widget/social-media/init.lua
new file mode 100644
index 0000000..ce049c7
--- /dev/null
+++ b/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 = 'SF Pro Text 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/awesome/widget/tag-list.lua b/awesome/widget/tag-list.lua
new file mode 100644
index 0000000..8811ff2
--- /dev/null
+++ b/awesome/widget/tag-list.lua
@@ -0,0 +1,172 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local capi = {button = _G.button}
+local clickable_container = require('widget.clickable-container')
+local modkey = require('configuration.keys.mod').modKey
+--- Common method to create buttons.
+-- @tab buttons
+-- @param object
+-- @treturn 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 = capi.button {modifiers = b.modifiers, button = b.button}
+ btn:connect_signal(
+ 'press',
+ function()
+ b:emit_signal('press', object)
+ end
+ )
+ btn:connect_signal(
+ '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 TagList = 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 TagList
diff --git a/awesome/widget/task-list.lua b/awesome/widget/task-list.lua
new file mode 100644
index 0000000..9f8fece
--- /dev/null
+++ b/awesome/widget/task-list.lua
@@ -0,0 +1,248 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local dpi = require('beautiful').xresources.apply_dpi
+local capi = {button = _G.button}
+local gears = require('gears')
+
+local clickable_container = require('widget.clickable-container')
+local icons = require('theme.icons')
+
+--- sub string for utf8 format
+-- @s the string need to be sub
+-- @i index of start position
+-- @j index of end position
+local function utf8_sub(s, i, j)
+ i = utf8.offset(s, i)
+ j = (utf8.offset(s, j + 1) or j + 1) - 1
+ return gears.string.xml_escape(s:sub(i, j))
+end
+
+--- Common method to create buttons.
+-- @tab buttons
+-- @param object
+-- @treturn 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 = capi.button {modifiers = b.modifiers, button = b.button}
+ btn:connect_signal(
+ 'press',
+ function()
+ b:emit_signal('press', object)
+ end
+ )
+ btn:connect_signal(
+ '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 (text_only:len() > 24) then
+ text = text:gsub('>(.-)<', '>' .. utf8_sub(text_only,1,21) .. '...<')
+ 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 == _G.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
+ _G.client.focus = c
+ 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 TaskList = function(s)
+ return awful.widget.tasklist(
+ s,
+ awful.widget.tasklist.filter.currenttags,
+ tasklist_buttons,
+ {},
+ list_update,
+ wibox.layout.fixed.horizontal()
+ )
+end
+
+return TaskList
diff --git a/awesome/widget/temperature/temperature-meter.lua b/awesome/widget/temperature/temperature-meter.lua
new file mode 100644
index 0000000..5fe2e4b
--- /dev/null
+++ b/awesome/widget/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/awesome/widget/tray-toggler/icons/left-arrow.svg b/awesome/widget/tray-toggler/icons/left-arrow.svg
new file mode 100644
index 0000000..f0e76e5
--- /dev/null
+++ b/awesome/widget/tray-toggler/icons/left-arrow.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/tray-toggler/icons/right-arrow.svg b/awesome/widget/tray-toggler/icons/right-arrow.svg
new file mode 100644
index 0000000..7446424
--- /dev/null
+++ b/awesome/widget/tray-toggler/icons/right-arrow.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/tray-toggler/init.lua b/awesome/widget/tray-toggler/init.lua
new file mode 100644
index 0000000..af5765d
--- /dev/null
+++ b/awesome/widget/tray-toggler/init.lua
@@ -0,0 +1,80 @@
+-------------------------------------------------
+-- Toggle System tray
+-------------------------------------------------
+
+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-toggler/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 screen.primary.systray.visible ~= true 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/awesome/widget/user-profile/init.lua b/awesome/widget/user-profile/init.lua
new file mode 100644
index 0000000..eae9c17
--- /dev/null
+++ b/awesome/widget/user-profile/init.lua
@@ -0,0 +1,222 @@
+-- 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',
+ clip_shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) end,
+ widget = wibox.widget.imagebox,
+ resize = true
+ },
+ layout = wibox.layout.align.horizontal
+}
+
+profile_imagebox:buttons(
+ gears.table.join(
+ awful.button(
+ {},
+ 1,
+ 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 = "SF Pro Text Bold 14",
+ markup = 'User',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local distro_name = wibox.widget {
+ font = "SF Pro Text Regular 11",
+ markup = 'GNU/Linux',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local kernel_version = wibox.widget {
+ font = "SF Pro Text Regular 10",
+ markup = 'Linux',
+ align = 'left',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local uptime_time = wibox.widget {
+ font = "SF Pro Text 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.bins.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(
+ "printf \"$(whoami)@$(hostname)\"",
+ function(stdout)
+ local stdout = stdout:gsub('%\n', '')
+ -- stdout = stdout:sub(1,1):upper() .. stdout:sub(2)
+ 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/awesome/widget/volume/volume-slider.lua b/awesome/widget/volume/volume-slider.lua
new file mode 100644
index 0000000..6e16e63
--- /dev/null
+++ b/awesome/widget/volume/volume-slider.lua
@@ -0,0 +1,141 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+
+local watch = awful.widget.watch
+local spawn = awful.spawn
+
+local dpi = beautiful.xresources.apply_dpi
+
+local icons = require('theme.icons')
+
+local slider = wibox.widget {
+ nil,
+ {
+ id = 'vol_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 volume_slider = slider.vol_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()
+
+-- 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 {
+ {
+ {
+ {
+ image = icons.volume,
+ 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 volume_setting
diff --git a/awesome/widget/weather/icons/d_rain.svg b/awesome/widget/weather/icons/d_rain.svg
new file mode 100644
index 0000000..44cacc1
--- /dev/null
+++ b/awesome/widget/weather/icons/d_rain.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dbroken_clouds.svg b/awesome/widget/weather/icons/dbroken_clouds.svg
new file mode 100644
index 0000000..8fa8005
--- /dev/null
+++ b/awesome/widget/weather/icons/dbroken_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dfew_clouds.svg b/awesome/widget/weather/icons/dfew_clouds.svg
new file mode 100644
index 0000000..a4f1fd3
--- /dev/null
+++ b/awesome/widget/weather/icons/dfew_clouds.svg
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dmist.svg b/awesome/widget/weather/icons/dmist.svg
new file mode 100644
index 0000000..b23f3bf
--- /dev/null
+++ b/awesome/widget/weather/icons/dmist.svg
@@ -0,0 +1,77 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dscattered_clouds.svg b/awesome/widget/weather/icons/dscattered_clouds.svg
new file mode 100644
index 0000000..9c0ebcb
--- /dev/null
+++ b/awesome/widget/weather/icons/dscattered_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dshower_rain.svg b/awesome/widget/weather/icons/dshower_rain.svg
new file mode 100644
index 0000000..3a88004
--- /dev/null
+++ b/awesome/widget/weather/icons/dshower_rain.svg
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/dthunderstorm.svg b/awesome/widget/weather/icons/dthunderstorm.svg
new file mode 100644
index 0000000..10375e4
--- /dev/null
+++ b/awesome/widget/weather/icons/dthunderstorm.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/moon_icon.svg b/awesome/widget/weather/icons/moon_icon.svg
new file mode 100644
index 0000000..b9e5c3a
--- /dev/null
+++ b/awesome/widget/weather/icons/moon_icon.svg
@@ -0,0 +1,67 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/n_rain.svg b/awesome/widget/weather/icons/n_rain.svg
new file mode 100644
index 0000000..3ba466a
--- /dev/null
+++ b/awesome/widget/weather/icons/n_rain.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nbroken_clouds.svg b/awesome/widget/weather/icons/nbroken_clouds.svg
new file mode 100644
index 0000000..d462c33
--- /dev/null
+++ b/awesome/widget/weather/icons/nbroken_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nfew_clouds.svg b/awesome/widget/weather/icons/nfew_clouds.svg
new file mode 100644
index 0000000..74575ee
--- /dev/null
+++ b/awesome/widget/weather/icons/nfew_clouds.svg
@@ -0,0 +1,83 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nmist.svg b/awesome/widget/weather/icons/nmist.svg
new file mode 100644
index 0000000..34d0e41
--- /dev/null
+++ b/awesome/widget/weather/icons/nmist.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nscattered_clouds.svg b/awesome/widget/weather/icons/nscattered_clouds.svg
new file mode 100644
index 0000000..007e66b
--- /dev/null
+++ b/awesome/widget/weather/icons/nscattered_clouds.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nshower_rain.svg b/awesome/widget/weather/icons/nshower_rain.svg
new file mode 100644
index 0000000..50b4ebc
--- /dev/null
+++ b/awesome/widget/weather/icons/nshower_rain.svg
@@ -0,0 +1,73 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/nthunderstorm.svg b/awesome/widget/weather/icons/nthunderstorm.svg
new file mode 100644
index 0000000..73f67e5
--- /dev/null
+++ b/awesome/widget/weather/icons/nthunderstorm.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/refresh.svg b/awesome/widget/weather/icons/refresh.svg
new file mode 100644
index 0000000..0eb9ef7
--- /dev/null
+++ b/awesome/widget/weather/icons/refresh.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/awesome/widget/weather/icons/snow.svg b/awesome/widget/weather/icons/snow.svg
new file mode 100644
index 0000000..f4fcc6a
--- /dev/null
+++ b/awesome/widget/weather/icons/snow.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/sun_icon.svg b/awesome/widget/weather/icons/sun_icon.svg
new file mode 100644
index 0000000..24ac40d
--- /dev/null
+++ b/awesome/widget/weather/icons/sun_icon.svg
@@ -0,0 +1,64 @@
+
+
+
+
diff --git a/awesome/widget/weather/icons/sunrise.svg b/awesome/widget/weather/icons/sunrise.svg
new file mode 100644
index 0000000..f0e8a47
--- /dev/null
+++ b/awesome/widget/weather/icons/sunrise.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/awesome/widget/weather/icons/sunset.svg b/awesome/widget/weather/icons/sunset.svg
new file mode 100644
index 0000000..d60f574
--- /dev/null
+++ b/awesome/widget/weather/icons/sunset.svg
@@ -0,0 +1,72 @@
+
+
diff --git a/awesome/widget/weather/icons/weather-error.svg b/awesome/widget/weather/icons/weather-error.svg
new file mode 100644
index 0000000..afcb331
--- /dev/null
+++ b/awesome/widget/weather/icons/weather-error.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/awesome/widget/weather/init.lua b/awesome/widget/weather/init.lua
new file mode 100644
index 0000000..dee5371
--- /dev/null
+++ b/awesome/widget/weather/init.lua
@@ -0,0 +1,369 @@
+local awful = require('awful')
+local beautiful = require('beautiful')
+local naughty = require('naughty')
+local wibox = require('wibox')
+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/weather/icons/'
+
+local clickable_container = require('widget.clickable-container')
+
+local secrets = require('configuration.secrets')
+
+local key = secrets.weather.key
+local city_id = secrets.weather.city_id
+local units = secrets.weather.units
+
+local update_interval = 1200
+
+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')
+ 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 = 'SF Pro Text Bold 12',
+ 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 = 'SF Pro Text Regular 12',
+ 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 = 'SF Pro Text Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local weather_sunset = wibox.widget {
+ markup = "00:00",
+ font = 'SF Pro Text Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+local weather_data_time = wibox.widget {
+ markup = "00:00",
+ font = 'SF Pro Text Regular 10',
+ align = 'center',
+ valign = 'center',
+ widget = wibox.widget.textbox
+}
+
+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,
+ spacing = dpi(3),
+ 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
+}
+
+if units == "metric" then
+ weather_temperature_symbol = "°C"
+elseif units == "imperial" then
+ weather_temperature_symbol = "°F"
+end
+
+-- Weather script using your API KEY
+local weather_details_script = [[
+KEY="]]..key..[["
+CITY="]]..city_id..[["
+UNITS="]]..units..[["
+
+weather=$(curl -sf "http://api.openweathermap.org/data/2.5/weather?APPID="${KEY}"&id="${CITY}"&units="${UNITS}"")
+
+if [ ! -z "$weather" ]; then
+ weather_icon="icon=$(printf "$weather" | jq -r ".weather[].icon" | head -1)"
+
+ weather_location="location=$(printf "$weather" | jq -r ".name")"
+ weather_country="country=$(printf "$weather" | jq -r ".sys.country")"
+
+ weather_sunrise="sunrise=$(printf "$weather" | jq -r ".sys.sunrise" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)"
+ weather_sunset="sunset=$(printf "$weather" | jq -r ".sys.sunset" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)"
+
+ weather_data_time="update=$(printf "$weather" | jq -r ".dt" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)"
+
+ weather_temp="temperature=$(printf "$weather" | jq ".main.temp" | cut -d "." -f 1)"
+
+ weather_description="details=$(printf "$weather" | jq -r ".weather[].description" | head -1)"
+
+ DATA="${weather_icon}\n${weather_location}\n${weather_country}\n${weather_sunrise}\n${weather_sunset}\n${weather_data_time}\n${weather_temp}\n${weather_description}\n"
+ printf "${DATA}"
+
+else
+ printf "icon=..."
+fi
+]]
+
+awesome.connect_signal(
+ 'widget::weather_fetch',
+ function()
+
+ awful.spawn.easy_async_with_shell(
+ weather_details_script,
+ function(stdout)
+
+ local weather_data_tbl = {}
+
+ for data in stdout:gmatch("[^\n]+") do
+ local key = data:match("(.*)=")
+ local value = data:match("=(.*)")
+ weather_data_tbl[key] = value
+ end
+
+ local icon_code = weather_data_tbl['icon']
+
+ if icon_code == '...' then
+
+ awesome.emit_signal("widget::weather_update",
+ icon_code,
+ 'dust and clouds, -1000°C',
+ 'Earth, Milky Way',
+ '00:00',
+ '00:00',
+ '00:00'
+ )
+
+ else
+ local location = weather_data_tbl['location']
+ local country = weather_data_tbl['country']
+ local sunrise = weather_data_tbl['sunrise']
+ local sunset = weather_data_tbl['sunset']
+ local update_time = weather_data_tbl['update']
+ local temperature = weather_data_tbl['temperature']
+ local details = weather_data_tbl['details']
+
+ local description = details:sub(1, 1):upper() .. details:sub(2)
+ local weather_description = description .. ', ' .. temperature .. weather_temperature_symbol
+ local weather_location = location .. ', ' .. country
+
+ awesome.emit_signal("widget::weather_update",
+ icon_code,
+ weather_description,
+ weather_location,
+ sunrise,
+ sunset,
+ update_time
+ )
+ end
+ collectgarbage('collect')
+ end
+ )
+end)
+
+local update_widget_timer = gears.timer {
+ timeout = update_interval,
+ autostart = true,
+ call_now = true,
+ single_shot = false,
+ callback = function()
+ awesome.emit_signal('widget::weather_fetch')
+ end
+}
+
+awesome.connect_signal(
+ 'system::wifi_connected',
+ function()
+ gears.timer.start_new(
+ 5,
+ function()
+ awesome.emit_signal('widget::weather_fetch')
+ end
+ )
+ 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/awesome/widget/window-effects/blur-strength-slider.lua b/awesome/widget/window-effects/blur-strength-slider.lua
new file mode 100644
index 0000000..1fc4b11
--- /dev/null
+++ b/awesome/widget/window-effects/blur-strength-slider.lua
@@ -0,0 +1,141 @@
+local wibox = require('wibox')
+local gears = require('gears')
+local awful = require('awful')
+local beautiful = require('beautiful')
+
+local dpi = beautiful.xresources.apply_dpi
+
+local start_up = true
+
+local icons = require('theme.icons')
+
+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',
+ 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_slider_value()
+
+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 blur_slider_setting = wibox.widget {
+ {
+ {
+ {
+ image = icons.effects,
+ 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 blur_slider_setting
diff --git a/awesome/widget/window-effects/blur-toggle.lua b/awesome/widget/window-effects/blur-toggle.lua
new file mode 100644
index 0000000..e8d078c
--- /dev/null
+++ b/awesome/widget/window-effects/blur-toggle.lua
@@ -0,0 +1,144 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local gears = require('gears')
+
+local clickable_container = require('widget.window-effects.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 = 'SF Pro Text 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/awesome/widget/window-effects/clickable-container.lua b/awesome/widget/window-effects/clickable-container.lua
new file mode 100644
index 0000000..f531740
--- /dev/null
+++ b/awesome/widget/window-effects/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/awesome/widget/xdg-folders/documents.lua b/awesome/widget/xdg-folders/documents.lua
new file mode 100644
index 0000000..dc05b06
--- /dev/null
+++ b/awesome/widget/xdg-folders/documents.lua
@@ -0,0 +1,55 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+ }
+)
+
+return docu_button
diff --git a/awesome/widget/xdg-folders/downloads.lua b/awesome/widget/xdg-folders/downloads.lua
new file mode 100644
index 0000000..ed0f5a2
--- /dev/null
+++ b/awesome/widget/xdg-folders/downloads.lua
@@ -0,0 +1,56 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+ }
+)
+
+
+return downloads_button
diff --git a/awesome/widget/xdg-folders/home.lua b/awesome/widget/xdg-folders/home.lua
new file mode 100644
index 0000000..93bf43a
--- /dev/null
+++ b/awesome/widget/xdg-folders/home.lua
@@ -0,0 +1,55 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+ }
+)
+
+
+return home_button
diff --git a/awesome/widget/xdg-folders/icons/folder-documents.svg b/awesome/widget/xdg-folders/icons/folder-documents.svg
new file mode 100644
index 0000000..e6a53e5
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/folder-documents.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/folder-download.svg b/awesome/widget/xdg-folders/icons/folder-download.svg
new file mode 100644
index 0000000..9b75134
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/folder-download.svg
@@ -0,0 +1,134 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/folder-pictures.svg b/awesome/widget/xdg-folders/icons/folder-pictures.svg
new file mode 100644
index 0000000..014b5b3
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/folder-pictures.svg
@@ -0,0 +1,127 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/folder-videos.svg b/awesome/widget/xdg-folders/icons/folder-videos.svg
new file mode 100644
index 0000000..50b53df
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/folder-videos.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/no.svg b/awesome/widget/xdg-folders/icons/no.svg
new file mode 100644
index 0000000..0654b8a
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/no.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/open-folder.svg b/awesome/widget/xdg-folders/icons/open-folder.svg
new file mode 100644
index 0000000..f1f131d
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/open-folder.svg
@@ -0,0 +1,110 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/user-home.svg b/awesome/widget/xdg-folders/icons/user-home.svg
new file mode 100644
index 0000000..b0a0839
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/user-home.svg
@@ -0,0 +1,126 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/user-trash-empty.svg b/awesome/widget/xdg-folders/icons/user-trash-empty.svg
new file mode 100644
index 0000000..f4d107f
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/user-trash-empty.svg
@@ -0,0 +1,160 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/user-trash-full.svg b/awesome/widget/xdg-folders/icons/user-trash-full.svg
new file mode 100644
index 0000000..2d75d2d
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/user-trash-full.svg
@@ -0,0 +1,979 @@
+
+
diff --git a/awesome/widget/xdg-folders/icons/yes.svg b/awesome/widget/xdg-folders/icons/yes.svg
new file mode 100644
index 0000000..2617c5d
--- /dev/null
+++ b/awesome/widget/xdg-folders/icons/yes.svg
@@ -0,0 +1,69 @@
+
+
diff --git a/awesome/widget/xdg-folders/init.lua b/awesome/widget/xdg-folders/init.lua
new file mode 100644
index 0000000..e8adc84
--- /dev/null
+++ b/awesome/widget/xdg-folders/init.lua
@@ -0,0 +1,27 @@
+local awful = require('awful')
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+
+local dpi = require('beautiful').xresources.apply_dpi
+
+local separator = wibox.widget {
+ orientation = 'horizontal',
+ forced_height = 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,
+ },
+}
diff --git a/awesome/widget/xdg-folders/pictures.lua b/awesome/widget/xdg-folders/pictures.lua
new file mode 100644
index 0000000..4123c75
--- /dev/null
+++ b/awesome/widget/xdg-folders/pictures.lua
@@ -0,0 +1,56 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+ }
+)
+
+
+return pic_button
diff --git a/awesome/widget/xdg-folders/trash.lua b/awesome/widget/xdg-folders/trash.lua
new file mode 100644
index 0000000..909036a
--- /dev/null
+++ b/awesome/widget/xdg-folders/trash.lua
@@ -0,0 +1,134 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+}
+
+-- 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, false)
+
+
+ else
+ trash_widget.trash_icon:set_image(widget_icon_dir .. 'user-trash-empty' .. '.svg')
+
+ trash_tooltip.markup = 'Trash empty'
+
+ end
+ end, false)
+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, false)
+
+
+return trash_button
diff --git a/awesome/widget/xdg-folders/videos.lua b/awesome/widget/xdg-folders/videos.lua
new file mode 100644
index 0000000..d2e8b6d
--- /dev/null
+++ b/awesome/widget/xdg-folders/videos.lua
@@ -0,0 +1,56 @@
+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 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 = {'right', 'left', 'top', 'bottom'}
+}
+
+return videos_button
diff --git a/picom.conf b/picom.conf
index 9cbedec..a6fb7fb 100644
--- a/picom.conf
+++ b/picom.conf
@@ -41,11 +41,11 @@ shadow-opacity = .75
# The left offset for shadows, in pixels. (defaults to -15)
# shadow-offset-x = -15
-shadow-offset-x = -7;
+shadow-offset-x = -17;
# The top offset for shadows, in pixels. (defaults to -15)
# shadow-offset-y = -15
-shadow-offset-y = -7;
+shadow-offset-y = -17;
# Avoid drawing shadows on dock/panel windows. This option is deprecated,
# you should use the *wintypes* option in your config file instead.