diff --git a/.config/awesome/configuration/apps.lua b/.config/awesome/configuration/apps.lua new file mode 100644 index 0000000..246996a --- /dev/null +++ b/.config/awesome/configuration/apps.lua @@ -0,0 +1,86 @@ +local filesystem = require('gears.filesystem') +local config_dir = filesystem.get_configuration_dir() +local utils_dir = config_dir .. 'utilities/' + +return { + -- The default applications that we will use in keybindings and widgets + default = { + -- Default terminal emulator + terminal = 'alacritty', + -- Default web browser + web_browser = 'firefox', + -- Default text editor + text_editor = 'subl3', + -- Default file manager + file_manager = 'dolphin', + -- Default media player + multimedia = 'vlc', + -- Default game, can be a launcher like steam + game = 'supertuxkart', + -- Default graphics editor + graphics = 'gimp-2.10', + -- Default sandbox + sandbox = 'virtualbox', + -- Default IDE + development = '', + -- Default network manager + network_manager = 'kitty iwctl', + -- Default bluetooth manager + bluetooth_manager = 'blueman-manager', + -- Default power manager + power_manager = 'xfce4-power-manager', + -- Default GUI package manager + package_manager = 'pamac-manager', + -- Default locker + lock = 'awesome-client "awesome.emit_signal(\'module::lockscreen_show\')"', + -- Default quake terminal + quake = 'alacritty --name QuakeTerminal', + -- Default rofi global menu + rofi_global = 'rofi -dpi ' .. screen.primary.dpi .. + ' -show "Global Search" -modi "Global Search":' .. config_dir .. + '/configuration/rofi/global/rofi-spotlight.sh' .. + ' -theme ' .. config_dir .. + '/configuration/rofi/global/rofi.rasi', + -- Default app menu + rofi_appmenu = 'rofi -dpi ' .. screen.primary.dpi .. + ' -show drun -theme ' .. config_dir .. + '/configuration/rofi/appmenu/rofi.rasi' + + -- You can add more default applications here + }, + + -- List of apps to start once on start-up + run_on_start_up = { + -- Compositor + 'picom -b --experimental-backends --dbus --config ' .. + config_dir .. '/configuration/picom.conf', + -- Blueman applet + 'blueman-applet', + -- Music server + 'mpd', + -- Polkit and keyring + '/usr/bin/lxqt-policykit-agent &' .. + ' eval $(gnome-keyring-daemon -s --components=pkcs11,secrets,ssh,gpg)', + -- Load X colors + 'xrdb $HOME/.Xresources', + -- Audio equalizer + 'pulseeffects --gapplication-service', + -- Lockscreen timer + [[ + xidlehook --not-when-fullscreen --not-when-audio --timer 600 \ + "awesome-client 'awesome.emit_signal(\"module::lockscreen_show\")'" "" + ]] + + -- You can add more start-up applications here + }, + + -- List of binaries/shell scripts that will execute for a certain task + utils = { + -- Fullscreen screenshot + full_screenshot = utils_dir .. 'snap full', + -- Area screenshot + area_screenshot = utils_dir .. 'snap area', + -- Update profile picture + update_profile = utils_dir .. 'profile-image' + } +} diff --git a/.config/awesome/configuration/client/buttons.lua b/.config/awesome/configuration/client/buttons.lua new file mode 100644 index 0000000..e744393 --- /dev/null +++ b/.config/awesome/configuration/client/buttons.lua @@ -0,0 +1,37 @@ +local awful = require('awful') +local modkey = require('configuration.keys.mod').mod_key + +return awful.util.table.join( + awful.button( + {}, + 1, + function(c) + c:emit_signal('request::activate') + c:raise() + end + ), + awful.button( + {modkey}, + 1, + awful.mouse.client.move + ), + awful.button( + {modkey}, + 3, + awful.mouse.client.resize + ), + awful.button( + {modkey}, + 4, + function() + awful.layout.inc(1) + end + ), + awful.button( + {modkey}, + 5, + function() + awful.layout.inc(-1) + end + ) +) diff --git a/.config/awesome/configuration/client/init.lua b/.config/awesome/configuration/client/init.lua new file mode 100644 index 0000000..a5bc872 --- /dev/null +++ b/.config/awesome/configuration/client/init.lua @@ -0,0 +1,2 @@ +require('configuration.client.rules') +require('configuration.client.signals') diff --git a/.config/awesome/configuration/client/keys.lua b/.config/awesome/configuration/client/keys.lua new file mode 100644 index 0000000..3182e41 --- /dev/null +++ b/.config/awesome/configuration/client/keys.lua @@ -0,0 +1,216 @@ +local awful = require('awful') +local gears = require('gears') +local dpi = require('beautiful').xresources.apply_dpi +require('awful.autofocus') +local modkey = require('configuration.keys.mod').mod_key +local altkey = require('configuration.keys.mod').alt_key + +local client_keys = awful.util.table.join( + awful.key( + {modkey}, + 'f', + function(c) + c.fullscreen = not c.fullscreen + c:raise() + end, + {description = 'toggle fullscreen', group = 'client'} + ), + awful.key( + {modkey}, + 'q', + function(c) + c:kill() + end, + {description = 'close', group = 'client'} + ), + awful.key( + {modkey}, + 'd', + function() + awful.client.focus.byidx(1) + end, + {description = 'focus next by index', group = 'client'} + ), + awful.key( + {modkey}, + 'a', + function() + awful.client.focus.byidx(-1) + end, + {description = 'focus previous by index', group = 'client'} + ), + awful.key( + { modkey, 'Shift' }, + 'd', + function () + awful.client.swap.byidx(1) + end, + {description = 'swap with next client by index', group = 'client'} + ), + awful.key( + { modkey, 'Shift' }, + 'a', + function () + awful.client.swap.byidx(-1) + end, + {description = 'swap with next client by index', group = 'client'} + ), + awful.key( + {modkey}, + 'u', + awful.client.urgent.jumpto, + {description = 'jump to urgent client', group = 'client'} + ), + awful.key( + {modkey}, + 'Tab', + function() + awful.client.focus.history.previous() + if client.focus then + client.focus:raise() + end + end, + {description = 'go back', group = 'client'} + ), + awful.key( + {modkey}, + 'n', + function(c) + c.minimized = true + end, + {description = 'minimize client', group = 'client'} + ), + awful.key( + { modkey, 'Shift' }, + 'c', + function(c) + local focused = awful.screen.focused() + + awful.placement.centered(c, { + honor_workarea = true + }) + end, + {description = 'align a client to the center of the focused screen', group = 'client'} + ), + awful.key( + {modkey}, + 'c', + function(c) + c.fullscreen = false + c.maximized = false + c.floating = not c.floating + c:raise() + end, + {description = 'toggle floating', group = 'client'} + ), + awful.key( + {modkey}, + 'Up', + function(c) + c:relative_move(0, dpi(-10), 0, 0) + end, + {description = 'move floating client up by 10 px', group = 'client'} + ), + awful.key( + {modkey}, + 'Down', + function(c) + c:relative_move(0, dpi(10), 0, 0) + end, + {description = 'move floating client down by 10 px', group = 'client'} + ), + awful.key( + {modkey}, + 'Left', + function(c) + c:relative_move(dpi(-10), 0, 0, 0) + end, + {description = 'move floating client to the left by 10 px', group = 'client'} + ), + awful.key( + {modkey}, + 'Right', + function(c) + c:relative_move(dpi(10), 0, 0, 0) + end, + {description = 'move floating client to the right by 10 px', group = 'client'} + ), + awful.key( + {modkey, 'Shift'}, + 'Up', + function(c) + c:relative_move(0, dpi(-10), 0, dpi(10)) + end, + {description = 'increase floating client size vertically by 10 px up', group = 'client'} + ), + awful.key( + {modkey, 'Shift'}, + 'Down', + function(c) + c:relative_move(0, 0, 0, dpi(10)) + end, + {description = 'increase floating client size vertically by 10 px down', group = 'client'} + ), + awful.key( + {modkey, 'Shift'}, + 'Left', + function(c) + c:relative_move(dpi(-10), 0, dpi(10), 0) + end, + {description = 'increase floating client size horizontally by 10 px left', group = 'client'} + ), + awful.key( + {modkey, 'Shift'}, + 'Right', + function(c) + c:relative_move(0, 0, dpi(10), 0) + end, + {description = 'increase floating client size horizontally by 10 px right', group = 'client'} + ), + awful.key( + {modkey, 'Control'}, + 'Up', + function(c) + if c.height > 10 then + c:relative_move(0, 0, 0, dpi(-10)) + end + end, + {description = 'decrease floating client size vertically by 10 px up', group = 'client'} + ), + awful.key( + {modkey, 'Control'}, + 'Down', + function(c) + local c_height = c.height + c:relative_move(0, 0, 0, dpi(-10)) + if c.height ~= c_height and c.height > 10 then + c:relative_move(0, dpi(10), 0, 0) + end + end, + {description = 'decrease floating client size vertically by 10 px down', group = 'client'} + ), + awful.key( + {modkey, 'Control'}, + 'Left', + function(c) + if c.width > 10 then + c:relative_move(0, 0, dpi(-10), 0) + end + end, + {description = 'decrease floating client size horizontally by 10 px left', group = 'client'} + ), + awful.key( + {modkey, 'Control'}, + 'Right', + function(c) + local c_width = c.width + c:relative_move(0, 0, dpi(-10), 0) + if c.width ~= c_width and c.width > 10 then + c:relative_move(dpi(10), 0 , 0, 0) + end + end, + {description = 'decrease floating client size horizontally by 10 px right', group = 'client'} + ) +) + +return client_keys diff --git a/.config/awesome/configuration/client/rules.lua b/.config/awesome/configuration/client/rules.lua new file mode 100644 index 0000000..0ab0b11 --- /dev/null +++ b/.config/awesome/configuration/client/rules.lua @@ -0,0 +1,393 @@ +local awful = require('awful') +local gears = require('gears') +local ruled = require('ruled') +local beautiful = require('beautiful') +local client_keys = require('configuration.client.keys') +local client_buttons = require('configuration.client.buttons') + +ruled.client.connect_signal( + 'request::rules', + function() + -- All clients will match this rule. + ruled.client.append_rule { + id = 'global', + rule = {}, + properties = { + focus = awful.client.focus.filter, + raise = true, + floating = false, + maximized = false, + above = false, + below = false, + ontop = false, + sticky = false, + maximized_horizontal = false, + maximized_vertical = false, + keys = client_keys, + buttons = client_buttons, + screen = awful.screen.preferred, + placement = awful.placement.no_overlap + awful.placement.no_offscreen + } + } + + ruled.client.append_rule { + id = 'round_clients', + rule_any = { + type = { + 'normal', + 'dialog' + } + }, + except_any = { + name = {'Discord Updater'} + }, + properties = { + round_corners = true, + shape = beautiful.client_shape_rounded + } + } + + -- Titlebar rules + ruled.client.append_rule { + id = 'titlebars', + rule_any = { + type = { + 'normal', + 'dialog', + 'modal', + 'utility' + } + }, + properties = { + titlebars_enabled = true + } + } + + -- Dialogs + ruled.client.append_rule { + id = 'dialog', + rule_any = { + type = {'dialog'}, + class = {'Wicd-client.py', 'calendar.google.com'} + }, + properties = { + titlebars_enabled = true, + floating = true, + above = true, + skip_decoration = true, + placement = awful.placement.centered + } + } + + -- Modals + ruled.client.append_rule { + id = 'modal', + rule_any = { + type = {'modal'} + }, + properties = { + titlebars_enabled = true, + floating = true, + above = true, + skip_decoration = true, + placement = awful.placement.centered + } + } + + -- Utilities + ruled.client.append_rule { + id = 'utility', + rule_any = { + type = {'utility'} + }, + properties = { + titlebars_enabled = false, + floating = true, + skip_decoration = true, + placement = awful.placement.centered + } + } + + -- Splash + ruled.client.append_rule { + id = 'splash', + rule_any = { + type = {'splash'}, + name = {'Discord Updater'} + }, + properties = { + titlebars_enabled = false, + round_corners = false, + floating = true, + above = true, + skip_decoration = true, + placement = awful.placement.centered + } + } + + -- Terminal emulators + ruled.client.append_rule { + id = 'terminals', + rule_any = { + class = { + 'URxvt', + 'XTerm', + 'UXTerm', + 'kitty', + 'K3rmit' + } + }, + properties = { + tag = '1', + switch_to_tags = true, + size_hints_honor = false, + titlebars_enabled = true + } + } + + -- Browsers and chats + ruled.client.append_rule { + id = 'internet', + rule_any = { + class = { + 'firefox', + 'Tor Browser', + 'discord', + 'Chromium', + 'Google-chrome', + 'TelegramDesktop' + } + }, + properties = { + tag = '2' + } + } + + -- Text editors and word processing + ruled.client.append_rule { + id = 'text', + rule_any = { + class = { + 'Geany', + 'Atom', + 'Subl3', + 'code-oss' + }, + name = { + 'LibreOffice', + 'libreoffice' + } + }, + properties = { + tag = '3' + } + } + + -- File managers + ruled.client.append_rule { + id = 'files', + rule_any = { + class = { + 'dolphin', + 'ark', + 'Nemo', + 'File-roller' + } + }, + properties = { + tag = '4', + switch_to_tags = true + } + } + + -- Multimedia + ruled.client.append_rule { + id = 'multimedia', + rule_any = { + class = { + 'vlc', + 'Spotify' + } + }, + properties = { + tag = '5', + switch_to_tags = true, + placement = awful.placement.centered + } + } + + -- Gaming + ruled.client.append_rule { + id = 'gaming', + rule_any = { + class = { + 'Wine', + 'dolphin-emu', + 'Steam', + 'Citra', + 'supertuxkart' + }, + name = {'Steam'} + }, + properties = { + tag = '6', + skip_decoration = true, + switch_to_tags = true, + placement = awful.placement.centered + } + } + + -- Multimedia Editing + ruled.client.append_rule { + id = 'graphics', + rule_any = { + class = { + 'Gimp-2.10', + 'Inkscape', + 'Flowblade' + } + }, + properties = { + tag = '7' + } + } + + -- Sandboxes and VMs + ruled.client.append_rule { + id = 'sandbox', + rule_any = { + class = { + 'VirtualBox Manage', + 'VirtualBox Machine', + 'Gnome-boxes', + 'Virt-manager' + } + }, + properties = { + tag = '8' + } + } + + -- IDEs and Tools + ruled.client.append_rule { + id = 'development', + rule_any = { + class = { + 'Oomox', + 'Unity', + 'UnityHub', + 'jetbrains-studio', + 'Ettercap', + 'scrcpy' + } + }, + properties = { + tag = '9', + skip_decoration = true + } + } + + -- Image viewers + ruled.client.append_rule { + id = 'image_viewers', + rule_any = { + class = { + 'feh', + 'Pqiv', + 'Sxiv' + }, + }, + properties = { + titlebars_enabled = true, + skip_decoration = true, + floating = true, + ontop = true, + placement = awful.placement.centered + } + } + + -- Floating + ruled.client.append_rule { + id = 'floating', + rule_any = { + instance = { + 'file_progress', + 'Popup', + 'nm-connection-editor', + }, + class = { + 'scrcpy', + 'Mugshot', + 'Pulseeffects' + }, + role = { + 'AlarmWindow', + 'ConfigManager', + 'pop-up' + } + }, + properties = { + titlebars_enabled = true, + skip_decoration = true, + ontop = true, + floating = true, + focus = awful.client.focus.filter, + raise = true, + keys = client_keys, + buttons = client_buttons, + placement = awful.placement.centered + } + } + end +) + +-- Normally we'd do this with a rule, but some program like spotify doesn't set its class or name +-- until after it starts up, so we need to catch that signal. +client.connect_signal( + 'property::class', + function(c) + if c.class == 'Spotify' then + local window_mode = false + + -- Check if fullscreen or window mode + if c.fullscreen then + window_mode = false + c.fullscreen = false + else + window_mode = true + end + + -- Check if Spotify is already open + local app = function (c) + return ruled.client.match(c, {class = 'Spotify'}) + end + + local app_count = 0 + for c in awful.client.iterate(app) do + app_count = app_count + 1 + end + + -- If Spotify is already open, don't open a new instance + if app_count > 1 then + c:kill() + -- Switch to previous instance + for c in awful.client.iterate(app) do + c:jump_to(false) + end + else + -- Move the instance to specified tag on this screen + local t = awful.tag.find_by_name(awful.screen.focused(), '5') + c:move_to_tag(t) + t:view_only() + + -- Fullscreen mode if not window mode + if not window_mode then + c.fullscreen = true + else + c.floating = true + awful.placement.centered(c, {honor_workarea = true}) + end + end + end + end +) diff --git a/.config/awesome/configuration/client/signals.lua b/.config/awesome/configuration/client/signals.lua new file mode 100644 index 0000000..a13a4aa --- /dev/null +++ b/.config/awesome/configuration/client/signals.lua @@ -0,0 +1,115 @@ +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') + +local update_client = function(c) + -- Set client's shape based on its tag's layout and status (floating, maximized, etc.) + local current_layout = awful.tag.getproperty(c.first_tag, 'layout') + if current_layout == awful.layout.suit.max and (not c.floating) then + c.shape = beautiful.client_shape_rectangle + elseif c.maximized or c.fullscreen then + c.shape = beautiful.client_shape_rectangle + elseif (not c.round_corners) then + c.shape = beautiful.client_shape_rectangle + else + c.shape = beautiful.client_shape_rounded + end +end + +-- Signal function to execute when a new client appears. +client.connect_signal( + 'manage', + function(c) + -- Focus, raise and activate + c:emit_signal( + 'request::activate', + 'mouse_enter', + { + raise = true + } + ) + + -- Set the windows at the slave, + -- i.e. put it at the end of others instead of setting it master. + if not awesome.startup then + awful.client.setslave(c) + end + + if awesome.startup and not c.size_hints.user_position and + not c.size_hints.program_position then + -- Prevent clients from being unreachable after screen count changes. + awful.placement.no_offscreen(c) + end + + -- Update client shape + update_client(c) + end +) + +-- Enable sloppy focus, so that focus follows mouse then raises it. +client.connect_signal( + 'mouse::enter', + function(c) + c:emit_signal( + 'request::activate', + 'mouse_enter', + { + raise = true + } + ) + end +) + +client.connect_signal( + 'focus', + function(c) + c.border_color = beautiful.border_focus + end +) + +client.connect_signal( + 'unfocus', + function(c) + c.border_color = beautiful.border_normal + end +) + +-- Manipulate client shape on fullscreen/non-fullscreen +client.connect_signal( + 'property::fullscreen', + function(c) + if c.fullscreen then + c.shape = beautiful.client_shape_rectangle + else + update_client(c) + end + end +) + +-- Manipulate client shape on maximized +client.connect_signal( + 'property::maximized', + function(c) + local current_layout = awful.tag.getproperty(c.first_tag, 'layout') + if c.maximized then + c.shape = beautiful.client_shape_rectangle + else + update_client(c) + end + end +) + +-- Manipulate client shape on floating +client.connect_signal( + 'property::floating', + function(c) + local current_layout = awful.tag.getproperty(c.first_tag, 'layout') + if c.floating and not c.maximized then + c.shape = beautiful.client_shape_rounded + else + if current_layout == awful.layout.suit.max then + c.shape = beautiful.client_shape_rectangle + end + end + end +) diff --git a/.config/awesome/configuration/config.lua b/.config/awesome/configuration/config.lua new file mode 100644 index 0000000..7bc752d --- /dev/null +++ b/.config/awesome/configuration/config.lua @@ -0,0 +1,103 @@ +return { + widget = { + email = { + -- Email address + address = '', + -- App password + app_password = '', + -- Imap server + imap_server = 'imap.gmail.com', + -- Port + port = '993' + }, + + weather = { + -- API Key + key = '67784a48d58d4cab5beb5d7f1b03a4ce', + -- City ID + city_id = '2153953', + -- Units + units = 'metric', + -- Update in N seconds + update_interval = 1200 + }, + + network = { + -- Wired interface + wired_interface = 'enp34s0', + -- Wireless interface + wireless_interface = 'wlan0' + }, + + clock = { + -- Clock widget format + military_mode = false + }, + + screen_recorder = { + -- Default record dimension + resolution = '1366x768', + -- X,Y coordinate + offset = '0,0', + -- Enable audio by default + audio = false, + -- Recordings directory + save_directory = '$(xdg-user-dir VIDEOS)/Recordings/', + -- Mic level + mic_level = '20', + -- FPS + fps = '30' + } + }, + + module = { + auto_start = { + -- Will create notification if true + debug_mode = false + }, + + dynamic_wallpaper = { + -- Will look for wallpapers here + wall_dir = 'theme/wallpapers/', + -- Image formats + valid_picture_formats = {'jpg', 'png', 'jpeg'}, + -- Leave this table empty for full auto scheduling + wallpaper_schedule = { + ['00:00:00'] = 'midnight-wallpaper.jpg', + ['06:22:00'] = 'morning-wallpaper.jpg', + ['12:00:00'] = 'noon-wallpaper.jpg', + ['17:58:00'] = 'night-wallpaper.jpg' + -- Example of just using auto-scheduling with keywords + --[[ + 'midnight', + 'morning', + 'noon', + 'afternoon', + 'evening', + 'night' + --]] + }, + -- Stretch background image across all screens(monitor) + stretch = true + }, + + lockscreen = { + -- Clock format + military_clock = false, + -- Default password if there's no PAM integration + fallback_password = 'toor', + -- Capture intruder using webcam + capture_intruder = true, + -- Intruder image save location (Will create directory if it doesn't exist) + face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/', + -- Background directory - Defaults to 'awesome/config/theme/wallpapers/' if null + bg_dir = nil, + -- Will look for this image file under 'bg_dir' + bg_image = 'locksreen-bg.jpg', + -- Blur lockscreen background + blur_background = false, + -- Blurred/filtered background image path (No reason to change this) + tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/' + } + } +} diff --git a/.config/awesome/configuration/config.lua.broken b/.config/awesome/configuration/config.lua.broken new file mode 100644 index 0000000..76b4f4c --- /dev/null +++ b/.config/awesome/configuration/config.lua.broken @@ -0,0 +1,103 @@ +return { + widget = { + email = { + -- Email address + address = '', + -- App password + app_password = '', + -- Imap server + imap_server = 'imap.gmail.com', + -- Port + port = '993' + }, + + weather = { + -- API Key + key = '67784a48d58d4cab5beb5d7f1b03a4ce', + -- City ID + city_id = '2153953', + -- Units + units = 'metric', + -- Update in N seconds + update_interval = 1200 + }, + + network = { + -- Wired interface + wired_interface = 'enp34s0', + -- Wireless interface + wireless_interface = 'wlan0' + }, + + clock = { + -- Clock widget format + military_mode = false + }, + + screen_recorder = { + -- Default record dimension + resolution = '1366x768', + -- X,Y coordinate + offset = '0,0', + -- Enable audio by default + audio = false, + -- Recordings directory + save_directory = '$(xdg-user-dir VIDEOS)/Recordings/', + -- Mic level + mic_level = '20', + -- FPS + fps = '30' + } + }, + + module = { + auto_start = { + -- Will create notification if true + debug_mode = true + }, + + -- dynamic_wallpaper = { + -- -- Will look for wallpapers here + -- wall_dir = 'theme/wallpapers/', + -- -- Image formats + -- valid_picture_formats = {'jpg', 'png', 'jpeg'}, + -- -- Leave this table empty for full auto scheduling + -- wallpaper_schedule = { + -- ['00:00:00'] = 'midnight-wallpaper.jpg', + -- ['06:22:00'] = 'morning-wallpaper.jpg', + -- ['12:00:00'] = 'noon-wallpaper.jpg', + -- ['17:58:00'] = 'night-wallpaper.jpg' + -- -- Example of just using auto-scheduling with keywords + -- --[[ + -- 'midnight', + -- 'morning', + -- 'noon', + -- 'afternoon', + -- 'evening', + -- 'night' + -- --]] + -- }, + -- -- Stretch background image across all screens(monitor) + -- stretch = true + -- }, + + lockscreen = { + -- Clock format + military_clock = false, + -- Default password if there's no PAM integration + fallback_password = 'toor', + -- Capture intruder using webcam + capture_intruder = true, + -- Intruder image save location (Will create directory if it doesn't exist) + face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/', + -- Background directory - Defaults to 'awesome/config/theme/wallpapers/' if null + bg_dir = nil, + -- Will look for this image file under 'bg_dir' + bg_image = 'locksreen-bg.jpg', + -- Blur lockscreen background + blur_background = false, + -- Blurred/filtered background image path (No reason to change this) + tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/' + } + } +} diff --git a/.config/awesome/configuration/init.lua b/.config/awesome/configuration/init.lua new file mode 100644 index 0000000..f93e86b --- /dev/null +++ b/.config/awesome/configuration/init.lua @@ -0,0 +1,4 @@ +return { + keys = require('configuration.keys'), + apps = require('configuration.apps') +} diff --git a/.config/awesome/configuration/keys/global.lua b/.config/awesome/configuration/keys/global.lua new file mode 100644 index 0000000..90ad1f2 --- /dev/null +++ b/.config/awesome/configuration/keys/global.lua @@ -0,0 +1,606 @@ +local awful = require('awful') +local beautiful = require('beautiful') + +require('awful.autofocus') + +local hotkeys_popup = require('awful.hotkeys_popup').widget + +local modkey = require('configuration.keys.mod').mod_key +local altkey = require('configuration.keys.mod').alt_key +local apps = require('configuration.apps') + +-- Key bindings +local global_keys = awful.util.table.join( + + -- Hotkeys + awful.key( + {modkey}, + 'F1', + hotkeys_popup.show_help, + {description = 'show help', group = 'awesome'} + ), + awful.key({modkey, 'Control'}, + 'r', + awesome.restart, + {description = 'reload awesome', group = 'awesome'} + ), + + awful.key({modkey, 'Control'}, + 'q', + awesome.quit, + {description = 'quit awesome', group = 'awesome'} + ), + awful.key( + {altkey, 'Shift'}, + 'l', + function() + awful.tag.incmwfact(0.05) + end, + {description = 'increase master width factor', group = 'layout'} + ), + awful.key( + {altkey, 'Shift'}, + 'h', + function() + awful.tag.incmwfact(-0.05) + end, + {description = 'decrease master width factor', group = 'layout'} + ), + awful.key( + {modkey, 'Shift'}, + 'h', + function() + awful.tag.incnmaster(1, nil, true) + end, + {description = 'increase the number of master clients', group = 'layout'} + ), + awful.key( + {modkey, 'Shift'}, + 'l', + function() + awful.tag.incnmaster(-1, nil, true) + end, + {description = 'decrease the number of master clients', group = 'layout'} + ), + awful.key( + {modkey, 'Control'}, + 'h', + function() + awful.tag.incncol(1, nil, true) + end, + {description = 'increase the number of columns', group = 'layout'} + ), + awful.key( + {modkey, 'Control'}, + 'l', + function() + awful.tag.incncol(-1, nil, true) + end, + {description = 'decrease the number of columns', group = 'layout'} + ), + awful.key( + {modkey}, + 'space', + function() + awful.layout.inc(1) + end, + {description = 'select next layout', group = 'layout'} + ), + awful.key( + {modkey, 'Shift'}, + 'space', + function() + awful.layout.inc(-1) + end, + {description = 'select previous layout', group = 'layout'} + ), + awful.key( + {modkey}, + 'o', + function() + awful.tag.incgap(1) + end, + {description = 'increase gap', group = 'layout'} + ), + awful.key( + {modkey, 'Shift'}, + 'o', + function() + awful.tag.incgap(-1) + end, + {description = 'decrease gap', group = 'layout'} + ), + awful.key( + {modkey}, + 'w', + awful.tag.viewprev, + {description = 'view previous tag', group = 'tag'} + ), + awful.key( + {modkey}, + 's', + awful.tag.viewnext, + {description = 'view next tag', group = 'tag'} + ), + awful.key( + {modkey}, + 'Escape', + awful.tag.history.restore, + {description = 'alternate between current and previous tag', group = 'tag'} + ), + awful.key({ modkey, 'Control' }, + 'w', + function () + -- tag_view_nonempty(-1) + local focused = awful.screen.focused() + for i = 1, #focused.tags do + awful.tag.viewidx(-1, focused) + if #focused.clients > 0 then + return + end + end + end, + {description = 'view previous non-empty tag', group = 'tag'} + ), + awful.key({ modkey, 'Control' }, + 's', + function () + -- tag_view_nonempty(1) + local focused = awful.screen.focused() + for i = 1, #focused.tags do + awful.tag.viewidx(1, focused) + if #focused.clients > 0 then + return + end + end + end, + {description = 'view next non-empty tag', group = 'tag'} + ), + awful.key( + {modkey, 'Shift'}, + 'F1', + function() + awful.screen.focus_relative(-1) + end, + { description = 'focus the previous screen', group = 'screen'} + ), + awful.key( + {modkey, 'Shift'}, + 'F2', + function() + awful.screen.focus_relative(1) + end, + { description = 'focus the next screen', group = 'screen'} + ), + awful.key( + {modkey, 'Control'}, + 'n', + function() + local c = awful.client.restore() + -- Focus restored client + if c then + c:emit_signal('request::activate') + c:raise() + end + end, + {description = 'restore minimized', group = 'screen'} + ), + awful.key( + {}, + 'XF86MonBrightnessUp', + function() + awful.spawn('light -A 10', false) + awesome.emit_signal('widget::brightness') + awesome.emit_signal('module::brightness_osd:show', true) + end, + {description = 'increase brightness by 10%', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86MonBrightnessDown', + function() + awful.spawn('light -U 10', false) + awesome.emit_signal('widget::brightness') + awesome.emit_signal('module::brightness_osd:show', true) + end, + {description = 'decrease brightness by 10%', group = 'hotkeys'} + ), + -- ALSA volume control + awful.key( + {}, + 'XF86AudioRaiseVolume', + function() + awful.spawn('amixer -D pulse sset Master 5%+', false) + awesome.emit_signal('widget::volume') + awesome.emit_signal('module::volume_osd:show', true) + end, + {description = 'increase volume up by 5%', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86AudioLowerVolume', + function() + awful.spawn('amixer -D pulse sset Master 5%-', false) + awesome.emit_signal('widget::volume') + awesome.emit_signal('module::volume_osd:show', true) + end, + {description = 'decrease volume up by 5%', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86AudioMute', + function() + awful.spawn('amixer -D pulse set Master 1+ toggle', false) + end, + {description = 'toggle mute', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86AudioNext', + function() + awful.spawn('mpc next', false) + end, + {description = 'next music', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86AudioPrev', + function() + awful.spawn('mpc prev', false) + end, + {description = 'previous music', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86AudioPlay', + function() + awful.spawn('mpc toggle', false) + end, + {description = 'play/pause music', group = 'hotkeys'} + + ), + awful.key( + {}, + 'XF86AudioMicMute', + function() + awful.spawn('amixer set Capture toggle', false) + end, + {description = 'mute microphone', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86PowerDown', + function() + -- + end, + {description = 'shutdown skynet', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86PowerOff', + function() + awesome.emit_signal('module::exit_screen:show') + end, + {description = 'toggle exit screen', group = 'hotkeys'} + ), + awful.key( + {}, + 'XF86Display', + function() + awful.spawn.single_instance('arandr', false) + end, + {description = 'arandr', group = 'hotkeys'} + ), + awful.key( + {modkey, 'Shift'}, + 'q', + function() + awesome.emit_signal('module::exit_screen:show') + end, + {description = 'toggle exit screen', group = 'hotkeys'} + ), + awful.key( + {modkey}, + '`', + function() + awesome.emit_signal('module::quake_terminal:toggle') + end, + {description = 'dropdown application', group = 'launcher'} + ), + awful.key( + {modkey}, + 'm', + function() + if awful.screen.focused().musicpop then + awesome.emit_signal('widget::music', 'keyboard') + end + end, + {description = 'toggle music widget', group = 'launcher'} + ), + awful.key( + { }, + 'Print', + function () + -- awful.spawn.easy_async_with_shell(apps.utils.full_screenshot,function() end) + awful.util.spawn("flameshot gui") + end, + {description = 'fullscreen screenshot', group = 'Utility'} + ), + awful.key( + {modkey, 'Shift'}, + 's', + function () + awful.spawn.easy_async_with_shell(apps.utils.area_screenshot,function() end) + end, + {description = 'area/selected screenshot', group = 'Utility'} + ), + awful.key( + {modkey}, + 'x', + function() + awesome.emit_signal('widget::blur:toggle') + end, + {description = 'toggle blur effects', group = 'Utility'} + ), + awful.key( + {modkey}, + ']', + function() + awesome.emit_signal('widget::blur:increase') + end, + {description = 'increase blur effect by 10%', group = 'Utility'} + ), + awful.key( + {modkey}, + '[', + function() + awesome.emit_signal('widget::blur:decrease') + end, + {description = 'decrease blur effect by 10%', group = 'Utility'} + ), + awful.key( + {modkey}, + 't', + function() + awesome.emit_signal('widget::blue_light:toggle') + end, + {description = 'toggle redshift filter', group = 'Utility'} + ), + awful.key( + { 'Control' }, + 'Escape', + function () + if screen.primary.systray then + if not screen.primary.tray_toggler then + local systray = screen.primary.systray + systray.visible = not systray.visible + else + awesome.emit_signal('widget::systray:toggle') + end + end + end, + {description = 'toggle systray visibility', group = 'Utility'} + ), + awful.key( + {modkey}, + 'l', + function() + awful.spawn(apps.default.lock, false) + end, + {description = 'lock the screen', group = 'Utility'} + ), + awful.key( + {modkey}, + 'Return', + function() + awful.spawn(apps.default.terminal) + end, + {description = 'open default terminal', group = 'launcher'} + ), + awful.key( + {modkey, 'Shift'}, + 'e', + function() + awful.spawn(apps.default.file_manager) + end, + {description = 'open default file manager', group = 'launcher'} + ), + awful.key( + {modkey, 'Shift'}, + 'f', + function() + awful.spawn(apps.default.web_browser) + end, + {description = 'open default web browser', group = 'launcher'} + ), + awful.key( + {'Control', 'Shift'}, + 'Escape', + function() + awful.spawn(apps.default.terminal .. ' ' .. 'htop') + end, + {description = 'open system monitor', group = 'launcher'} + ), + awful.key( + {modkey}, + 'e', + function() + local focused = awful.screen.focused() + + if focused.left_panel then + focused.left_panel:hide_dashboard() + focused.left_panel.opened = false + end + if focused.right_panel then + focused.right_panel:hide_dashboard() + focused.right_panel.opened = false + end + awful.spawn(apps.default.rofi_appmenu, false) + end, + {description = 'open application drawer', group = 'launcher'} + ), + awful.key( + {}, + 'XF86Launch1', + function() + local focused = awful.screen.focused() + + if focused.left_panel then + focused.left_panel:hide_dashboard() + focused.left_panel.opened = false + end + if focused.right_panel then + focused.right_panel:hide_dashboard() + focused.right_panel.opened = false + end + awful.spawn(apps.default.rofi_appmenu, false) + end, + {description = 'open application drawer', group = 'launcher'} + ), + awful.key( + {modkey}, + 'r', + function() + local focused = awful.screen.focused() + + if focused.right_panel and focused.right_panel.visible then + focused.right_panel.visible = false + end + screen.primary.left_panel:toggle() + end, + {description = 'open sidebar', group = 'launcher'} + ), + awful.key( + {modkey, 'Shift'}, + 'r', + function() + local focused = awful.screen.focused() + + if focused.right_panel and focused.right_panel.visible then + focused.right_panel.visible = false + end + screen.primary.left_panel:toggle(true) + end, + {description = 'open sidebar and global search', group = 'launcher'} + ), + awful.key( + {modkey}, + 'F2', + function() + local focused = awful.screen.focused() + + if focused.left_panel and focused.left_panel.opened then + focused.left_panel:toggle() + end + + if focused.right_panel then + if _G.right_panel_mode == 'today_mode' or not focused.right_panel.visible then + focused.right_panel:toggle() + switch_rdb_pane('today_mode') + else + switch_rdb_pane('today_mode') + end + + _G.right_panel_mode = 'today_mode' + end + end, + {description = 'open today pane', group = 'launcher'} + ), + awful.key( + {modkey}, + 'F3', + function() + local focused = awful.screen.focused() + + if focused.left_panel and focused.left_panel.opened then + focused.left_panel:toggle() + end + + if focused.right_panel then + if _G.right_panel_mode == 'notif_mode' or not focused.right_panel.visible then + focused.right_panel:toggle() + switch_rdb_pane('notif_mode') + else + switch_rdb_pane('notif_mode') + end + + _G.right_panel_mode = 'notif_mode' + end + end, + {description = 'open notification center', group = 'launcher'} + ) +) + +-- Bind all key numbers to tags. +-- Be careful: we use keycodes to make it work on any keyboard layout. +-- This should map on the top row of your keyboard, usually 1 to 9. +for i = 1, 9 do + -- Hack to only show tags 1 and 9 in the shortcut window (mod+s) + local descr_view, descr_toggle, descr_move, descr_toggle_focus + if i == 1 or i == 9 then + descr_view = {description = 'view tag #', group = 'tag'} + descr_toggle = {description = 'toggle tag #', group = 'tag'} + descr_move = {description = 'move focused client to tag #', group = 'tag'} + descr_toggle_focus = {description = 'toggle focused client on tag #', group = 'tag'} + end + global_keys = + awful.util.table.join( + global_keys, + -- View tag only. + awful.key( + {modkey}, + '#' .. i + 9, + function() + local focused = awful.screen.focused() + local tag = focused.tags[i] + if tag then + tag:view_only() + end + end, + descr_view + ), + -- Toggle tag display. + awful.key( + {modkey, 'Control'}, + '#' .. i + 9, + function() + local focused = awful.screen.focused() + local tag = focused.tags[i] + if tag then + awful.tag.viewtoggle(tag) + end + end, + descr_toggle + ), + -- Move client to tag. + awful.key( + {modkey, 'Shift'}, + '#' .. i + 9, + function() + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:move_to_tag(tag) + end + end + end, + descr_move + ), + -- Toggle tag on focused client. + awful.key( + {modkey, 'Control', 'Shift'}, + '#' .. i + 9, + function() + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:toggle_tag(tag) + end + end + end, + descr_toggle_focus + ) + ) +end + +return global_keys diff --git a/.config/awesome/configuration/keys/init.lua b/.config/awesome/configuration/keys/init.lua new file mode 100644 index 0000000..9591667 --- /dev/null +++ b/.config/awesome/configuration/keys/init.lua @@ -0,0 +1,4 @@ +return { + mod = require('configuration.keys.mod'), + global = require('configuration.keys.global') +} diff --git a/.config/awesome/configuration/keys/mod.lua b/.config/awesome/configuration/keys/mod.lua new file mode 100644 index 0000000..d7791de --- /dev/null +++ b/.config/awesome/configuration/keys/mod.lua @@ -0,0 +1,4 @@ +return { + mod_key = 'Mod4', + alt_key = 'Mod1' +} diff --git a/.config/awesome/configuration/picom.conf b/.config/awesome/configuration/picom.conf new file mode 100644 index 0000000..9868338 --- /dev/null +++ b/.config/awesome/configuration/picom.conf @@ -0,0 +1,156 @@ +# ░█▀█░▀█▀░█▀▀░█▀█░█▄█░░░░█▀▀░█▀█░█▀█░█▀▀ +# ░█▀▀░░█░░█░░░█░█░█░█░░░░█░░░█░█░█░█░█▀▀ +# ░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░░▀▀▀░▀▀▀░▀░▀░▀░░ +# +# X compositor configuration + +# ░█▀▀░█░█░█▀█░█▀▄░█▀█░█░█ +# ░▀▀█░█▀█░█▀█░█░█░█░█░█▄█ +# ░▀▀▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀ + +shadow = false; +shadow-radius = 12; +shadow-opacity = 0.75; +shadow-offset-x = -12; +shadow-offset-y = -12; + +# shadow-red = 0 +# shadow-green = 0 +# shadow-blue = 0 +shadow-color = "#000000"; + +shadow-exclude = [ + "name = 'Notification'", + "class_g = 'Conky'", + "class_g ?= 'Notify-osd'", + "class_g = 'Cairo-clock'", + "class_g = 'slop'", + "class_g = 'Firefox' && argb", + "class_g = 'Rofi'", + "_GTK_FRAME_EXTENTS@:c", + "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'" +]; + +# shadow-exclude-reg = "x10+0+0"; +# xinerama-shadow-crop = true; + +# ░█▀▀░█▀█░█▀▄░▀█▀░█▀█░█▀▀ +# ░█▀▀░█▀█░█░█░░█░░█░█░█░█ +# ░▀░░░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀ + +fading = true; +fade-in-step = 0.03; +fade-out-step = 0.03; +fade-delta = 3; + +fade-exclude = []; + +no-fading-openclose = false; +no-fading-destroyed-argb = true; + +# ░█▀█░█▀█░█▀█░█▀▀░▀█▀░▀█▀░█░█ +# ░█░█░█▀▀░█▀█░█░░░░█░░░█░░░█░ +# ░▀▀▀░▀░░░▀░▀░▀▀▀░▀▀▀░░▀░░░▀░ + +inactive-opacity = 1; +frame-opacity = 1; +inactive-opacity-override = false; +active-opacity = 1.0; +inactive-dim = 0.0; + +focus-exclude = [ + "class_g = 'Cairo-clock'", + "class_g ?= 'rofi'", + "class_g ?= 'slop'", + "class_g ?= 'Steam'" +]; + +# inactive-dim-fixed = 1.0; + +opacity-rule = [ + "80:class_g = 'URxvt'", + "80:class_g = 'UXTerm'", + "80:class_g = 'XTerm'" +] + +# ░█▀▄░█░░░█░█░█▀▄░█▀▄░▀█▀░█▀█░█▀▀ +# ░█▀▄░█░░░█░█░█▀▄░█▀▄░░█░░█░█░█░█ +# ░▀▀░░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀░▀░▀▀▀ + +blur: { + method = "dual_kawase"; + strength = 4.0; + deviation = 1.0; + kernel = "11x11gaussian"; +} + +blur-background = false; +blur-background-frame = true; +blur-background-fixed = true; +# blur-kern = "3x3box"; + +blur-background-exclude = [ + "class_g = 'slop'", + "class_g = 'Firefox' && argb", + "name = 'rofi - Global Search'", + "_GTK_FRAME_EXTENTS@:c" +]; + +# ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░█░░░░░█▀▀░█▀▀░▀█▀░▀█▀░▀█▀░█▀█░█▀▀░█▀▀ +# ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░█░░░░░▀▀█░█▀▀░░█░░░█░░░█░░█░█░█░█░▀▀█ +# ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░▀▀▀░░░▀▀▀░▀▀▀░░▀░░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀ + +daemon = false; +backend = "glx"; +vsync = true; +dbus = false; +mark-wmwin-focused = true; +mark-ovredir-focused = true; +detect-rounded-corners = true; +detect-client-opacity = true; +refresh-rate = 0; +# use-ewmh-active-win = true; +# unredir-if-possible = false; +# unredir-if-possible-delay = 0; + +unredir-if-possible-exclude = []; + +detect-transient = true; +detect-client-leader = true; +resize-damage = 1; + +invert-color-include = []; + +glx-no-stencil = true; +# glx-no-rebind-pixmap = false; +use-damage = true; +# xrender-sync-fence = true; + +# glx-fshader-win = ""; +# force-win-blend = false; + +# no-ewmh-fullscreen = false; +# max-brightness = 1.0; + +transparent-clipping = false; + +log-level = "warn"; +log-file = "~/.cache/picom-log.log"; +show-all-xerrors = true; +# write-pid-path = '/path/to/your/mom'; + +wintypes: { + tooltip = { fade = true; shadow = false; focus = false; }; + normal = { shadow = false; }; + dock = { shadow = false; }; + dnd = { shadow = false; }; + popup_menu = { shadow = true; focus = false; opacity = 0.90; }; + dropdown_menu = { shadow = false; focus = false; }; + above = { shadow = true; }; + splash = { shadow = false; }; + utility = { focus = false; shadow = false; blur-background = false; }; + notification = { shadow = false; }; + desktop = { shadow = false; blur-background = false; }; + menu = { focus = false; }; + dialog = { shadow = true; }; +}; diff --git a/.config/awesome/configuration/rofi/appmenu/rofi.rasi b/.config/awesome/configuration/rofi/appmenu/rofi.rasi new file mode 100644 index 0000000..c4af2c2 --- /dev/null +++ b/.config/awesome/configuration/rofi/appmenu/rofi.rasi @@ -0,0 +1,152 @@ +configuration { + font: "Inter Regular 10"; + show-icons: true; + drun-display-format: "{name}"; + fullscreen: false; + threads: 0; + matching: "fuzzy"; + scroll-method: 0; + disable-history: false; + fullscreen: true; + window-thumbnail: true; +} + +* { + transparent: #00000000; + foreground: #F2F2F2EE; + background-selected: #F2F2F245; + background-active: #F2F2F230; + background-white: #F2F2F211; + background-black: #00000066; + urgent: #E91E6366; + urgent-selected: #E91E6377; +} + +window { + transparency: "real"; + background-color: @transparent; + text-color: @foreground; + location: northwest; + anchor: northwest; +} + +prompt { + enabled: false; +} + +button { + action: "ok"; + str: " "; + font: "FantasqueSansMono Nerd Font 11"; + expand: false; + text-color: @foreground; + background-color: @transparent; + vertical-align: 0.7; + horizontal-align: 0.5; +} + +entry { + font: "Inter Regular 11"; + background-color: @transparent; + text-color: @foreground; + expand: true; + vertical-align: 0.5; + horizontal-align: 0.5; + placeholder: "Type to search"; + placeholder-color: @foreground; + blink: true; +} + +case-indicator { + background-color: @transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +entry-wrapper { + orientation: horizontal; + vertical-align: 0.5; + spacing: 4px; + background-color: @transparent; + children: [ button, entry, case-indicator ]; +} + +inputbar { + background-color: @background-white; + text-color: @foreground; + expand: false; + border-radius: 6px; + margin: 0px calc((100% - 640px) / 2) 0px calc((100% - 640px) / 2); + padding: 10px 10px 10px 10px; + position: north; + children: [ entry-wrapper ]; +} + +listview { + background-color: @transparent; + columns: 6; + spacing: 5px; + cycle: false; + dynamic: true; + layout: vertical; +} + +mainbox { + background-color: @background-black; + children: [ inputbar, listview ]; + spacing: 25px; + padding: 70px 15% 0 15%; + /*padding: 70px 135px 0 135px;*/ +} + +element { + background-color: @transparent; + text-color: @foreground; + orientation: vertical; + border-radius: 12px; + padding: 25px 0 25px 0; +} + +element-icon { + background-color: @transparent; + size: 72px; + border: 0; +} + +element-text { + background-color: @transparent; + text-color: @foreground; + expand: true; + horizontal-align: 0.5; + vertical-align: 0.5; + margin: 0 10px 0 10px; +} + +element normal.urgent, +element alternate.urgent { + background-color: @urgent; + text-color: @foreground; + border-radius: 9px; +} + +element normal.active, +element alternate.active { + background-color: @background-active; + text-color: @foreground; +} + +element selected { + background-color: @background-selected; + text-color: @foreground; +} + +element selected.urgent { + background-color: @urgent-selected; + text-color: @foreground; +} + +element selected.active { + background-color: @background-active; + color: @foreground-selected; +} diff --git a/.config/awesome/configuration/rofi/global/history.txt b/.config/awesome/configuration/rofi/global/history.txt new file mode 100644 index 0000000..e69de29 diff --git a/.config/awesome/configuration/rofi/global/icons/ddg.svg b/.config/awesome/configuration/rofi/global/icons/ddg.svg new file mode 100644 index 0000000..20ea387 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/icons/ddg.svg @@ -0,0 +1,615 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/configuration/rofi/global/icons/google.svg b/.config/awesome/configuration/rofi/global/icons/google.svg new file mode 100644 index 0000000..21e5bf3 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/icons/google.svg @@ -0,0 +1,365 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/configuration/rofi/global/icons/history.svg b/.config/awesome/configuration/rofi/global/icons/history.svg new file mode 100644 index 0000000..872bac8 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/icons/history.svg @@ -0,0 +1,75 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/configuration/rofi/global/icons/result.svg b/.config/awesome/configuration/rofi/global/icons/result.svg new file mode 100644 index 0000000..0f4d883 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/icons/result.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/configuration/rofi/global/icons/suggestion.svg b/.config/awesome/configuration/rofi/global/icons/suggestion.svg new file mode 100644 index 0000000..bf67346 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/icons/suggestion.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.config/awesome/configuration/rofi/global/rofi-spotlight.sh b/.config/awesome/configuration/rofi/global/rofi-spotlight.sh new file mode 100755 index 0000000..d5c4a23 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/rofi-spotlight.sh @@ -0,0 +1,692 @@ +#!/usr/bin/env bash + +TMP_DIR="/tmp/rofi/${USER}/" + +PREV_LOC_FILE="${TMP_DIR}rofi_fb_prevloc" +CURRENT_FILE="${TMP_DIR}rofi_fb_current_file" + +MY_PATH="$(realpath "$0" | xargs dirname)" +HIST_FILE="${MY_PATH}/history.txt" + +OPENER=xdg-open +TERM_EMU=kitty +TEXT_EDITOR=$EDITOR +FILE_MANAGER=xdg-open +BLUETOOTH_SEND=blueman-sendto + +CUR_DIR=$PWD +NEXT_DIR="" +FD_INSTALLED=$(command -v fd) + +SHOW_HIDDEN=false + +# Setup menu options +declare -a OPEN_FILE_LOCATION=( + "Open file location in ${TERM_EMU}" + "Open file location in ${FILE_MANAGER}" +) +declare -a RUN_COMMANDS=( + "Run" + "Execute in ${TERM_EMU}" +) +declare -a STANDARD_CONTROLS=( + "Move to trash" + "Delete" + "Back" +) +declare -a SHELL_NO_X_OPTIONS=( + "Edit" + "${OPEN_FILE_LOCATION[@]}" + "${STANDARD_CONTROLS[@]}" +) +declare -a SHELL_OPTIONS=( + "${RUN_COMMANDS[@]}" + "${SHELL_NO_X_OPTIONS[@]}" +) +declare -a BIN_NO_X_OPTIONS=( + "${OPEN_FILE_LOCATION[@]}" + "Back" +) +declare -a BIN_OPTIONS=( + "${RUN_COMMANDS[@]}" + "${BIN_NO_X_OPTIONS[@]}" +) +declare -a TEXT_OPTIONS=("${SHELL_NO_X_OPTIONS[@]}") +declare -a HTML_OPTIONS=( + "Open" + "Edit" + "${OPEN_FILE_LOCATION[@]}" + "${STANDARD_CONTROLS[@]}" +) +declare -a XCF_SVG_OPTIONS=( + "Open" + "${OPEN_FILE_LOCATION[@]}" + "${STANDARD_CONTROLS[@]}" +) +declare -a IMAGE_OPTIONS=( + "Open" + "Send via Bluetooth" + "${OPEN_FILE_LOCATION[@]}" + "${STANDARD_CONTROLS[@]}" +) + +declare -a ALL_OPTIONS=() + +# Combine all context menu +COMBINED_OPTIONS=( + "${SHELL_OPTIONS[@]}" + "${IMAGE_OPTIONS[@]}" +) + +# Remove duplicates +ALL_OPTIONS=("$(printf '%s\n' "${COMBINED_OPTIONS[@]}" | sort -u)") + +# Create tmp dir for rofi +[ ! -d "${TMP_DIR}" ] && mkdir -p "${TMP_DIR}"; + +# Create hist file if it doesn't exist +[ ! -f "${HIST_FILE}" ] && touch "${HIST_FILE}" + +# Help message +if [ -n "$*" ] && [[ "$*" = ":help" ]] +then + echo -en "Rofi Spotlight +A Rofi with file and web searching functionality + +Commands: +:help to print this help message +:h or :hidden to show hidden files/dirs +:sh or :show_hist to show search history +:ch or :clear_hist to clear search history +:xdg to jump to an xdg directory +Examples: + :xdg DOCUMENTS + :xdg DOWNLOADS +Also supports incomplete path: +Examples: + :xdg doc + :xdg down +For more info about XDG dirs, see: +\`man xdg-user-dir\` + +File search syntaxes: +! to search for a file and web suggestions +? to search parent directories +Examples: + !half-life 3 + ?portal 3 + +Web search syntaxes: +! to gets search suggestions +:web/:w to also to gets search suggestions +:webbro/:wb to search directly from your browser +Examples: + !how to install archlinux + :web how to install gentoo + :w how to make a nuclear fission + :webbro how to install wine in windowsxp +Back\0icon\x1fdraw-arrow-back\n" + + exit +fi + +# Return the icon string +function icon_file_type(){ + icon_name="" + mime_type=$(file --mime-type -b "${1}") + + case "${mime_type}" in + "inode/directory") + case "${1}" in + "Desktop/" ) + icon_name='folder-blue-desktop' + ;; + "Documents/" ) + icon_name='folder-blue-documents' + ;; + "Downloads/" ) + icon_name='folder-blue-downloads' + ;; + "Music/" ) + icon_name='folder-blue-music' + ;; + "Pictures/" ) + icon_name='folder-blue-pictures' + ;; + "Public/" ) + icon_name='folder-blue-public' + ;; + "Templates/" ) + icon_name='folder-blue-templates' + ;; + "Videos/" ) + icon_name='folder-blue-videos' + ;; + "root/" ) + icon_name='folder-root' + ;; + "home/" | "${USER}/") + icon_name='folder-home' + ;; + *"$" ) + icon_name='folder-blue' + ;; + *) + icon_name='folder-blue' + ;; + esac + ;; + "inode/symlink" ) + icon_name='inode-symlink' + ;; + "audio/flac" | "audio/mpeg" ) + icon_name='music' + ;; + "video/mp4" ) + icon_name='video-mp4' + ;; + "video/x-matroska" ) + icon_name=video-x-matroska + ;; + "image/x-xcf" ) + # notify-send '123' + icon_name='image-x-xcf' + ;; + "image/jpeg" | "image/png" | "image/svg+xml") + icon_name="${CUR_DIR}/${1}" + ;; + "image/gif" ) + icon_name='gif' + ;; + "image/vnd.adobe.photoshop" ) + icon_name='image-vnd.adobe.photoshop' + ;; + "image/webp" ) + icon_name='gif' + ;; + "application/x-pie-executable" ) + icon_name='binary' + ;; + "application/pdf" ) + icon_name='pdf' + ;; + "application/zip" ) + icon_name='application-zip' + ;; + "application/x-xz" ) + icon_name='application-x-xz-compressed-tar' + ;; + "application/x-7z-compressed" ) + icon_name='application-x-7zip' + ;; + "application/x-rar" ) + icon_name='application-x-rar' + ;; + "application/octet-stream" | "application/x-iso9660-image" ) + icon_name='application-x-iso' + ;; + "application/x-dosexec" ) + icon_name='application-x-ms-dos-executable' + ;; + "text/plain" ) + icon_name='application-text' + ;; + "text/x-shellscript" ) + icon_name='application-x-shellscript' + ;; + "text/html" ) + icon_name='text-html' + ;; + "font/sfnt" | "application/vnd.ms-opentype" ) + icon_name='application-x-font-ttf' + ;; + * ) + case "${1}" in + *."docx" | *".doc" ) + icon_name='application-msword' + ;; + *."apk" ) + icon_name='android-package-archive' + ;; + * ) + icon_name='unknown' + ;; + esac + ;; + esac + + echo -en "$1\0icon\x1f$icon_name\n" +} + +export -f icon_file_type + +# Pass the argument to python script +function web_search() { + # Pass the search query to web-search script + "${MY_PATH}/web-search.py" "${1}" + exit; +} + +# Handles the web search method +if [ ! -z "$@" ] && ([[ "$@" == ":webbro"* ]] || [[ "$@" == ":wb"* ]]) +then + remove='' + [[ "$*" = ":webbro"* ]] && remove=":webbro" || remove=":wb" + + # Search directly from your web browser + web_search "$(printf '%s\n' "${1//$remove/}")" + exit; + +elif [ ! -z "$@" ] && ([[ "$@" == ":web"* ]] || [[ "$@" == ":w"* ]]) +then + remove='' + [[ "$*" = ":web"* ]] && remove=":web" || remove=":w" + + # Get search suggestions + web_search "!$(printf '%s\n' "${1//$remove/}")" + exit; +fi + +function find_query() { + QUERY=${1} + if [[ ! "${QUERY}" =~ ( |\') ]] + then + if [ -z "$FD_INSTALLED" ]; + then + find "${HOME}" -iname *"${QUERY}"* | sed "s/\/home\/$USER/\~/" | + awk -v MY_PATH="${MY_PATH}" '{print $0"\0icon\x1f"MY_PATH"/icons/result.svg\n"}' + else + fd -H ${QUERY} ${HOME} | sed "s/\/home\/$USER/\~/" | + awk -v MY_PATH="${MY_PATH}" '{print $0"\0icon\x1f"MY_PATH"/icons/result.svg\n"}' + fi + fi +} + +# File and calls to the web search +if [ ! -z "$@" ] && ([[ "$@" == ?(\~)/* ]] || [[ "$@" == \?* ]] || [[ "$@" == \!* ]]) +then + QUERY=$@ + + echo "${QUERY}" >> "${HIST_FILE}" + + if [[ "$@" == ?(\~)/* ]] + then + [[ "$*" = \~* ]] && QUERY="${QUERY//"~"/"$HOME"}" + + coproc ${OPENER} "${QUERY}" > /dev/null 2>&1 + exec 1>&- + exit + + elif [[ "$@" == \?* ]] + then + find_query ${QUERY#\?} + + else + # Find the file + find_query ${QUERY#!} + + # Web search + web_search "! ${QUERY#!}" + fi + exit; +fi + +# Create notification if there's an error +function create_notification() { + case "${1}" in + "denied" ) + notify-send -a "Global Search" "Permission denied!" \ + 'You have no permission to access '"${CUR_DIR}!" + ;; + "deleted" ) + notify-send -a "Global Search" "Success!" \ + 'File deleted!' + ;; + "trashed" ) + notify-send -a "Global Search" "Success!" \ + 'The file has been moved to trash!' + ;; + "cleared" ) + notify-send -a "Global Search" "Success!" \ + 'Search history has been successfully cleared!' + ;; + * ) + notify-send -a "Global Search" "Somethings wrong I can feel it!" \ + 'This incident will be reported!' + ;; + esac +} + +# Show the files in the current directory +function navigate_to() { + # process current dir. + if [ -n "${CUR_DIR}" ] + then + CUR_DIR=$(readlink -e "${CUR_DIR}") + if [ ! -d "${CUR_DIR}" ] || [ ! -r "${CUR_DIR}" ] + then + create_notification "denied" + CUR_DIR=$(realpath ${CUR_DIR} | xargs dirname) + echo "${CUR_DIR}" > "${PREV_LOC_FILE}" + else + echo "${CUR_DIR}/" > "${PREV_LOC_FILE}" + fi + pushd "${CUR_DIR}" >/dev/null || exit + fi + + printf "..\0icon\x1fup\n" + + if [[ -z "$FD_INSTALLED" ]] + then + #Group directories + if [[ ${SHOW_HIDDEN} == true ]] + then + for i in .*/ + do + [[ -d "${i}" ]] && ([[ "${i}" != "./" ]] && [[ "${i}" != "../"* ]]) && icon_file_type "${i}" + done + fi + for i in */ + do + [[ -d "${i}" ]] && icon_file_type "${i}" + done + #Group files + if [[ ${SHOW_HIDDEN} = true ]] + then + for i in .* + do + [[ -f "${i}" ]] && icon_file_type "${i}" + done + fi + for i in * + do + [[ -f "${i}" ]] && icon_file_type "${i}" + done + else + THREADS=$(getconf _NPROCESSORS_ONLN) + export CUR_DIR + if [[ ${SHOW_HIDDEN} == true ]] + then + fd -Ht d -d 1 -x bash -c 'icon_file_type "$1/"' _ {} \ | sort -V --parallel=$THREADS + fd -Ht f -d 1 -x bash -c 'icon_file_type "$1"' _ {} \ | sort -V --parallel=$THREADS + else + fd -t d -d 1 -x bash -c 'icon_file_type "$1/"' _ {} \ | sort -V --parallel=$THREADS + fd -t f -d 1 -x bash -c 'icon_file_type "$1"' _ {} \ | sort -V --parallel=$THREADS + fi + fi +} + +# Set XDG dir +function return_xdg_dir() { + target_dir=${1^^} + + if [[ "HOME" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir) + + elif [[ "DESKTOP" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir DESKTOP) + + elif [[ "DOCUMENTS" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir DOCUMENTS) + + elif [[ "DOWNLOADS" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir DOWNLOAD) + + elif [[ "MUSIC" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir MUSIC) + + elif [[ "PICTURES" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir PICTURES) + + elif [[ "PUBLICSHARE" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir PUBLICSHARE) + + elif [[ "TEMPLATES" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir TEMPLATES) + + elif [[ "VIDEOS" == *"${target_dir}"* ]] + then + CUR_DIR=$(xdg-user-dir VIDEOS) + + elif [[ "ROOT" == *"${target_dir}"* ]] + then + CUR_DIR="/" + + else + CUR_DIR="${HOME}" + fi + navigate_to + exit; +} + +# Show and Clear History +if [ ! -z "$@" ] && ([[ "$@" == ":sh" ]] || [[ "$@" == ":show_hist" ]]) +then + hist=$(tac "${HIST_FILE}") + + echo -en "Back\0icon\x1fdraw-arrow-back\n" + [ -z "${hist}" ] && echo -en "No History Yet\0icon\x1ftext-plain\n" + + while IFS= read -r line; + do + echo -en "${line}\0icon\x1f${MY_PATH}/icons/history.svg\n"; + done <<< "${hist}" + + exit; +elif [ ! -z "$@" ] && ([[ "$@" == ":ch" ]] || [[ "$@" == ":clear_hist" ]]) +then + :> "${HIST_FILE}" + create_notification "cleared" + + CUR_DIR="${HOME}" + navigate_to + exit; +fi + +# Accepts XDG command +if [[ ! -z "$@" ]] && [[ "$@" == ":xdg"* ]] +then + NEXT_DIR=${*//":xdg "/} + + [[ -n "$NEXT_DIR" ]] && return_xdg_dir "${NEXT_DIR}" || return_xdg_dir "${HOME}" +fi + +# Read last location, otherwise we default to PWD. +[ -f "${PREV_LOC_FILE}" ] && CUR_DIR=$(< "${PREV_LOC_FILE}") + +if [[ ! -z "$@" ]] && ([[ "$@" == ":h" ]] || [[ "$@" == ":hidden" ]]) +then + SHOW_HIDDEN=true + navigate_to + exit; +fi + +# Handle argument. +[ -n "$*" ] && CUR_DIR="${CUR_DIR}/$*" + +# Context Menu +if [ -n "$*" ] && [[ "${ALL_OPTIONS[*]} " = *"$*"* ]] +then + case "${1}" in + "Run" ) + coproc ( eval "$(< ${CURRENT_FILE})" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Execute in ${TERM_EMU}" ) + coproc ( eval "${TERM_EMU} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Open" ) + coproc ( eval "${OPENER} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Open file location in ${TERM_EMU}" ) + file_path="$(< ${CURRENT_FILE})" + coproc ( ${TERM_EMU} bash -c "cd ${file_path%/*} ; ${SHELL}" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Open file location in ${FILE_MANAGER}" ) + file_path="$(< "${CURRENT_FILE}")" + coproc ( eval "${FILE_MANAGER} "${file_path%/*}"" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Edit" ) + coproc ( eval "${TERM_EMU} ${TEXT_EDITOR} \"$(< ${CURRENT_FILE})\"" & > /dev/null 2>&1 ) + kill -9 $(pgrep rofi) + ;; + "Move to trash" ) + coproc( gio trash "$(< ${CURRENT_FILE})" & > /dev/null 2>&1 ) + create_notification "trashed" + CUR_DIR="$(dirname "$(< ${CURRENT_FILE})")" + navigate_to + ;; + "Delete" ) + shred "$(< ${CURRENT_FILE})" + rm "$(< ${CURRENT_FILE})" + create_notification "deleted" + CUR_DIR="$(dirname "$(< ${CURRENT_FILE})")" + navigate_to + ;; + "Send via Bluetooth" ) + rfkill unblock bluetooth && bluetoothctl power on + sleep 1 + blueman-sendto "$(< ${CURRENT_FILE})" & > /dev/null 2>&1 + kill -9 $(pgrep rofi) + ;; + "Back" ) + CUR_DIR="$(< ${PREV_LOC_FILE})" + navigate_to + ;; + esac + exit; +fi + +function context_menu_icons() { + + if [[ "${1}" == "Run" ]] + then + echo '\0icon\x1fsystem-run\n' + + elif [[ "${1}" == "Execute in ${TERM_EMU}" ]] + then + echo "\0icon\x1f${TERM_EMU}\n" + + elif [[ "${1}" == "Open" ]] + then + echo "\0icon\x1futilities-x-terminal\n" + + elif [[ "${1}" == "Open file location in ${TERM_EMU}" ]] + then + echo "\0icon\x1f${TERM_EMU}\n" + + elif [[ "${1}" == "Open file location in ${FILE_MANAGER}" ]] + then + echo "\0icon\x1fblue-folder-open\n" + + elif [[ "${1}" == "Edit" ]] + then + echo "\0icon\x1faccessories-text-editor\n" + + elif [[ "${1}" == "Move to trash" ]] + then + echo "\0icon\x1fapplication-x-trash\n" + + elif [[ "${1}" == "Delete" ]] + then + echo "\0icon\x1findicator-trashindicator\n" + + elif [[ "${1}" == "Send via Bluetooth" ]] + then + echo "\0icon\x1fbluetooth\n" + + elif [[ "${1}" == "Back" ]] + then + echo "\0icon\x1fback\n" + fi +} + +function print_context_menu() { + declare -a arg_arr=("${!1}") + + for menu in "${arg_arr[@]}" + do + printf "$menu$(context_menu_icons "${menu}")\n" + done +} + +function context_menu() { + + type="$(file --mime-type -b "${CUR_DIR}")" + + if [ -w "${CUR_DIR}" ] && [[ "${type}" == "text/x-shellscript" ]] + then + if [ -x "${CUR_DIR}" ]; + then + print_context_menu SHELL_OPTIONS[@] + else + print_context_menu SHELL_NO_X_OPTIONS[@] + fi + + elif [[ "${type}" == "application/x-executable" ]] || [[ "${type}" == "application/x-pie-executable" ]] + then + if [ -x "${CUR_DIR}" ] + then + print_context_menu BIN_OPTIONS[@] + else + print_context_menu BIN_NO_X_OPTIONS[@] + fi + + elif [[ "${type}" == "text/plain" ]] + then + print_context_menu TEXT_OPTIONS[@] + + elif [[ "${type}" == "text/html" ]] + then + print_context_menu HTML_OPTIONS[@] + + elif [[ "${type}" == "image/jpeg" ]] || [[ "${type}" == "image/png" ]] + then + print_context_menu IMAGE_OPTIONS[@] + + elif [[ "${type}" == "image/x-xcf" ]] || [[ "${type}" == "image/svg+xml" ]] + then + print_context_menu XCF_SVG_OPTIONS[@] + + elif [ ! -w "${CUR_DIR}" ] && [[ "${type}" == "text/x-shellscript" ]] + then + coproc ( exec "${CUR_DIR}" & > /dev/null 2>&1 ) + + else + if [ ! -d "${CUR_DIR}" ] && [ ! -f "${CUR_DIR}" ] + then + QUERY="${CUR_DIR//*\/\//}" + + echo "${QUERY}" >> "${HIST_FILE}" + + find_query "${QUERY#!}" + + web_search "!${QUERY}" + else + coproc ( ${OPENER} "${CUR_DIR}" & > /dev/null 2>&1 ) + fi + fi + exit; +} + +# If argument is not a directory/folder +if [ ! -d "${CUR_DIR}" ] +then + echo "${CUR_DIR}" > "${CURRENT_FILE}" + context_menu + exit; +fi + +navigate_to diff --git a/.config/awesome/configuration/rofi/global/rofi.rasi b/.config/awesome/configuration/rofi/global/rofi.rasi new file mode 100644 index 0000000..d14ecd2 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/rofi.rasi @@ -0,0 +1,157 @@ +configuration { + font: "Inter Regular 10"; + sidebar-mode: true; + show-icons: true; + fullscreen: false; + threads: 0; + matching: "fuzzy"; + scroll-method: 0; + monitor: "primary"; +} + +* { + transparent: #00000000; + foreground: #F2F2F2EE; + background-selected: #F2F2F245; + background-active: #F2F2F230; + background-white: #F2F2F211; + background-black: #00000000; + urgent: #E91E6366; + urgent-selected: #E91E6377; +} + +window { + transparency: "real"; + background-color: @transparent; + text-color: @foreground; + location: west; + anchor: west; + x-offset: 0; + height: 100%; + width: 350px; + orientation: vertical; +} + +prompt { + enabled: false; +} + +button { + action: "ok"; + str: " "; + font: "FantasqueSansMono Nerd Font 16"; + expand: false; + text-color: @foreground; + background-color: @transparent; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +entry { + font: "Inter Regular 12"; + background-color: @transparent; + text-color: @foreground; + expand: true; + vertical-align: 0.5; + horizontal-align: 0; + placeholder: "Global Search"; + placeholder-color: @foreground; + blink: true; +} + +entry-wrapper { + orientation: horizontal; + margin: 0 12px 0 12px; + spacing: 24px; + vertical-align: 0.5; + background-color: @transparent; + children: [ button, entry ]; +} + +inputbar { + padding: 14px; + margin: 10px 10px 14px 10px; + background-color: @background-white; + text-color: @foreground; + expand: false; + border-radius: 9px; + position: north; + children: [ entry-wrapper ]; +} + +listview { + background-color: @transparent; + spacing: 0; + cycle: true; + dynamic: true; + scrollbar: true; +} + +mainbox { + width: 200px; + expand: true; + spacing: 12px; + padding: 5px; + background-color: @background-black; + children: [ inputbar, listview ]; +} + +scrollbar { + background-color: @background-white; + handle-width: 0; + margin: 0 0 5px 0; + border-radius: 9px; +} + +element { + background-color: @transparent; + text-color: @foreground; + orientation: horizontal; + border: 0; + border-color: @background-white; + border-radius: 6px; + spacing: 24px; + margin: 0px 12px 0px 12px; + padding: 10px 24px 10px 24px; +} + +element-icon { + size: 24px; + border: 0; + border-color: @transparent; +} + +element-text { + font: "Inter Regular 11"; + expand: true; + horizontal-align: 0; + vertical-align: 0.5; +} + +element normal.urgent, +element alternate.urgent { + background-color: @urgent; + text-color: @foreground; + border-radius: 9px; +} + +element normal.active, +element alternate.active { + background-color: @background-active; + text-color: @foreground; +} + +element selected { + background-color: @background-selected; + text-color: @foreground; +} + +element selected.urgent { + background-color: @urgent-selected; + text-color: @foreground; +} + +element selected.active { + background-color: @background-active; + color: @foreground-selected; +} diff --git a/.config/awesome/configuration/rofi/global/web-search.py b/.config/awesome/configuration/rofi/global/web-search.py new file mode 100755 index 0000000..ba314d5 --- /dev/null +++ b/.config/awesome/configuration/rofi/global/web-search.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 + +# MIT License + +# Copyright (c) 2019 Paolo Donadeo + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + +import json +import re +import urllib.parse +import urllib.request +import sys +import os +import datetime +import gzip + +import subprocess as sp + +import html + + +################################################################################ +##### C O N F I G U R A T I O N ###### +################################################################################ +SEARCH_ENGINE = 'google' # or 'duckduckgo' +BROWSER = 'firefox' # or 'firefox', 'chromium', 'brave', 'lynx' +TERMINAL = ['kitty', '--'] # or ['st', '-e'] or something like that +################################################################################ + +CONFIG = { + 'BROWSER_PATH' : { + 'chrome' : ['google-chrome-stable'], + 'firefox' : ['firefox'], + 'chromium' : ['chromium-browser'], + 'brave' : ['brave-browser'], + 'lynx' : TERMINAL + ['lynx'] + }, + 'USER_AGENT' : { + 'chrome' : 'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + 'firefox' : 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0', + 'chromium' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/76.0.3809.100 Chrome/76.0.3809.100 Safari/537.36', + 'brave' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36', + 'lynx' : 'Lynx/2.8.9rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.1.1d' + }, + 'SEARCH_ENGINE_NAME' : { + 'google' : 'Google', + 'duckduckgo' : 'DuckDuckGo' + }, + 'SEARCH_URL' : { + 'google' : 'https://www.google.com/search?q=', + 'duckduckgo' : 'https://duckduckgo.com/?q=' + }, + 'SUGGESTION_URL' : { + 'google' : 'https://www.google.com/complete/search?', + 'duckduckgo' : 'https://duckduckgo.com/ac/?' + } +} + +def cleanhtml(txt): + return re.sub(r'<.*?>', '', txt) + +def fetch_suggestions(search_string): + if SEARCH_ENGINE == 'google': + r = { + 'q' : search_string, + 'cp' : '11', + 'client' : 'psy-ab', + 'xssi' : 't', + 'gs_ri' : 'gws-wiz', + 'hl' : 'en-IT', + 'authuser' : '0' + } + url = CONFIG['SUGGESTION_URL'][SEARCH_ENGINE] + urllib.parse.urlencode(r) + headers = { + 'sec-fetch-mode' : 'cors', + 'dnt' : '1', + 'accept-encoding' : 'gzip', + 'accept-language' : 'en-US;q=0.9,en;q=0.8', + 'pragma' : 'no-cache', + 'user-agent' : CONFIG['USER_AGENT'][BROWSER], + 'accept' : '*/*', + 'cache-control' : 'no-cache', + 'authority' : 'www.google.com', + 'referer' : 'https://www.google.com/', + 'sec-fetch-site' : 'same-origin' + } + req = urllib.request.Request(url, headers=headers, method='GET') + + reply_data = gzip.decompress(urllib.request.urlopen(req).read()).split(b'\n')[1] + reply_data = json.loads(reply_data) + return [ cleanhtml(res[0]).strip() for res in reply_data[0] ] + else: # 'duckduckgo' + if search_string.startswith('!'): + bang_search = True + search_string = search_string.lstrip('!') + else: + bang_search = False + r = { + 'q' : search_string, + 'callback' : 'autocompleteCallback', + 'kl' : 'wt-wt', + '_' : str(int((datetime.datetime.now().timestamp())*1000)) + } + url = CONFIG['SUGGESTION_URL'][SEARCH_ENGINE] + urllib.parse.urlencode(r) + if bang_search: + url = url.replace('?q=', '?q=!') + headers = { + 'pragma' : 'no-cache', + 'dnt' : '1', + 'accept-encoding' : 'gzip', + 'accept-language' : 'en-US;q=0.9,en;q=0.8', + 'user-agent' : CONFIG['USER_AGENT'][BROWSER], + 'sec-fetch-mode' : 'no-cors', + 'accept' : '*/*', + 'cache-control' : 'no-cache', + 'authority' : 'duckduckgo.com', + 'referer' : 'https://duckduckgo.com/', + 'sec-fetch-site' : 'same-origin', + } + req = urllib.request.Request(url, headers=headers, method='GET') + reply_data = gzip.decompress(urllib.request.urlopen(req).read()).decode('utf8') + reply_data = json.loads(re.match(r'autocompleteCallback\((.*)\);', reply_data).group(1)) + return [ cleanhtml(res['phrase']).strip() for res in reply_data ] + +def main(): + search_string = html.unescape((' '.join(sys.argv[1:])).strip()) + + path_str = os.path.dirname(os.path.realpath(__file__)) + '/' + icon_path_str = path_str + 'icons/' + icon_name = icon_path_str + + if SEARCH_ENGINE == 'google': + icon_name += 'google.svg' + else: + icon_name += 'ddg.svg' + + if search_string.startswith('!'): + search_string = search_string.rstrip('!').strip() + results = fetch_suggestions(search_string) + for r in results: + print(":wb " + html.unescape(r) + "\0icon\x1f"+icon_name+"\n") + else: + url = CONFIG['SEARCH_URL'][SEARCH_ENGINE] + urllib.parse.quote_plus(search_string) + sp.Popen(CONFIG['BROWSER_PATH'][BROWSER] + [url], stdout=sp.DEVNULL, stderr=sp.DEVNULL, shell=False) + +if __name__ == "__main__": + try: + main() + except Exception as e: + if e: + sys.exit(1) diff --git a/.config/awesome/configuration/root/init.lua b/.config/awesome/configuration/root/init.lua new file mode 100644 index 0000000..55e43b3 --- /dev/null +++ b/.config/awesome/configuration/root/init.lua @@ -0,0 +1,84 @@ +local gears = require('gears') +local awful = require('awful') + +local apps = require('configuration.apps') + +root.buttons( + gears.table.join( + awful.button( + {}, + 1, + function() + if mymainmenu then + mymainmenu:hide() + end + end + ), + awful.button( + {}, + 3, + function () + if mymainmenu then + mymainmenu:toggle() + end + end + ), + awful.button( + {}, + 2, + function () + awful.util.spawn(apps.default.rofi_appmenu) + end + ), + awful.button( + {'Control'}, + 2, + function () + awesome.emit_signal('module::exit_screen:show') + end + ), + awful.button( + {'Shift'}, + 2, + function () + awesome.emit_signal('widget::blue_light:toggle') + end + ), + awful.button( + {}, + 4, + function() + awful.spawn('light -A 10',false) + awesome.emit_signal('widget::brightness') + awesome.emit_signal('module::brightness_osd:show',true) + end + ), + awful.button( + {}, + 5, + function() + awful.spawn('light -U 10',false) + awesome.emit_signal('widget::brightness') + awesome.emit_signal('module::brightness_osd:show',true) + end + ), + awful.button( + {'Control'}, + 4, + function() + awful.spawn('amixer -D pulse sset Master 5%+',false) + awesome.emit_signal('widget::volume') + awesome.emit_signal('module::volume_osd:show',true) + end + ), + awful.button( + {'Control'}, + 5, + function() + awful.spawn('amixer -D pulse sset Master 5%-',false) + awesome.emit_signal('widget::volume') + awesome.emit_signal('module::volume_osd:show',true) + end + ) + ) +) \ No newline at end of file diff --git a/.config/awesome/configuration/tags/init.lua b/.config/awesome/configuration/tags/init.lua new file mode 100644 index 0000000..a637fd4 --- /dev/null +++ b/.config/awesome/configuration/tags/init.lua @@ -0,0 +1,168 @@ +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local icons = require('theme.icons') +local apps = require('configuration.apps') + +local tags = { + { + type = 'terminal', + icon = icons.terminal, + default_app = apps.default.terminal, + gap = beautiful.useless_gap + }, + { + type = 'internet', + icon = icons.web_browser, + default_app = apps.default.web_browser, + gap = beautiful.useless_gap + }, + { + type = 'code', + icon = icons.text_editor, + default_app = apps.default.text_editor, + gap = beautiful.useless_gap + }, + { + type = 'files', + icon = icons.file_manager, + default_app = apps.default.file_manager, + gap = beautiful.useless_gap, + layout = awful.layout.suit.tile + }, + { + type = 'multimedia', + icon = icons.multimedia, + default_app = apps.default.multimedia, + gap = beautiful.useless_gap, + layout = awful.layout.suit.floating, + gap = 0 + }, + { + type = 'games', + icon = icons.games, + default_app = apps.default.game, + gap = beautiful.useless_gap, + layout = awful.layout.suit.floating + }, + { + type = 'graphics', + icon = icons.graphics, + default_app = apps.default.graphics, + gap = beautiful.useless_gap + }, + { + type = 'sandbox', + icon = icons.sandbox, + default_app = apps.default.sandbox, + layout = awful.layout.suit.max, + gap = 0 + }, + { + type = 'any', + icon = icons.development, + default_app = apps.default.development, + gap = beautiful.useless_gap, + layout = awful.layout.suit.floating + } + -- { + -- type = 'social', + -- icon = icons.social, + -- default_app = 'discord', + -- gap = beautiful.useless_gap + -- } +} + +-- Set tags layout +tag.connect_signal( + 'request::default_layouts', + function() + awful.layout.append_default_layouts({ + awful.layout.suit.spiral.dwindle, + awful.layout.suit.tile, + awful.layout.suit.floating, + awful.layout.suit.max + }) + end +) + +-- Create tags for each screen +screen.connect_signal( + 'request::desktop_decoration', + function(s) + for i, tag in pairs(tags) do + awful.tag.add( + i, + { + icon = tag.icon, + icon_only = true, + layout = tag.layout or awful.layout.suit.spiral.dwindle, + gap_single_client = true, + gap = tag.gap, + screen = s, + default_app = tag.default_app, + selected = i == 1 + } + ) + end + end +) + +local update_gap_and_shape = function(t) + -- Get current tag layout + local current_layout = awful.tag.getproperty(t, 'layout') + -- If the current layout is awful.layout.suit.max + if (current_layout == awful.layout.suit.max) then + -- Set clients gap to 0 and shape to rectangle if maximized + t.gap = 0 + for _, c in ipairs(t:clients()) do + if not c.floating or not c.round_corners or c.maximized or c.fullscreen then + c.shape = beautiful.client_shape_rectangle + else + c.shape = beautiful.client_shape_rounded + end + end + else + t.gap = beautiful.useless_gap + for _, c in ipairs(t:clients()) do + if not c.round_corners or c.maximized or c.fullscreen then + c.shape = beautiful.client_shape_rectangle + else + c.shape = beautiful.client_shape_rounded + end + end + end +end + +-- Change tag's client's shape and gap on change +tag.connect_signal( + 'property::layout', + function(t) + update_gap_and_shape(t) + end +) + +-- Change tag's client's shape and gap on move to tag +tag.connect_signal( + 'tagged', + function(t) + update_gap_and_shape(t) + end +) + +-- Focus on urgent clients +awful.tag.attached_connect_signal( + s, + 'property::selected', + function() + local urgent_clients = function (c) + return awful.rules.match(c, {urgent = true}) + end + for c in awful.client.iterate(urgent_clients) do + if c.first_tag == mouse.screen.selected_tag then + c:emit_signal('request::activate') + c:raise() + end + end + end +) diff --git a/.config/awesome/configuration/user-profile/default.svg b/.config/awesome/configuration/user-profile/default.svg new file mode 100644 index 0000000..14f8006 --- /dev/null +++ b/.config/awesome/configuration/user-profile/default.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/layout/init.lua b/.config/awesome/layout/init.lua new file mode 100644 index 0000000..362807c --- /dev/null +++ b/.config/awesome/layout/init.lua @@ -0,0 +1,70 @@ +local awful = require('awful') +local left_panel = require('layout.left-panel') +local top_panel = require('layout.top-panel') +local right_panel = require('layout.right-panel') + +-- Create a wibox panel for each screen and add it +screen.connect_signal( + 'request::desktop_decoration', + function(s) + if s.index == 1 then + s.left_panel = left_panel(s) + s.top_panel = top_panel(s, true) + else + s.top_panel = top_panel(s, false) + end + s.right_panel = right_panel(s) + s.right_panel_show_again = false + end +) + + +-- Hide bars when app go fullscreen +function update_bars_visibility() + for s in screen do + if s.selected_tag then + local fullscreen = s.selected_tag.fullscreen_mode + -- Order matter here for shadow + s.top_panel.visible = not fullscreen + if s.left_panel then + s.left_panel.visible = not fullscreen + end + if s.right_panel then + if fullscreen and s.right_panel.visible then + s.right_panel:toggle() + s.right_panel_show_again = true + elseif not fullscreen and not s.right_panel.visible and s.right_panel_show_again then + s.right_panel:toggle() + s.right_panel_show_again = false + end + end + end + end +end + +tag.connect_signal( + 'property::selected', + function(t) + update_bars_visibility() + end +) + +client.connect_signal( + 'property::fullscreen', + function(c) + if c.first_tag then + c.first_tag.fullscreen_mode = c.fullscreen + end + update_bars_visibility() + end +) + +client.connect_signal( + 'unmanage', + function(c) + if c.fullscreen then + c.screen.selected_tag.fullscreen_mode = false + update_bars_visibility() + end + end +) diff --git a/.config/awesome/layout/left-panel/action-bar.lua b/.config/awesome/layout/left-panel/action-bar.lua new file mode 100755 index 0000000..7fd366c --- /dev/null +++ b/.config/awesome/layout/left-panel/action-bar.lua @@ -0,0 +1,72 @@ +local awful = require('awful') +local beautiful = require('beautiful') +local wibox = require('wibox') +local gears = require('gears') +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') +local tag_list = require('widget.tag-list') +local clickable_container = require('widget.clickable-container') + +return function(s, panel, action_bar_width) + + local menu_icon = wibox.widget { + { + id = 'menu_btn', + image = icons.menu, + resize = true, + widget = wibox.widget.imagebox + }, + margins = dpi(10), + widget = wibox.container.margin + } + + local open_dashboard_button = wibox.widget { + { + menu_icon, + widget = clickable_container + }, + bg = beautiful.background .. '66', + widget = wibox.container.background + } + + open_dashboard_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + panel:toggle() + end + ) + ) + ) + + panel:connect_signal( + 'opened', + function() + menu_icon.menu_btn:set_image(gears.surface(icons.close_small)) + end + ) + + panel:connect_signal( + 'closed', + function() + menu_icon.menu_btn:set_image(gears.surface(icons.menu)) + end + ) + + return wibox.widget { + id = 'action_bar', + layout = wibox.layout.align.vertical, + forced_width = action_bar_width, + { + require('widget.search-apps')(), + tag_list(s), + require("widget.xdg-folders")(), + layout = wibox.layout.fixed.vertical, + }, + nil, + open_dashboard_button + } +end diff --git a/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua b/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua new file mode 100644 index 0000000..819d6e4 --- /dev/null +++ b/.config/awesome/layout/left-panel/dashboard/hardware-monitor.lua @@ -0,0 +1,47 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi + +local hardware_header = wibox.widget { + text = 'Hardware Monitor', + font = 'Inter Regular 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + +} + +return wibox.widget { + layout = wibox.layout.fixed.vertical, + { + { + hardware_header, + left = dpi(24), + right = dpi(24), + widget = wibox.container.margin + }, + bg = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.groups_radius) + end, + forced_height = dpi(35), + widget = wibox.container.background + + }, + { + { + layout = wibox.layout.fixed.vertical, + require('widget.cpu-meter'), + require('widget.ram-meter'), + require('widget.temperature-meter'), + require('widget.harddrive-meter') + }, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background + } + +} diff --git a/.config/awesome/layout/left-panel/dashboard/init.lua b/.config/awesome/layout/left-panel/dashboard/init.lua new file mode 100644 index 0000000..2acaa7c --- /dev/null +++ b/.config/awesome/layout/left-panel/dashboard/init.lua @@ -0,0 +1,80 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +return function(_, panel) + + local search_widget = wibox.widget { + { + { + { + image = icons.search, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + { + text = 'Global Search', + font = 'Inter Regular 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin + } + + search_button = wibox.widget { + { + search_widget, + widget = clickable_container + }, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background + } + + search_button:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + function() + panel:run_rofi() + end + ) + ) + ) + + return wibox.widget { + { + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(7), + search_button, + require('layout.left-panel.dashboard.hardware-monitor'), + require('layout.left-panel.dashboard.quick-settings'), + + }, + nil, + require('widget.end-session')(), + layout = wibox.layout.align.vertical + }, + margins = dpi(16), + widget = wibox.container.margin + } +end diff --git a/.config/awesome/layout/left-panel/dashboard/quick-settings.lua b/.config/awesome/layout/left-panel/dashboard/quick-settings.lua new file mode 100644 index 0000000..f5a1c2d --- /dev/null +++ b/.config/awesome/layout/left-panel/dashboard/quick-settings.lua @@ -0,0 +1,67 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local bar_color = beautiful.groups_bg +local dpi = beautiful.xresources.apply_dpi + +local quick_header = wibox.widget { + text = 'Quick Settings', + font = 'Inter Regular 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + +} + +return wibox.widget { + layout = wibox.layout.fixed.vertical, + spacing = dpi(7), + { + layout = wibox.layout.fixed.vertical, + { + { + quick_header, + left = dpi(24), + right = dpi(24), + widget = wibox.container.margin + }, + forced_height = dpi(35), + bg = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, beautiful.groups_radius) + end, + widget = wibox.container.background + }, + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(7), + { + { + layout = wibox.layout.fixed.vertical, + require('widget.brightness-slider'), + require('widget.volume-slider'), + require('widget.airplane-mode'), + require('widget.bluetooth-toggle'), + require('widget.blue-light') + }, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, false, false, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background + }, + { + { + layout = wibox.layout.fixed.vertical, + require('widget.blur-slider'), + require('widget.blur-toggle') + }, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background + } + } + } +} diff --git a/.config/awesome/layout/left-panel/init.lua b/.config/awesome/layout/left-panel/init.lua new file mode 100644 index 0000000..12171e5 --- /dev/null +++ b/.config/awesome/layout/left-panel/init.lua @@ -0,0 +1,154 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local apps = require('configuration.apps') + +local left_panel = function(screen) + + local action_bar_width = dpi(45) + local panel_content_width = dpi(350) + + local panel = wibox { + screen = screen, + width = action_bar_width, + type = 'dock', + height = screen.geometry.height, + x = screen.geometry.x, + y = screen.geometry.y, + ontop = true, + shape = gears.shape.rectangle, + bg = beautiful.background, + fg = beautiful.fg_normal + } + + panel.opened = false + + panel:struts { + left = action_bar_width + } + + local backdrop = wibox { + ontop = true, + screen = screen, + bg = beautiful.transparent, + type = 'utility', + x = screen.geometry.x, + y = screen.geometry.y, + width = screen.geometry.width, + height = screen.geometry.height + } + + function panel:run_rofi() + awesome.spawn( + apps.default.rofi_global, + false, + false, + false, + false, + function() + panel:toggle() + end + ) + + -- Hide panel content if rofi global search is opened + panel:get_children_by_id('panel_content')[1].visible = false + end + + -- "Punch a hole" on backdrop to show the left dashboard + local update_backdrop = function(wibox_backdrop, wibox_panel) + local cairo = require('lgi').cairo + local geo = wibox_panel.screen.geometry + + wibox_backdrop.x = geo.x + wibox_backdrop.y = geo.y + wibox_backdrop.width = geo.width + wibox_backdrop.height = geo.height + + -- Create an image surface that is as large as the wibox_panel screen + local shape = cairo.ImageSurface.create(cairo.Format.A1, geo.width, geo.height) + local cr = cairo.Context(shape) + + -- Fill with "completely opaque" + cr.operator = 'SOURCE' + cr:set_source_rgba(1, 1, 1, 1) + cr:paint() + + -- Remove the shape of the client + local c_geo = wibox_panel:geometry() + local c_shape = gears.surface(wibox_panel.shape_bounding) + cr:set_source_rgba(0, 0, 0, 0) + cr:mask_surface(c_shape, c_geo.x + wibox_panel.border_width - geo.x, c_geo.y + wibox_panel.border_width - geo.y) + c_shape:finish() + + wibox_backdrop.shape_bounding = shape._native + shape:finish() + wibox_backdrop:draw() + end + + local open_panel = function(should_run_rofi) + panel.width = action_bar_width + panel_content_width + backdrop.visible = true + update_backdrop(backdrop, panel) + panel:get_children_by_id('panel_content')[1].visible = true + if should_run_rofi then + panel:run_rofi() + end + panel:emit_signal('opened') + end + + local close_panel = function() + panel.width = action_bar_width + panel:get_children_by_id('panel_content')[1].visible = false + backdrop.visible = false + update_backdrop(backdrop, panel) + panel:emit_signal('closed') + end + + -- Hide this panel when app dashboard is called. + function panel:hide_dashboard() + close_panel() + end + + function panel:toggle(should_run_rofi) + self.opened = not self.opened + if self.opened then + open_panel(should_run_rofi) + else + close_panel() + end + end + + backdrop:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + function() + panel:toggle() + end + ) + ) + ) + + panel:setup { + layout = wibox.layout.align.horizontal, + nil, + { + id = 'panel_content', + bg = beautiful.transparent, + widget = wibox.container.background, + visible = false, + forced_width = panel_content_width, + { + require('layout.left-panel.dashboard')(screen, panel), + layout = wibox.layout.stack + } + }, + require('layout.left-panel.action-bar')(screen, panel, action_bar_width) + } + return panel +end + +return left_panel diff --git a/.config/awesome/layout/right-panel/init.lua b/.config/awesome/layout/right-panel/init.lua new file mode 100644 index 0000000..92c6f7b --- /dev/null +++ b/.config/awesome/layout/right-panel/init.lua @@ -0,0 +1,166 @@ +local awful = require('awful') +local wibox = require('wibox') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +panel_visible = false + +local right_panel = function(s) + + -- Set right panel geometry + local panel_width = dpi(350) + local panel_x = s.geometry.x + s.geometry.width - panel_width + + local panel = wibox { + ontop = true, + screen = s, + visible = false, + type = 'dock', + width = panel_width, + height = s.geometry.height, + x = panel_x, + y = s.geometry.y, + bg = beautiful.background, + fg = beautiful.fg_normal + } + + panel.opened = false + + s.backdrop_rdb = wibox { + ontop = true, + screen = s, + bg = beautiful.transparent, + type = 'utility', + x = s.geometry.x, + y = s.geometry.y, + width = s.geometry.width, + height = s.geometry.height + } + + panel:struts { + right = 0 + } + + open_panel = function() + local focused = awful.screen.focused() + panel_visible = true + + focused.backdrop_rdb.visible = true + focused.right_panel.visible = true + + panel:emit_signal('opened') + end + + close_panel = function() + local focused = awful.screen.focused() + panel_visible = false + + focused.right_panel.visible = false + focused.backdrop_rdb.visible = false + + panel:emit_signal('closed') + end + + -- Hide this panel when app dashboard is called. + function panel:hide_dashboard() + close_panel() + end + + function panel:toggle() + self.opened = not self.opened + if self.opened then + open_panel() + else + close_panel() + end + end + + + function panel:switch_pane(mode) + if mode == 'notif_mode' then + -- Update Content + panel:get_children_by_id('notif_id')[1].visible = true + panel:get_children_by_id('pane_id')[1].visible = false + elseif mode == 'today_mode' then + -- Update Content + panel:get_children_by_id('notif_id')[1].visible = false + panel:get_children_by_id('pane_id')[1].visible = true + end + end + + s.backdrop_rdb:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + function() + panel:toggle() + end + ) + ) + ) + + local separator = wibox.widget { + orientation = 'horizontal', + opacity = 0.0, + forced_height = 15, + widget = wibox.widget.separator, + } + + local line_separator = wibox.widget { + orientation = 'horizontal', + forced_height = dpi(1), + span_ratio = 1.0, + color = beautiful.groups_title_bg, + widget = wibox.widget.separator + } + + panel : setup { + { + expand = 'none', + layout = wibox.layout.fixed.vertical, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + require('widget.info-center-switch'), + nil + }, + separator, + line_separator, + separator, + { + layout = wibox.layout.stack, + -- Today Pane + { + id = 'pane_id', + visible = true, + layout = wibox.layout.fixed.vertical, + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(7), + require('widget.user-profile'), + require('widget.weather'), + require('widget.email'), + require('widget.social-media'), + require('widget.calculator') + }, + + }, + -- Notification Center + { + id = 'notif_id', + visible = false, + require('widget.notif-center')(s), + layout = wibox.layout.fixed.vertical, + } + }, + }, + margins = dpi(16), + widget = wibox.container.margin + } + + return panel +end + +return right_panel + diff --git a/.config/awesome/layout/right-panel/panel-mode-switcher.lua b/.config/awesome/layout/right-panel/panel-mode-switcher.lua new file mode 100644 index 0000000..1b6876e --- /dev/null +++ b/.config/awesome/layout/right-panel/panel-mode-switcher.lua @@ -0,0 +1,135 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +-- Variable used for switching panel modes +right_panel_mode = 'today_mode' + +local active_button = beautiful.groups_title_bg +local inactive_button = beautiful.transparent + +local notif_text = wibox.widget +{ + text = 'Notifications', + font = 'Inter Bold 11', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local notif_button = clickable_container( + wibox.container.margin( + notif_text, dpi(0), dpi(0), dpi(7), dpi(7) + ) +) + +local wrap_notif = wibox.widget { + notif_button, + forced_width = dpi(140), + bg = inactive_button, + border_width = dpi(1), + border_color = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, false, true, true, false, beautiful.groups_radius + ) + end, + widget = wibox.container.background +} + + +local today_text = wibox.widget +{ + text = 'Today', + font = 'Inter Bold 11', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local today_button = clickable_container( + wibox.container.margin( + today_text, dpi(0), dpi(0), dpi(7), dpi(7) + ) +) + +local wrap_today = wibox.widget { + today_button, + forced_width = dpi(140), + bg = active_button, + border_width = dpi(1), + border_color = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, true, false, false, true, beautiful.groups_radius + ) + end, + widget = wibox.container.background +} + +local switcher = wibox.widget { + expand = 'none', + layout = wibox.layout.fixed.horizontal, + wrap_today, + wrap_notif +} + + +function switch_rdb_pane(right_panel_mode) + + local focused = awful.screen.focused() + + if right_panel_mode == 'notif_mode' then + + -- Update button color + wrap_notif.bg = active_button + wrap_today.bg = inactive_button + + -- Change panel content of right-panel.lua + focused.right_panel:switch_pane(right_panel_mode) + + elseif right_panel_mode == 'today_mode' then + + -- Update button color + wrap_notif.bg = inactive_button + wrap_today.bg = active_button + + -- Change panel content of right-panel.lua + focused.right_panel:switch_pane(right_panel_mode) + end + +end + + +notif_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + switch_rdb_pane('notif_mode') + end + ) + ) +) + +today_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + switch_rdb_pane('today_mode') + end + ) + ) +) + + +return switcher diff --git a/.config/awesome/layout/top-panel.lua b/.config/awesome/layout/top-panel.lua new file mode 100755 index 0000000..3c52906 --- /dev/null +++ b/.config/awesome/layout/top-panel.lua @@ -0,0 +1,99 @@ +local awful = require('awful') +local beautiful = require('beautiful') +local wibox = require('wibox') +local gears = require('gears') +local icons = require('theme.icons') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local task_list = require('widget.task-list') + +local top_panel = function(s, offset) + + local offsetx = 0 + if offset == true then + offsetx = dpi(45) + end + + local panel = wibox + { + ontop = true, + screen = s, + type = 'dock', + height = dpi(28), + width = s.geometry.width - offsetx, + x = s.geometry.x + offsetx, + y = s.geometry.y, + stretch = false, + bg = beautiful.background, + fg = beautiful.fg_normal + } + + panel:struts + { + top = dpi(28) + } + + panel:connect_signal( + 'mouse::enter', + function() + local w = mouse.current_wibox + if w then + w.cursor = 'left_ptr' + end + end + ) + + s.systray = wibox.widget { + visible = false, + base_size = dpi(20), + horizontal = true, + screen = 'primary', + widget = wibox.widget.systray + } + + local clock = require('widget.clock')(s) + local layout_box = require('widget.layoutbox')(s) + local add_button = require('widget.open-default-app')(s) + s.tray_toggler = require('widget.tray-toggle') + s.updater = require('widget.package-updater')() + s.screen_rec = require('widget.screen-recorder')() + s.mpd = require('widget.mpd')() + s.bluetooth = require('widget.bluetooth')() + s.battery = require('widget.battery')() + s.network = require('widget.network')() + s.info_center_toggle = require('widget.info-center-toggle')() + + panel : setup { + layout = wibox.layout.align.horizontal, + expand = 'none', + { + layout = wibox.layout.fixed.horizontal, + task_list(s), + add_button + }, + clock, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(5), + { + s.systray, + margins = dpi(5), + widget = wibox.container.margin + }, + s.tray_toggler, + s.updater, + s.screen_rec, + s.mpd, + s.network, + s.bluetooth, + s.battery, + layout_box, + s.info_center_toggle + } + } + + return panel +end + + +return top_panel diff --git a/.config/awesome/library/json.lua b/.config/awesome/library/json.lua new file mode 100644 index 0000000..3fbaea7 --- /dev/null +++ b/.config/awesome/library/json.lua @@ -0,0 +1,201 @@ +-- ░▀▀█░█▀▀░█▀█░█▀█░░ +-- ░░░█░▀▀█░█░█░█░█░░ +-- ░▀▀░░▀▀▀░▀▀▀░▀░▀░░ + +-- This script is from https://gist.github.com/tylerneylon/59f4bcf316be525b30ab +-- License: None. Public Domain + +--[[ json.lua + +A compact pure-Lua JSON library. +The main functions are: json.stringify, json.parse. + +## json.stringify: + +This expects the following to be true of any tables being encoded: + * They only have string or number keys. Number keys must be represented as + strings in json; this is part of the json spec. + * They are not recursive. Such a structure cannot be specified in json. + +A Lua table is considered to be an array if and only if its set of keys is a +consecutive sequence of positive integers starting at 1. Arrays are encoded like +so: `[2, 3, false, "hi"]`. Any other type of Lua table is encoded as a json +object, encoded like so: `{"key1": 2, "key2": false}`. + +Because the Lua nil value cannot be a key, and as a table value is considerd +equivalent to a missing key, there is no way to express the json "null" value in +a Lua table. The only way this will output "null" is if your entire input obj is +nil itself. + +An empty Lua table, {}, could be considered either a json object or array - +it's an ambiguous edge case. We choose to treat this as an object as it is the +more general type. + +To be clear, none of the above considerations is a limitation of this code. +Rather, it is what we get when we completely observe the json specification for +as arbitrary a Lua object as json is capable of expressing. + +## json.parse: + +This function parses json, with the exception that it does not pay attention to +\u-escaped unicode code points in strings. + +It is difficult for Lua to return null as a value. In order to prevent the loss +of keys with a null value in a json string, this function uses the one-off +table value json.null (which is just an empty table) to indicate null values. +This way you can check if a value is null with the conditional +`val == json.null`. + +If you have control over the data and are using Lua, I would recommend just +avoiding null values in your data to begin with. + +--]] + + +local json = {} + + +-- Internal functions. + +local function kind_of(obj) + if type(obj) ~= 'table' then return type(obj) end + local i = 1 + for _ in pairs(obj) do + if obj[i] ~= nil then i = i + 1 else return 'table' end + end + if i == 1 then return 'table' else return 'array' end +end + +local function escape_str(s) + local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'} + local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'} + for i, c in ipairs(in_char) do + s = s:gsub(c, '\\' .. out_char[i]) + end + return s +end + +-- Returns pos, did_find; there are two cases: +-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. +-- 2. Delimiter not found: pos = pos after leading space; did_find = false. +-- This throws an error if err_if_missing is true and the delim is not found. +local function skip_delim(str, pos, delim, err_if_missing) + pos = pos + #str:match('^%s*', pos) + if str:sub(pos, pos) ~= delim then + if err_if_missing then + error('Expected ' .. delim .. ' near position ' .. pos) + end + return pos, false + end + return pos + 1, true +end + +-- Expects the given pos to be the first character after the opening quote. +-- Returns val, pos; the returned pos is after the closing quote character. +local function parse_str_val(str, pos, val) + val = val or '' + local early_end_error = 'End of input found while parsing string.' + if pos > #str then error(early_end_error) end + local c = str:sub(pos, pos) + if c == '"' then return val, pos + 1 end + if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end + -- We must have a \ character. + local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} + local nextc = str:sub(pos + 1, pos + 1) + if not nextc then error(early_end_error) end + return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) +end + +-- Returns val, pos; the returned pos is after the number's final character. +local function parse_num_val(str, pos) + local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) + local val = tonumber(num_str) + if not val then error('Error parsing number at position ' .. pos .. '.') end + return val, pos + #num_str +end + + +-- Public values and functions. + +function json.stringify(obj, as_key) + local s = {} -- We'll build the string as an array of strings to be concatenated. + local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise. + if kind == 'array' then + if as_key then error('Can\'t encode array as key.') end + s[#s + 1] = '[' + for i, val in ipairs(obj) do + if i > 1 then s[#s + 1] = ', ' end + s[#s + 1] = json.stringify(val) + end + s[#s + 1] = ']' + elseif kind == 'table' then + if as_key then error('Can\'t encode table as key.') end + s[#s + 1] = '{' + for k, v in pairs(obj) do + if #s > 1 then s[#s + 1] = ', ' end + s[#s + 1] = json.stringify(k, true) + s[#s + 1] = ':' + s[#s + 1] = json.stringify(v) + end + s[#s + 1] = '}' + elseif kind == 'string' then + return '"' .. escape_str(obj) .. '"' + elseif kind == 'number' then + if as_key then return '"' .. tostring(obj) .. '"' end + return tostring(obj) + elseif kind == 'boolean' then + return tostring(obj) + elseif kind == 'nil' then + return 'null' + else + error('Unjsonifiable type: ' .. kind .. '.') + end + return table.concat(s) +end + +json.null = {} -- This is a one-off table to represent the null value. + +function json.parse(str, pos, end_delim) + pos = pos or 1 + if pos > #str then error('Reached unexpected end of input.') end + local pos = pos + #str:match('^%s*', pos) -- Skip whitespace. + local first = str:sub(pos, pos) + if first == '{' then -- Parse an object. + local obj, key, delim_found = {}, true, true + pos = pos + 1 + while true do + key, pos = json.parse(str, pos, '}') + if key == nil then return obj, pos end + if not delim_found then error('Comma missing between object items.') end + pos = skip_delim(str, pos, ':', true) -- true -> error if missing. + obj[key], pos = json.parse(str, pos) + pos, delim_found = skip_delim(str, pos, ',') + end + elseif first == '[' then -- Parse an array. + local arr, val, delim_found = {}, true, true + pos = pos + 1 + while true do + val, pos = json.parse(str, pos, ']') + if val == nil then return arr, pos end + if not delim_found then error('Comma missing between array items.') end + arr[#arr + 1] = val + pos, delim_found = skip_delim(str, pos, ',') + end + elseif first == '"' then -- Parse a string. + return parse_str_val(str, pos + 1) + elseif first == '-' or first:match('%d') then -- Parse a number. + return parse_num_val(str, pos) + elseif first == end_delim then -- End of an object or array. + return nil, pos + 1 + else -- Parse true, false, or null. + local literals = {['true'] = true, ['false'] = false, ['null'] = json.null} + for lit_str, lit_val in pairs(literals) do + local lit_end = pos + #lit_str - 1 + if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end + end + local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) + error('Invalid json syntax starting at ' .. pos_info_str) + end +end + +return json diff --git a/.config/awesome/module/auto-start.lua b/.config/awesome/module/auto-start.lua new file mode 100644 index 0000000..601bd39 --- /dev/null +++ b/.config/awesome/module/auto-start.lua @@ -0,0 +1,36 @@ +-- MODULE AUTO-START +-- Run all the apps listed in configuration/apps.lua as run_on_start_up only once when awesome start + +local awful = require('awful') +local naughty = require('naughty') +local apps = require('configuration.apps') +local config = require('configuration.config') +local debug_mode = config.module.auto_start.debug_mode or false + +local run_once = function(cmd) + local findme = cmd + local firstspace = cmd:find(' ') + if firstspace then + findme = cmd:sub(0, firstspace - 1) + end + awful.spawn.easy_async_with_shell( + string.format('pgrep -u $USER -x %s > /dev/null || (%s)', findme, cmd), + function(stdout, stderr) + -- Debugger + if not stderr or stderr == '' or not debug_mode then + return + end + naughty.notification({ + app_name = 'Start-up Applications', + title = 'Oof! Error detected when starting an application!', + message = stderr:gsub('%\n', ''), + timeout = 20, + icon = require('beautiful').awesome_icon + }) + end + ) +end + +for _, app in ipairs(apps.run_on_start_up) do + run_once(app) +end diff --git a/.config/awesome/module/brightness-osd.lua b/.config/awesome/module/brightness-osd.lua new file mode 100644 index 0000000..4538736 --- /dev/null +++ b/.config/awesome/module/brightness-osd.lua @@ -0,0 +1,268 @@ +local awful = require("awful") +local gears = require("gears") +local wibox = require("wibox") +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +local osd_header = wibox.widget { + text = 'Brightness', + font = 'Inter Bold 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local osd_value = wibox.widget { + text = '0%', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local slider_osd = wibox.widget { + nil, + { + id = 'bri_osd_slider', + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(2), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +local bri_osd_slider = slider_osd.bri_osd_slider + +bri_osd_slider:connect_signal( + 'property::value', + function() + local brightness_level = bri_osd_slider:get_value() + + awful.spawn('light -S ' .. math.max(brightness_level, 5), false) + + -- Update textbox widget text + osd_value.text = brightness_level .. '%' + + -- Update the brightness slider if values here change + awesome.emit_signal('widget::brightness:update', brightness_level) + + if awful.screen.focused().show_bri_osd then + awesome.emit_signal( + 'module::brightness_osd:show', + true + ) + end + end +) + +bri_osd_slider:connect_signal( + 'button::press', + function() + awful.screen.focused().show_bri_osd = true + end +) + +bri_osd_slider:connect_signal( + 'mouse::enter', + function() + awful.screen.focused().show_bri_osd = true + end +) + +-- The emit will come from brightness slider +awesome.connect_signal( + 'module::brightness_osd', + function(brightness) + bri_osd_slider:set_value(brightness) + end +) + +local icon = wibox.widget { + { + image = icons.brightness, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin +} + +local brightness_slider_osd = wibox.widget { + icon, + slider_osd, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal +} + +local osd_height = dpi(100) +local osd_width = dpi(300) +local osd_margin = dpi(10) + +screen.connect_signal( + 'request::desktop_decoration', + function(s) + local s = s or {} + s.show_bri_osd = false + + s.brightness_osd_overlay = awful.popup { + widget = { + -- Removing this block will cause an error... + }, + ontop = true, + visible = false, + type = 'notification', + screen = s, + height = osd_height, + width = osd_width, + maximum_height = osd_height, + maximum_width = osd_width, + offset = dpi(5), + shape = gears.shape.rectangle, + bg = beautiful.transparent, + preferred_anchors = 'middle', + preferred_positions = {'left', 'right', 'top', 'bottom'} + } + + s.brightness_osd_overlay : setup { + { + { + { + layout = wibox.layout.align.horizontal, + expand = 'none', + forced_height = dpi(48), + osd_header, + nil, + osd_value + }, + brightness_slider_osd, + layout = wibox.layout.fixed.vertical + }, + left = dpi(24), + right = dpi(24), + widget = wibox.container.margin + }, + bg = beautiful.background, + shape = gears.shape.rounded_rect, + widget = wibox.container.background() + } + + -- Reset timer on mouse hover + s.brightness_osd_overlay:connect_signal( + 'mouse::enter', + function() + awful.screen.focused().show_bri_osd = true + awesome.emit_signal('module::brightness_osd:rerun') + end + ) + end +) + +local hide_osd = gears.timer { + timeout = 2, + autostart = true, + callback = function() + local focused = awful.screen.focused() + focused.brightness_osd_overlay.visible = false + focused.show_bri_osd = false + end +} + +awesome.connect_signal( + 'module::brightness_osd:rerun', + function() + if hide_osd.started then + hide_osd:again() + else + hide_osd:start() + end + end +) + +local placement_placer = function() + local focused = awful.screen.focused() + + local right_panel = focused.right_panel + local left_panel = focused.left_panel + local brightness_osd = focused.brightness_osd_overlay + + if right_panel and left_panel then + if right_panel.visible then + awful.placement.bottom_left( + brightness_osd, + { + margins = { + left = osd_margin, + right = 0, + top = 0, + bottom = osd_margin + }, + honor_workarea = true + } + ) + return + end + end + + if right_panel then + if right_panel.visible then + awful.placement.bottom_left( + brightness_osd, + { + margins = { + left = osd_margin, + right = 0, + top = 0, + bottom = osd_margin + }, + honor_workarea = true + } + ) + return + end + end + + awful.placement.bottom_right( + brightness_osd, + { + margins = { + left = 0, + right = osd_margin, + top = 0, + bottom = osd_margin + }, + honor_workarea = true + } + ) +end + +awesome.connect_signal( + 'module::brightness_osd:show', + function(bool) + placement_placer() + awful.screen.focused().brightness_osd_overlay.visible = bool + if bool then + awesome.emit_signal('module::brightness_osd:rerun') + awesome.emit_signal( + 'module::volume_osd:show', + false + ) + else + if hide_osd.started then + hide_osd:stop() + end + end + end +) diff --git a/.config/awesome/module/dynamic-wallpaper.lua b/.config/awesome/module/dynamic-wallpaper.lua new file mode 100755 index 0000000..72e4406 --- /dev/null +++ b/.config/awesome/module/dynamic-wallpaper.lua @@ -0,0 +1,364 @@ +---------------------------------------------------------------------------- +--- Wallpaper changer module +-- +-- @author Gerome Matilla <gerome.matilla07@gmail.com> +-- @copyright 2019 Gerome Matilla +-- @module wallchange +-- +--- Nevermind this. Do what you want. +---------------------------------------------------------------------------- + +-- This module changes wallpaper based on declared time +-- It checks the difference between the current time and the next scheduled time +-- Then convert it to seconds to set it as a timeout value + +-- Limitations: +-- Timeout paused when laptop/pc is suspended or in sleep mode, and there's probably some bugs too so whatever +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local filesystem = gears.filesystem +local config = require('configuration.config') + + +-- ======================================== +-- Configuration +-- Change your preference here +-- ======================================== + +local wall_config = { + -- Wallpaper directory. The default is: + -- local wall_config.wall_dir = os.getenv('HOME') .. 'Pictures/Wallpapers/' + wall_dir = filesystem.get_configuration_dir() .. (config.module.dynamic_wallpaper.wall_dir or 'theme/wallpapers/'), + + -- If there's a picture format that awesome accepts and i missed + -- (which i probably did) feel free to add it right here + valid_picture_formats = config.module.dynamic_wallpaper.valid_picture_formats or {"jpg", "png", "jpeg"}, + + -- Table mapping schedule to wallpaper filename + wallpaper_schedule = config.module.dynamic_wallpaper.wallpaper_schedule or { + ['00:00:00'] = 'midnight-wallpaper.jpg', + ['06:22:00'] = 'morning-wallpaper.jpg', + ['12:00:00'] = 'noon-wallpaper.jpg', + ['17:58:00'] = 'night-wallpaper.jpg' + }, + + -- Don't stretch wallpaper on multihead setups if true + stretch = config.module.dynamic_wallpaper.stretch or false +} + +-- ======================================== +-- Processes +-- Don't touch it if it's working +-- ======================================== + +-- Get current time +local current_time = function() + return os.date('%H:%M:%S') +end + +-- Countdown variable +-- In seconds +local the_countdown = nil + +-- Parse seconds to HH:MM:SS +local function parse_to_time(seconds) + -- DST ruined me :( + --return os.date("%H:%M:%S", seconds) + + local function format(str) + while #str < 2 do + str = '0' .. str + end + + return str + end + + local function convert(num) + return format(tostring(num)) + end + + local hours = convert(math.floor(seconds / 3600)) + seconds = seconds - (hours * 3600) + + local minutes = convert(math.floor(seconds / 60)) + seconds = seconds - (minutes * 60) + + local seconds = convert(math.floor(seconds)) + + return (hours .. ':' .. minutes .. ':' .. seconds) + +end + +-- Parse HH:MM:SS to seconds +local parse_to_seconds = function(time) + + -- Convert HH in HH:MM:SS + local hour_sec = tonumber(string.sub(time, 1, 2)) * 3600 + + -- Convert MM in HH:MM:SS + local min_sec = tonumber(string.sub(time, 4, 5)) * 60 + + -- Get SS in HH:MM:SS + local get_sec = tonumber(string.sub(time, 7, 8)) + + -- Return computed seconds + return (hour_sec + min_sec + get_sec) +end + +-- Get time difference +local time_diff = function(future, past) + local diff = parse_to_seconds(future) - parse_to_seconds(past) + if diff < 0 then + diff = diff + (24 * 3600) --If time difference is negative, the future is meant for tomorrow + end + return diff +end + +-- Returns a table containing all file paths in a directory +local function get_dir_contents(dir) + -- Command to give list of files in directory + local dir_explore = 'find ' .. dir .. ' -printf "%f\\n"' + local lines = io.popen(dir_explore):lines() --Done synchronously because we literally can't continue without files + local files = {} + for line in lines do + table.insert(files, line) + end + return files +end + +-- Returns a table of all the files that were one of the valid file formats +local function filter_files_by_format(files, valid_file_formats) + local valid_files = {} + for _, file in ipairs(files) do + for _, format in ipairs(valid_file_formats) do + if string.match(file, ".+%." .. format) ~= nil then + table.insert(valid_files, file) + break --No need to check other formats + end + end + end + + return valid_files +end + +-- Returns a table of files that contained any of the keywords, in the same order as the words themselves +local function find_files_containing_keywords(files, keywords) + local found_files = {} + + for _, word in ipairs(keywords) do --Preserves keyword order inherently, conveniently + for _, file in ipairs(files) do + -- Check if file is word, contains word at beginning or contains word between 2 non-alphanumeric characters + if file == word or string.find(file, "^" .. word .. "[^%a]") or string.find(file, "[^%a]" .. word .. "[^%a]") then + found_files[word] = file + break --Only return 1 file per word + end + end + end + + return found_files +end + +-- Turn an ordered list of files into a scheduled list of files +local function auto_schedule(wall_list) + local sched = {} + for index, file in ipairs(wall_list) do + local auto_time = parse_to_time(parse_to_seconds("24:00:00") * (index - 1) / #wall_list) + sched[auto_time] = file + end + + return sched +end + +-- Reformat whatever schedule was specified into an actual schedule +if #wall_config.wallpaper_schedule == 0 then + local count = 0 + -- Determine if empty or if manual schedule + for k, v in pairs(wall_config.wallpaper_schedule) do + count = count + 1 + end + + if count == 0 then --Schedule is actually empty + -- Get all pictures + local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats) + + --Sort pictures as sanely as possible + local function order_pictures(a, b) --Attempts to mimic default sort but numbers aren't compared as strings + if tonumber(a) ~= nil and tonumber(b) ~= nil then + return tonumber(a) < tonumber(b) + else + return a < b + end + end + table.sort(pictures, order_pictures) + + wall_config.wallpaper_schedule = auto_schedule(pictures) + + else --Schedule is manually timed + -- Get times as list + local ordered_times = {} + for time, _ in pairs(wall_config.wallpaper_schedule) do + table.insert(ordered_times, time) + end + + -- Sort times using seconds as comparison + local function order_time_asc(a, b) + return parse_to_seconds(a) < parse_to_seconds(b) + end + table.sort(ordered_times, order_time_asc) + + -- Get ordered list of keywords from ordered times + local keywords = {} + for index, time in ipairs(ordered_times) do + keywords[index] = wall_config.wallpaper_schedule[time] + end + + -- Get any pictures that match keywords + local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats) + pictures = find_files_containing_keywords(pictures, keywords) + + -- Replace keywords with files + for index, time in ipairs(ordered_times) do + local word = wall_config.wallpaper_schedule[time] + if pictures[word] ~= nil then + wall_config.wallpaper_schedule[time] = pictures[word] + else --To avoid crashes, we'll remove entries with invalid keywords + wall_config.wallpaper_schedule[time] = nil + end + end + end +else --Schedule is list of keywords + local keywords = wall_config.wallpaper_schedule + + -- Get any pictures that match keywords + local pictures = filter_files_by_format(get_dir_contents(wall_config.wall_dir), wall_config.valid_picture_formats) + pictures = find_files_containing_keywords(pictures, keywords) + + -- Order files by keyword (if a file was found for the keyword) + local ordered_pictures = {} + for _, word in ipairs(keywords) do + local file = pictures[word] + if file ~= nil then + table.insert(ordered_pictures, file) + end + end + + wall_config.wallpaper_schedule = auto_schedule(ordered_pictures) +end + +-- Set wallpaper +local set_wallpaper = function(path) + if wall_config.stretch then + for s in screen do + -- Update wallpaper based on the data in the array + gears.wallpaper.maximized (path, s) + end + else + -- Update wallpaper based on the data in the array + gears.wallpaper.maximized (path) + end +end + +-- Update wallpaper (used by the manage_timer function) +-- I think the gears.wallpaper.maximized is too fast or being ran asynchronously +-- So the wallpaper is not being updated on awesome (re)start without this timer +-- We need some delay. +-- Hey it's working, so whatever +local update_wallpaper = function(wall_name) + local wall_dir = wall_config.wall_dir .. wall_name + set_wallpaper(wall_dir) + + -- Overwrite the default wallpaper + -- This is important in case we add an extra monitor + beautiful.wallpaper = wall_dir +end + +-- Updates variables +local manage_timer = function() + -- Get current time + local time_now = parse_to_seconds(current_time()) + + local previous_time = '' --Scheduled time that should activate now + local next_time = '' --Time that should activate next + + local first_time = '24:00:00' --First scheduled time registered (to be found) + local last_time = '00:00:00' --Last scheduled time registered (to be found) + + -- Find previous_time + for time, wallpaper in pairs(wall_config.wallpaper_schedule) do + local parsed_time = parse_to_seconds(time) + if previous_time == '' or parsed_time > parse_to_seconds(previous_time) then + if parsed_time <= time_now then + previous_time = time + end + end + + if parsed_time > parse_to_seconds(last_time) then + last_time = time + end + end + + -- Previous time being blank = no scheduled time today. Therefore + -- the last time was yesterday's latest time + if previous_time == '' then + previous_time = last_time + end + + --Find next_time + for time, wallpaper in pairs(wall_config.wallpaper_schedule) do + local parsed_time = parse_to_seconds(time) + if next_time == '' or parsed_time < parse_to_seconds(next_time) then + if parsed_time > time_now then + next_time = time + end + end + + if parsed_time < parse_to_seconds(first_time) then + first_time = time + end + end + + -- Next time being blank means that there is no scheduled times left for + -- the current day. So next scheduled time is tomorrow's first time + if next_time == '' then + next_time = first_time + end + + -- Update Wallpaper + update_wallpaper(wall_config.wallpaper_schedule[previous_time]) + + -- Get the time difference to set as timeout for the wall_updater timer below + the_countdown = time_diff(next_time, current_time()) + +end + +-- Update values at startup +manage_timer() + +local wall_updater = gears.timer { + -- The timeout is the difference of current time and the scheduled time we set above. + timeout = the_countdown, + autostart = true, + call_now = true, + callback = function() + -- Emit signal to update wallpaper + awesome.emit_signal('module::change_wallpaper') + end +} + +-- Update wallpaper here and update the timeout for the next schedule +awesome.connect_signal( + 'module::change_wallpaper', + function() + --set_wallpaper(wall_dir .. wall_data[2]) + + -- Update values for the next specified schedule + manage_timer() + + -- Update timer timeout for the next specified schedule + wall_updater.timeout = the_countdown + + -- Restart timer + wall_updater:again() + end +) diff --git a/.config/awesome/module/exit-screen.lua b/.config/awesome/module/exit-screen.lua new file mode 100644 index 0000000..ee26849 --- /dev/null +++ b/.config/awesome/module/exit-screen.lua @@ -0,0 +1,360 @@ +local awful = require('awful') +local gears = require('gears') +local wibox = require('wibox') +local beautiful = require('beautiful') +local filesystem = gears.filesystem +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') +local apps = require('configuration.apps') +local clickable_container = require('widget.clickable-container') +local config_dir = filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'configuration/user-profile/' + +local msg_table = { + 'See you later, alligator!', + 'After a while, crocodile.', + 'Stay out of trouble.', + 'I’m out of here.', + 'Yamete, onii-chan~. UwU', + 'Okay...bye, fry guy!', + 'Peace out!', + 'Peace out, bitch!', + 'Gotta get going.', + 'Out to the door, dinosaur.', + 'Don\'t forget to come back!', + 'Smell ya later!', + 'In a while, crocodile.', + 'Adios, amigo.', + 'Begone!', + 'Arrivederci.', + 'Never look back!', + 'So long, sucker!', + 'Au revoir!', + 'Later, skater!', + 'That\'ll do pig. That\'ll do.', + 'Happy trails!', + 'Smell ya later!', + 'See you soon, baboon!', + 'Bye Felicia!', + 'Sayonara!', + 'Ciao!', + 'Well.... bye.', + 'Delete your browser history!', + 'See you, Space Cowboy!', + 'Change da world. My final message. Goodbye.', + 'Find out on the next episode of Dragonball Z...', + 'Choose wisely!' +} + +local greeter_message = wibox.widget { + markup = 'Choose wisely!', + font = 'Inter UltraLight 48', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local profile_name = wibox.widget { + markup = 'user@hostname', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local profile_imagebox = wibox.widget { + image = widget_icon_dir .. 'default.svg', + resize = true, + forced_height = dpi(140), + clip_shape = gears.shape.circle, + widget = wibox.widget.imagebox +} + +local update_profile_pic = function() + awful.spawn.easy_async_with_shell( + apps.utils.update_profile, + function(stdout) + stdout = stdout:gsub('%\n','') + if not stdout:match('default') then + profile_imagebox:set_image(stdout) + else + profile_imagebox:set_image(widget_icon_dir .. 'default.svg') + end + profile_imagebox:emit_signal('widget::redraw_needed') + end + ) +end + +update_profile_pic() + +local update_user_name = function() + awful.spawn.easy_async_with_shell( + [[ + fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")" + if [ -z "$fullname" ]; + then + printf "$(whoami)@$(hostname)" + else + printf "$fullname" + fi + ]], + function(stdout) + stdout = stdout:gsub('%\n','') + local first_name = stdout:match('(.*)@') or stdout:match('(.-)%s') + first_name = first_name:sub(1, 1):upper() .. first_name:sub(2) + profile_name:set_markup(stdout) + profile_name:emit_signal('widget::redraw_needed') + end + ) +end + +update_user_name() + +local update_greeter_msg = function() + greeter_message:set_markup(msg_table[math.random(#msg_table)]) + greeter_message:emit_signal('widget::redraw_needed') +end + +update_greeter_msg() + +local build_power_button = function(name, icon, callback) + local power_button_label= wibox.widget { + text = name, + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + } + + local power_button = wibox.widget { + { + { + { + { + image = icon, + widget = wibox.widget.imagebox + }, + margins = dpi(16), + widget = wibox.container.margin + }, + bg = beautiful.groups_bg, + widget = wibox.container.background + }, + shape = gears.shape.rounded_rect, + forced_width = dpi(90), + forced_height = dpi(90), + widget = clickable_container + }, + left = dpi(24), + right = dpi(24), + widget = wibox.container.margin + } + + local exit_screen_item = wibox.widget { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + power_button, + power_button_label + } + + exit_screen_item:connect_signal( + 'button::release', + function() + callback() + end + ) + return exit_screen_item +end + +local suspend_command = function() + awesome.emit_signal('module::exit_screen:hide') + awful.spawn.with_shell(apps.default.lock .. ' & systemctl suspend') +end + +local logout_command = function() + awesome.quit() +end + +local lock_command = function() + awesome.emit_signal('module::exit_screen:hide') + awful.spawn.with_shell(apps.default.lock) +end + +local poweroff_command = function() + awful.spawn.with_shell('poweroff') + awesome.emit_signal('module::exit_screen:hide') +end + +local reboot_command = function() + awful.spawn.with_shell('reboot') + awesome.emit_signal('module::exit_screen:hide') +end + +local poweroff = build_power_button('Shutdown', icons.power, poweroff_command) +local reboot = build_power_button('Restart', icons.restart, reboot_command) +local suspend = build_power_button('Sleep', icons.sleep, suspend_command) +local logout = build_power_button('Logout', icons.logout, logout_command) +local lock = build_power_button('Lock', icons.lock, lock_command) + +local create_exit_screen = function(s) + s.exit_screen = wibox + { + screen = s, + type = 'splash', + visible = false, + ontop = true, + bg = beautiful.background, + fg = beautiful.fg_normal, + height = s.geometry.height, + width = s.geometry.width, + x = s.geometry.x, + y = s.geometry.y + } + + s.exit_screen:buttons( + gears.table.join( + awful.button( + {}, + 2, + function() + awesome.emit_signal('module::exit_screen:hide') + end + ), + awful.button( + {}, + 3, + function() + awesome.emit_signal('module::exit_screen:hide') + end + ) + ) + ) + + s.exit_screen : setup { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.vertical, + { + nil, + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + profile_imagebox, + nil + }, + nil + }, + profile_name + }, + nil, + expand = 'none', + layout = wibox.layout.align.horizontal + }, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + widget = wibox.container.margin, + margins = dpi(15), + greeter_message + }, + nil + }, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + { + { + poweroff, + reboot, + suspend, + logout, + lock, + layout = wibox.layout.fixed.horizontal + }, + spacing = dpi(30), + layout = wibox.layout.fixed.vertical + }, + widget = wibox.container.margin, + margins = dpi(15) + }, + nil + } + }, + nil + } +end + +screen.connect_signal( + 'request::desktop_decoration', + function(s) + create_exit_screen(s) + end +) + +screen.connect_signal( + 'removed', + function(s) + create_exit_screen(s) + end +) + +local exit_screen_grabber = awful.keygrabber { + auto_start = true, + stop_event = 'release', + keypressed_callback = function(self, mod, key, command) + if key == 's' then + suspend_command() + + elseif key == 'e' then + logout_command() + + elseif key == 'l' then + lock_command() + + elseif key == 'p' then + poweroff_command() + + elseif key == 'r' then + reboot_command() + + elseif key == 'Escape' or key == 'q' or key == 'x' then + awesome.emit_signal('module::exit_screen:hide') + end + end +} + +awesome.connect_signal( + 'module::exit_screen:show', + function() + for s in screen do + s.exit_screen.visible = false + end + awful.screen.focused().exit_screen.visible = true + exit_screen_grabber:start() + end +) + +awesome.connect_signal( + 'module::exit_screen:hide', + function() + update_greeter_msg() + exit_screen_grabber:stop() + for s in screen do + s.exit_screen.visible = false + end + end +) diff --git a/.config/awesome/module/lockscreen.lua b/.config/awesome/module/lockscreen.lua new file mode 100755 index 0000000..ed46bbe --- /dev/null +++ b/.config/awesome/module/lockscreen.lua @@ -0,0 +1,849 @@ +local wibox = require('wibox') +local gears = require('gears') +local awful = require('awful') +local naughty = require('naughty') +local beautiful = require('beautiful') +local filesystem = gears.filesystem +local config_dir = filesystem.get_configuration_dir() +local dpi = beautiful.xresources.apply_dpi +local apps = require('configuration.apps') +local widget_icon_dir = config_dir .. 'configuration/user-profile/' +local config = require('configuration.config') + +-- Add paths to package.cpath +package.cpath = package.cpath .. ';' .. config_dir .. '/library/?.so;' .. '/usr/lib/lua-pam/?.so;' + +-- Configuration table +local locker_config = { + -- Clock mode + military_clock = config.module.lockscreen.military_clock or false, + -- Fallback password + fallback_password = function() + return config.module.lockscreen.fallback_password or 'toor' + end, + -- Capture a picture using webcam + capture_intruder = config.module.lockscreen.capture_intruder or false, + -- Save location, auto creates + face_capture_dir = config.module.lockscreen.face_capture_dir or '$(xdg-user-dir PICTURES)/Intruders/', + -- Blur background + blur_background = config.module.lockscreen.blur_background or false, + -- Background directory + bg_dir = config.module.lockscreen.bg_dir or (config_dir .. 'theme/wallpapers/'), + -- Default background + bg_image = config.module.lockscreen.bg_image or 'morning-wallpaper.jpg', + -- /tmp directory + tmp_wall_dir = config.module.lockscreen.tmp_wall_dir or '/tmp/awesomewm/' .. os.getenv('USER') .. '/' +} + +-- Useful variables (DO NOT TOUCH THESE) +local input_password = nil +local lock_again = nil +local type_again = true +local capture_now = locker_config.capture_intruder +local locked_tag = nil + +local uname_text = wibox.widget { + id = 'uname_text', + markup = '$USER', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local caps_text = wibox.widget { + id = 'uname_text', + markup = 'Caps Lock is on', + font = 'Inter Italic 10', + align = 'center', + valign = 'center', + opacity = 0.0, + widget = wibox.widget.textbox +} + +local profile_imagebox = wibox.widget { + id = 'user_icon', + image = widget_icon_dir .. 'default.svg', + resize = true, + forced_height = dpi(130), + forced_width = dpi(130), + clip_shape = gears.shape.circle, + widget = wibox.widget.imagebox +} + +local clock_format = '%H:%M' +if not locker_config.military_clock then + clock_format = '%I:%M %p' +end + +-- Create clock widget +local time = wibox.widget.textclock(clock_format, 1) + +local wanted_text = wibox.widget { + markup = 'INTRUDER ALERT!', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local msg_table = { + 'This incident will be reported.', + 'We are watching you.', + 'We know where you live.', + 'RUN!', + 'Yamete, Oniichan~ uwu', + 'This will self-destruct in 5 seconds!', + 'Image successfully sent!', + 'You\'re doomed!', + 'Authentication failed!', + 'I am watching you.', + 'I know where you live.', + 'RUN!', + 'Your parents must be proud of you.' +} + +local wanted_msg = wibox.widget { + markup = 'This incident will be reported!', + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local wanted_image = wibox.widget { + image = widget_icon_dir .. 'default.svg', + resize = true, + forced_height = dpi(120), + clip_shape = gears.shape.rounded_rect, + widget = wibox.widget.imagebox +} + +local date_value = function() + local ordinal = nil + local date = os.date('%d') + local day = os.date('%A') + local month = os.date('%B') + + local first_digit = string.sub(date, 0, 1) + local last_digit = string.sub(date, -1) + if first_digit == '0' then + date = last_digit + end + + if last_digit == '1' and date ~= '11' then + ordinal = 'st' + elseif last_digit == '2' and date ~= '12' then + ordinal = 'nd' + elseif last_digit == '3' and date ~= '13' then + ordinal = 'rd' + else + ordinal = 'th' + end + + return date .. ordinal .. ' of ' .. month .. ', ' .. day +end + +local date = wibox.widget { + markup = date_value(), + font = 'Inter Bold 20', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local circle_container = wibox.widget { + bg = beautiful.transparent, + forced_width = dpi(140), + forced_height = dpi(140), + shape = gears.shape.circle, + widget = wibox.container.background +} + +local locker_arc = wibox.widget { + bg = beautiful.transparent, + forced_width = dpi(140), + forced_height = dpi(140), + shape = function(cr, width, height) + gears.shape.arc(cr, width, height, dpi(5), 0, (math.pi / 2), false, false) + end, + widget = wibox.container.background +} + +local rotate_container = wibox.container.rotate() +local locker_widget = wibox.widget { + { + locker_arc, + widget = rotate_container + }, + layout = wibox.layout.fixed.vertical +} + +-- Rotation direction table +local rotation_direction = {'north', 'west', 'south', 'east'} + +-- Red, Green, Yellow, Blue +local red = beautiful.system_red_dark +local green = beautiful.system_green_dark +local yellow = beautiful.system_yellow_dark +local blue = beautiful.system_blue_dark + +-- Color table +local arc_color = {red, green, yellow, blue} + +-- Processes +local locker = function(s) + + local lockscreen = wibox { + screen = s, + visible = false, + ontop = true, + type = 'splash', + width = s.geometry.width, + height = s.geometry.height, + bg = beautiful.background, + fg = beautiful.fg_normal + } + + -- Update username textbox + awful.spawn.easy_async_with_shell( + [[ + sh -c ' + fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")" + if [ -z "$fullname" ]; + then + printf "$(whoami)@$(hostname)" + else + printf "$fullname" + fi + ' + ]], + function(stdout) + stdout = stdout:gsub('%\n','') + uname_text:set_markup(stdout) + end + ) + + local update_profile_pic = function() + awful.spawn.easy_async_with_shell( + apps.utils.update_profile, + function(stdout) + stdout = stdout:gsub('%\n','') + if not stdout:match('default') then + profile_imagebox:set_image(stdout) + else + profile_imagebox:set_image(widget_icon_dir .. 'default.svg') + end + end + ) + end + + -- Update image + gears.timer.start_new( + 2, + function() + update_profile_pic() + end + ) + + local wanted_poster = awful.popup { + widget = { + { + { + wanted_text, + { + nil, + wanted_image, + nil, + expand = 'none', + layout = wibox.layout.align.horizontal + }, + wanted_msg, + spacing = dpi(5), + layout = wibox.layout.fixed.vertical + }, + margins = dpi(20), + widget = wibox.container.margin + }, + bg = beautiful.background, + shape = gears.shape.rounded_rect, + widget = wibox.container.background + }, + bg = beautiful.transparent, + type = 'utility', + ontop = true, + shape = gears.shape.rectangle, + maximum_width = dpi(250), + maximum_height = dpi(250), + hide_on_right_click = false, + preferred_anchors = {'middle'}, + visible = false + } + + -- Place wanted poster at the bottom of primary screen + awful.placement.top( + wanted_poster, + { + margins = { + top = dpi(10) + } + } + ) + + -- Check Capslock state + local check_caps = function() + awful.spawn.easy_async_with_shell( + 'xset q | grep Caps | cut -d: -f3 | cut -d0 -f1 | tr -d \' \'', + function(stdout) + if stdout:match('on') then + caps_text.opacity = 1.0 + else + caps_text.opacity = 0.0 + end + caps_text:emit_signal('widget::redraw_needed') + end + ) + end + + -- Rotate the color arc on random direction + local locker_arc_rotate = function() + + local direction = rotation_direction[math.random(#rotation_direction)] + local color = arc_color[math.random(#arc_color)] + + rotate_container.direction = direction + locker_arc.bg = color + + rotate_container:emit_signal('widget::redraw_needed') + locker_arc:emit_signal('widget::redraw_needed') + locker_widget:emit_signal('widget::redraw_needed') + end + + -- Check webcam + local check_webcam = function() + awful.spawn.easy_async_with_shell( + 'ls -l /dev/video* | grep /dev/video0', + function(stdout) + if not locker_config.capture_intruder then + capture_now = false + return + end + + if not stdout:match('/dev/video0') then + capture_now = false + else + capture_now = true + end + end + ) + end + + check_webcam() + + -- Snap an image of the intruder + local intruder_capture = function() + local capture_image = [[ + save_dir="]] .. locker_config.face_capture_dir .. [[" + date="$(date +%Y%m%d_%H%M%S)" + file_loc="${save_dir}SUSPECT-${date}.png" + + if [ ! -d "$save_dir" ]; then + mkdir -p "$save_dir"; + fi + + ffmpeg -f video4linux2 -s 800x600 -i /dev/video0 -ss 0:0:2 -frames 1 "${file_loc}" + + canberra-gtk-play -i camera-shutter & + echo "${file_loc}" + ]] + + -- Capture the filthy intruder face + awful.spawn.easy_async_with_shell( + capture_image, + function(stdout) + circle_container.bg = beautiful.transparent + + -- Humiliate the intruder by showing his/her hideous face + wanted_image:set_image(stdout:gsub('%\n','')) + wanted_msg:set_markup(msg_table[math.random(#msg_table)]) + wanted_poster.visible= true + + awful.placement.top( + wanted_poster, + { + margins = { + top = dpi(10) + } + } + ) + + wanted_image:emit_signal('widget::redraw_needed') + type_again = true + end + ) + end + + -- Login failed + local stoprightthereyoucriminalscum = function() + circle_container.bg = red .. 'AA' + if capture_now then + intruder_capture() + else + gears.timer.start_new( + 1, + function() + circle_container.bg = beautiful.transparent + type_again = true + end + ) + end + end + + -- Login successful + local generalkenobi_ohhellothere = function() + circle_container.bg = green .. 'AA' + + -- Add a little delay before unlocking completely + gears.timer.start_new( + 1, + function() + if capture_now then + -- Hide wanted poster + wanted_poster.visible = false + end + + -- Hide all the lockscreen on all screen + for s in screen do + if s.index == 1 then + s.lockscreen.visible = false + else + s.lockscreen_extended.visible = false + end + end + + circle_container.bg = beautiful.transparent + lock_again = true + type_again = true + + -- Select old tag + -- And restore minimized focused client if there's any + if locked_tag then + locked_tag.selected = true + locked_tag = nil + end + local c = awful.client.restore() + if c then + c:emit_signal('request::activate') + c:raise() + end + end + ) + end + -- A backdoor. + -- Sometimes I'm too lazy to type so I decided to create this. + -- Sometimes my genius is... it's almost frightening. + local back_door = function() + generalkenobi_ohhellothere() + end + + -- Check module if valid + local module_check = function(name) + if package.loaded[name] then + return true + else + for _, searcher in ipairs(package.searchers or package.loaders) do + local loader = searcher(name) + if type(loader) == 'function' then + package.preload[name] = loader + return true + end + end + return false + end + end + + -- Password/key grabber + local password_grabber = awful.keygrabber { + auto_start = true, + stop_event = 'release', + mask_event_callback = true, + keybindings = { + awful.key { + modifiers = {'Control'}, + key = 'u', + on_press = function() + input_password = nil + end + }, + awful.key { + modifiers = {'Mod1', 'Mod4', 'Shift', 'Control'}, + key = 'Return', + on_press = function(self) + if not type_again then + return + end + self:stop() + + -- Call backdoor + back_door() + end + } + }, + keypressed_callback = function(self, mod, key, command) + if not type_again then + return + end + + -- Clear input string + if key == 'Escape' then + -- Clear input threshold + input_password = nil + return + end + + -- Accept only the single charactered key + -- Ignore 'Shift', 'Control', 'Return', 'F1', 'F2', etc., etc. + if #key == 1 then + locker_arc_rotate() + + if input_password == nil then + input_password = key + return + end + input_password = input_password .. key + end + + end, + keyreleased_callback = function(self, mod, key, command) + locker_arc.bg = beautiful.transparent + locker_arc:emit_signal('widget::redraw_needed') + + if key == 'Caps_Lock' then + check_caps() + return + end + + if not type_again then + return + end + + -- Validation + if key == 'Return' then + -- Validate password + local authenticated = false + if input_password ~= nil then + -- If lua-pam library is 'okay' + if module_check('liblua_pam') then + local pam = require('liblua_pam') + authenticated = pam:auth_current_user(input_password) + else + -- Library doesn't exist or returns an error due to some reasons (read the manual) + -- Use fallback password data + authenticated = input_password == locker_config.fallback_password() + + local rtfm = naughty.action { + name = 'Read Wiki', + icon_only = false + } + + local dismiss = naughty.action { + name = 'Dismiss', + icon_only = false + } + + rtfm:connect_signal( + 'invoked', + function() + awful.spawn( + [[sh -c " + xdg-open 'https://github.com/manilarome/the-glorious-dotfiles/wiki' + "]], + false + ) + end + ) + + naughty.notification({ + app_name = 'Security', + title = 'WARNING', + message = 'You\'re using the fallback password! It\'s recommended to use the PAM Integration!', + urgency = 'critical', + actions = { rtfm, dismiss } + }) + end + end + + if authenticated then + -- Come in! + self:stop() + generalkenobi_ohhellothere() + else + -- F*ck off, you [REDACTED]! + stoprightthereyoucriminalscum() + end + + -- Allow typing again and empty password container + type_again = false + input_password = nil + end + end + } + + lockscreen : setup { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + expand = 'none', + spacing = dpi(20), + { + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + time, + nil + }, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + date, + nil + }, + expand = 'none', + layout = wibox.layout.fixed.vertical + }, + { + layout = wibox.layout.fixed.vertical, + { + circle_container, + locker_widget, + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + profile_imagebox, + nil + }, + nil, + }, + layout = wibox.layout.stack + }, + uname_text, + caps_text + }, + }, + nil + }, + nil + } + + local show_lockscreen = function() + -- Why is there a lock_again variable? + -- It prevents the user to spam locking while in a process of authentication + -- Prevents a potential bug/problem + if lock_again == true or lock_again == nil then + -- Force update clock widget + time:emit_signal('widget::redraw_needed') + + -- Check capslock status + check_caps() + + -- Check webcam status + check_webcam() + + -- Show all the lockscreen on each screen + for s in screen do + if s.index == 1 then + s.lockscreen.visible = true + else + s.lockscreen_extended.visible = true + end + end + + -- Start keygrabbing, but with a little delay to + -- give some extra time for the free_keygrab function + gears.timer.start_new( + 0.5, + function() + -- Start key grabbing for password + password_grabber:start() + end + ) + + -- Dont lock again + lock_again = false + end + end + + local free_keygrab = function() + -- Kill rofi instance. + awful.spawn.with_shell('kill -9 $(pgrep rofi)') + + -- Check if there's a keygrabbing instance. + -- If yes, stop it. + local keygrabbing_instance = awful.keygrabber.current_instance + if keygrabbing_instance then + keygrabbing_instance:stop() + end + + -- Unselect all tags and minimize the focused client + -- These will fix the problem with virtualbox or + -- any other program that has keygrabbing enabled + if client.focus then + client.focus.minimized = true + end + for _, t in ipairs(mouse.screen.selected_tags) do + locked_tag = t + t.selected = false + end + end + + awesome.connect_signal( + 'module::lockscreen_show', + function() + if lock_again == true or lock_again == nil then + free_keygrab() + show_lockscreen() + end + end + ) + return lockscreen +end + +-- This lockscreen is for the extra/multi monitor +local locker_ext = function(s) + local extended_lockscreen = wibox { + screen = s, + visible = false, + ontop = true, + ontype = 'true', + x = s.geometry.x, + y = s.geometry.y, + width = s.geometry.width, + height = s.geometry.height, + bg = beautiful.background, + fg = beautiful.fg_normal + } + return extended_lockscreen +end + +-- Create lockscreen for each screen +local create_lock_screens = function(s) + if s.index == 1 then + s.lockscreen = locker(s) + else + s.lockscreen_extended = locker_ext(s) + end +end + +-- Don't show notification popups if the screen is locked +local check_lockscreen_visibility = function() + focused = awful.screen.focused() + if focused.lockscreen and focused.lockscreen.visible then + return true + end + if focused.lockscreen_extended and focused.lockscreen_extended.visible then + return true + end + return false +end + +-- Notifications signal +naughty.connect_signal( + 'request::display', + function(_) + if check_lockscreen_visibility() then + naughty.destroy_all_notifications(nil, 1) + end + end +) + +-- Filter background image +local filter_bg_image = function(wall_name, index, ap, width, height) + -- Checks if the blur has to be blurred + local blur_filter_param = '' + if locker_config.blur_background then + blur_filter_param = '-filter Gaussian -blur 0x10' + end + + -- Create imagemagick command + local magic = [[ + sh -c " + if [ ! -d ]] .. locker_config.tmp_wall_dir ..[[ ]; + then + mkdir -p ]] .. locker_config.tmp_wall_dir .. [[; + fi + convert -quality 100 -brightness-contrast -20x0 ]] .. ' ' .. blur_filter_param .. ' '.. locker_config.bg_dir .. wall_name .. + [[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height .. + [[! ]] .. locker_config.tmp_wall_dir .. index .. wall_name .. [[ + "]] + return magic +end + +-- Apply lockscreen background image +local apply_ls_bg_image = function(wall_name) + -- Iterate through all the screens and create a lockscreen for each of it + for s in screen do + local index = s.index .. '-' + + -- Get screen geometry + local screen_width = s.geometry.width + local screen_height = s.geometry.height + + -- Get the right resolution/aspect ratio that will be use as the background + local aspect_ratio = screen_width / screen_height + aspect_ratio = math.floor(aspect_ratio * 100) / 100 + + -- Create image filter command + local cmd = nil + cmd = filter_bg_image(wall_name, index, aspect_ratio, screen_width, screen_height) + + -- Asign lockscreen to each screen + if s.index == 1 then + -- Primary screen + awful.spawn.easy_async_with_shell( + cmd, + function() + s.lockscreen.bgimage = locker_config.tmp_wall_dir .. index .. wall_name + end + ) + else + -- Multihead screen/s + awful.spawn.easy_async_with_shell( + cmd, + function() + s.lockscreen_extended.bgimage = locker_config.tmp_wall_dir .. index .. wall_name + end + ) + end + end +end + +-- Create a lockscreen and its background for each screen on start-up +screen.connect_signal( + 'request::desktop_decoration', + function(s) + create_lock_screens(s) + apply_ls_bg_image(locker_config.bg_image) + end +) + +-- Regenerate lockscreens and its background if a screen was removed to avoid errors +screen.connect_signal( + 'removed', + function(s) + create_lock_screens(s) + apply_ls_bg_image(locker_config.bg_image) + end +) diff --git a/.config/awesome/module/menu.lua b/.config/awesome/module/menu.lua new file mode 100644 index 0000000..7843dc2 --- /dev/null +++ b/.config/awesome/module/menu.lua @@ -0,0 +1,246 @@ +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local apps = require('configuration.apps') +local menubar = require('menubar') +local awful_menu = awful.menu +local menu_gen = menubar.menu_gen +local menu_utils = menubar.utils +local icon_theme = require('menubar.icon_theme') +local hotkeys_popup = require('awful.hotkeys_popup').widget + +local terminal = apps.default.terminal +local web_browser = apps.default.web_browser +local file_manager = apps.default.file_manager +local text_editor = apps.default.text_editor +local editor_cmd = terminal .. ' -e ' .. (os.getenv('EDITOR') or 'nano') + +--[[ + + Awesome-Freedesktop + Freedesktop.org compliant desktop entries and menu + + Menu section + + Licensed under GNU General Public License v2 + * (c) 2016, Luke Bonham + * (c) 2014, Harvey Mittens + +--]] + +local io, pairs, string, table, os = io, pairs, string, table, os + +-- Expecting a wm_name of awesome omits too many applications and tools +menu_utils.wm_name = '' + +-- Menu table +local menu = {} + +-- Determines if a path points to a directory, by checking if it can be read +-- (which is `nil` also for empty files) and if its size is not 0. +-- @author blueyed +-- @param path the path to check +menu.is_dir = function(path) + local f = io.open(path) + return f and not f:read(0) and f:seek('end') ~= 0 and f:close() +end + +-- Remove non existent paths in order to avoid issues +local existent_paths = {} +for k,v in pairs(menu_gen.all_menu_dirs) do + if menu.is_dir(v) then + table.insert(existent_paths, v) + end +end +menu_gen.all_menu_dirs = existent_paths + +-- Determines whether an table includes a certain element +-- @param tab a given table +-- @param val the element to search for +-- @return true if the given string is found within the search table; otherwise, false if not +menu.has_value = function(tab, val) + for index, value in pairs(tab) do + if val:find(value) then + return true + end + end + return false +end + +-- Use MenuBar parsing utils to build a menu for Awesome +-- @return awful.menu +menu.build = function(args) + local args = args or {} + local icon_size = args.icon_size + local before = args.before or {} + local after = args.after or {} + local skip_items = args.skip_items or {} + local sub_menu = args.sub_menu or false + + local result = {} + local _menu = awful_menu({ items = before }) + + menu_gen.generate(function(entries) + -- Add category icons + for k, v in pairs(menu_gen.all_categories) do + table.insert(result, { k, {}, v.icon }) + end + + -- Get items table + for k, v in pairs(entries) do + for _, cat in pairs(result) do + if cat[1] == v.category then + if not menu.has_value(skip_items, v.name) then + table.insert(cat[2], { v.name, v.cmdline, v.icon }) + end + break + end + end + end + + -- Cleanup things a bit + for i = #result, 1, -1 do + local v = result[i] + if #v[2] == 0 then + -- Remove unused categories + table.remove(result, i) + else + --Sort entries alphabetically (by name) + table.sort(v[2], function (a, b) return string.byte(a[1]) < string.byte(b[1]) end) + -- Replace category name with nice name + v[1] = menu_gen.all_categories[v[1]].name + end + end + + -- Sort categories alphabetically also + table.sort(result, function(a, b) return string.byte(a[1]) < string.byte(b[1]) end) + + -- Add menu item to hold the generated menu + if sub_menu then + result = {{sub_menu, result}} + end + + -- Add items to menu + for _, v in pairs(result) do _menu:add(v) end + for _, v in pairs(after) do _menu:add(v) end + end) + + -- Set icon size + if icon_size then + for _,v in pairs(menu_gen.all_categories) do + v.icon = icon_theme():find_icon_path(v.icon_name, icon_size) + end + end + + -- Hold the menu in the module + menu.menu = _menu + + return _menu +end + +-- Create a launcher widget and a main menu +awesome_menu = { + { + 'Hotkeys', + function() + hotkeys_popup.show_help(nil, awful.screen.focused()) + end, + menubar.utils.lookup_icon('keyboard') + }, + { + 'Edit config', + editor_cmd .. ' ' .. awesome.conffile, + menubar.utils.lookup_icon('accessories-text-editor') + }, + { + 'Restart', + awesome.restart, + menubar.utils.lookup_icon('system-restart') + }, + { + 'Quit', + function() awesome.quit() end, + menubar.utils.lookup_icon('system-log-out') + } +} + +local default_app_menu = { + { + 'Terminal', + terminal, + menubar.utils.lookup_icon('utilities-terminal') + }, + { + 'Web browser', + web_browser, + menubar.utils.lookup_icon('webbrowser-app') + }, + { + 'File Manager', + file_manager, + menubar.utils.lookup_icon('system-file-manager') + }, + { + 'Text Editor', + text_editor, + menubar.utils.lookup_icon('accessories-text-editor') + } +} + +-- Screenshot menu +local screenshot_menu = { + { + 'Full', + function() + gears.timer.start_new( + 0.1, + function() + awful.spawn.easy_async_with_shell(apps.utils.full_screenshot) + end + ) + end, + menubar.utils.lookup_icon('accessories-screenshot') + }, + { + 'Area', + function() + gears.timer.start_new( + 0.1, + function() + awful.spawn.easy_async_with_shell(apps.utils.area_screenshot) + end, + menubar.utils.lookup_icon('accessories-screenshot') + ) + end, + menubar.utils.lookup_icon('accessories-screenshot') + } +} + +local tools_menu = { + { + 'Awesome', + awesome_menu, + beautiful.awesome_icon + }, + { + 'Take a Screenshot', + screenshot_menu, + menubar.utils.lookup_icon('accessories-screenshot') + }, + { + 'End Session', + function() + awesome.emit_signal('module::exit_screen:show') + end, + menubar.utils.lookup_icon('system-shutdown') + } +} + +mymainmenu = menu.build({ + -- Not actually the size, but the quality of the icon + icon_size = 48, + before = default_app_menu, + after = tools_menu +}) + +mylauncher = awful.widget.launcher({image = beautiful.awesome_icon, menu = mymainmenu}) diff --git a/.config/awesome/module/notifications.lua b/.config/awesome/module/notifications.lua new file mode 100644 index 0000000..a7199ce --- /dev/null +++ b/.config/awesome/module/notifications.lua @@ -0,0 +1,257 @@ +local gears = require('gears') +local wibox = require('wibox') +local awful = require('awful') +local ruled = require('ruled') +local naughty = require('naughty') +local menubar = require('menubar') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +-- Defaults +naughty.config.defaults.ontop = true +naughty.config.defaults.icon_size = dpi(32) +naughty.config.defaults.timeout = 5 +naughty.config.defaults.title = 'System Notification' +naughty.config.defaults.margin = dpi(16) +naughty.config.defaults.border_width = 0 +naughty.config.defaults.position = 'top_right' +naughty.config.defaults.shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, dpi(6)) +end + +-- Apply theme variables +naughty.config.padding = dpi(8) +naughty.config.spacing = dpi(8) +naughty.config.icon_dirs = { + '/usr/share/icons/Tela', + '/usr/share/icons/Tela-blue-dark', + '/usr/share/icons/Papirus/', + '/usr/share/icons/la-capitaine-icon-theme/', + '/usr/share/icons/gnome/', + '/usr/share/icons/hicolor/', + '/usr/share/pixmaps/' +} +naughty.config.icon_formats = { 'svg', 'png', 'jpg', 'gif' } + + +-- Presets / rules + +ruled.notification.connect_signal( + 'request::rules', + function() + + -- Critical notifs + ruled.notification.append_rule { + rule = { urgency = 'critical' }, + properties = { + font = 'Inter Bold 10', + bg = '#ff0000', + fg = '#ffffff', + margin = dpi(16), + position = 'top_right', + implicit_timeout = 0 + } + } + + -- Normal notifs + ruled.notification.append_rule { + rule = { urgency = 'normal' }, + properties = { + font = 'Inter Regular 10', + bg = beautiful.transparent, + fg = beautiful.fg_normal, + margin = dpi(16), + position = 'top_right', + implicit_timeout = 5 + } + } + + -- Low notifs + ruled.notification.append_rule { + rule = { urgency = 'low' }, + properties = { + font = 'Inter Regular 10', + bg = beautiful.transparent, + fg = beautiful.fg_normal, + margin = dpi(16), + position = 'top_right', + implicit_timeout = 5 + } + } + end + ) + +-- Error handling +naughty.connect_signal( + 'request::display_error', + function(message, startup) + naughty.notification { + urgency = 'critical', + title = 'Oops, an error happened'..(startup and ' during startup!' or '!'), + message = message, + app_name = 'System Notification', + icon = beautiful.awesome_icon + } + end +) + +-- XDG icon lookup +naughty.connect_signal( + 'request::icon', + function(n, context, hints) + if context ~= 'app_icon' then return end + + local path = menubar.utils.lookup_icon(hints.app_icon) or + menubar.utils.lookup_icon(hints.app_icon:lower()) + + if path then + n.icon = path + end + end +) + +-- Connect to naughty on display signal +naughty.connect_signal( + 'request::display', + function(n) + + -- Actions Blueprint + local actions_template = wibox.widget { + notification = n, + base_layout = wibox.widget { + spacing = dpi(0), + layout = wibox.layout.flex.horizontal + }, + widget_template = { + { + { + { + { + id = 'text_role', + font = 'Inter Regular 10', + widget = wibox.widget.textbox + }, + widget = wibox.container.place + }, + widget = clickable_container + }, + bg = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + forced_height = dpi(30), + widget = wibox.container.background + }, + margins = dpi(4), + widget = wibox.container.margin + }, + style = { underline_normal = false, underline_selected = true }, + widget = naughty.list.actions + } + + -- Notifbox Blueprint + naughty.layout.box { + notification = n, + type = 'notification', + screen = awful.screen.preferred(), + shape = gears.shape.rectangle, + widget_template = { + { + { + { + { + { + { + { + { + { + { + markup = n.app_name or 'System Notification', + font = 'Inter Bold 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + + }, + margins = beautiful.notification_margin, + widget = wibox.container.margin, + }, + bg = beautiful.background, + widget = wibox.container.background, + }, + { + { + { + resize_strategy = 'center', + widget = naughty.widget.icon, + }, + margins = beautiful.notification_margin, + widget = wibox.container.margin, + }, + { + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + { + align = 'left', + widget = naughty.widget.title + }, + { + align = 'left', + widget = naughty.widget.message, + }, + layout = wibox.layout.fixed.vertical + }, + nil + }, + margins = beautiful.notification_margin, + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + fill_space = true, + spacing = beautiful.notification_margin, + layout = wibox.layout.fixed.vertical, + }, + -- Margin between the fake background + -- Set to 0 to preserve the 'titlebar' effect + margins = dpi(0), + widget = wibox.container.margin, + }, + bg = beautiful.transparent, + widget = wibox.container.background, + }, + -- Actions + actions_template, + spacing = dpi(4), + layout = wibox.layout.fixed.vertical, + }, + bg = beautiful.transparent, + id = 'background_role', + widget = naughty.container.background, + }, + strategy = 'min', + width = dpi(160), + widget = wibox.container.constraint, + }, + strategy = 'max', + width = beautiful.notification_max_width or dpi(500), + widget = wibox.container.constraint + }, + bg = beautiful.background, + shape = gears.shape.rounded_rect, + widget = wibox.container.background + } + } + + -- Destroy popups if dont_disturb mode is on + -- Or if the right_panel is visible + local focused = awful.screen.focused() + if _G.dont_disturb or + (focused.right_panel and focused.right_panel.visible) then + naughty.destroy_all_notifications(nil, 1) + end + + end +) diff --git a/.config/awesome/module/quake-terminal.lua b/.config/awesome/module/quake-terminal.lua new file mode 100644 index 0000000..4bd2ce7 --- /dev/null +++ b/.config/awesome/module/quake-terminal.lua @@ -0,0 +1,112 @@ +local awful = require('awful') +local ruled = require('ruled') +local beautiful = require('beautiful') +local app = require('configuration.apps').default.quake +local client_keys = require('configuration.client.keys') +local client_buttons = require('configuration.client.buttons') +local quake_id = nil +local quake_client = nil +local quake_opened = false + +local quake_properties = function() + return { + skip_decoration = true, + titlebars_enabled = false, + switch_to_tags = false, + opacity = 0.95, + floating = true, + skip_taskbar = true, + ontop = true, + above = true, + sticky = true, + hidden = not quake_opened, + maximized_horizontal = true, + skip_center = true, + round_corners = false, + keys = client_keys, + buttons = client_buttons, + placement = awful.placement.top, + shape = beautiful.client_shape_rectangle + } +end + +ruled.client.connect_signal( + 'request::rules', + function() + ruled.client.append_rule { + id = 'quake_terminal', + rule_any = { + instance = { + 'QuakeTerminal' + } + }, + properties = quake_properties() + } + end +) + +local create_quake = function() + -- Check if there's already an instance of 'QuakeTerminal'. + -- If yes, recover it - use it again. + local quake_term = function (c) + return ruled.client.match(c, {instance = 'QuakeTerminal'}) + end + for c in awful.client.iterate(quake_term) do + -- 'QuakeTerminal' instance detected + -- Re-apply its properties + ruled.client.execute(c, quake_properties()) + quake_id = c.pid + c:emit_signal('request::activate') + return + end + -- No 'QuakeTerminal' instance, spawn one + quake_id = awful.spawn(app, quake_properties()) +end + +local quake_open = function() + quake_client.hidden = false + quake_client:emit_signal('request::activate') +end + +local quake_close = function() + quake_client.hidden = true +end + +local quake_toggle = function() + quake_opened = not quake_opened + if not quake_client then + create_quake() + else + if quake_opened then + quake_open() + else + quake_close() + end + end +end + +awesome.connect_signal( + 'module::quake_terminal:toggle', + function() + quake_toggle(); + end +) + +client.connect_signal( + 'manage', + function(c) + if c.pid == quake_id then + quake_client = c + end + end +) + +client.connect_signal( + 'unmanage', + function(c) + if c.pid == quake_id then + quake_opened = false + quake_client = nil + end + end +) diff --git a/.config/awesome/module/titlebar.lua b/.config/awesome/module/titlebar.lua new file mode 100644 index 0000000..ebf958d --- /dev/null +++ b/.config/awesome/module/titlebar.lua @@ -0,0 +1,278 @@ +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local wibox = require('wibox') +local dpi = beautiful.xresources.apply_dpi +awful.titlebar.enable_tooltip = true +awful.titlebar.fallback_name = 'Client' + +local double_click_event_handler = function(double_click_event) + if double_click_timer then + double_click_timer:stop() + double_click_timer = nil + double_click_event() + return + end + double_click_timer = gears.timer.start_new( + 0.20, + function() + double_click_timer = nil + return false + end + ) +end + +local create_click_events = function(c) + -- Titlebar button/click events + local buttons = gears.table.join( + awful.button( + {}, + 1, + function() + double_click_event_handler(function() + if c.floating then + c.floating = false + return + end + c.maximized = not c.maximized + c:raise() + return + end) + c:activate {context = 'titlebar', action = 'mouse_move'} + end + ), + awful.button( + {}, + 3, + function() + c:activate {context = 'titlebar', action = 'mouse_resize'} + end + ) + ) + return buttons +end + +local create_vertical_bar = function(c, pos, bg, size) + + -- Check if passed position is valid + if (pos == 'top' or pos == 'bottom') then + pos = 'left' + bg = '#FF00FF' + end + + awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup { + { + { + awful.titlebar.widget.closebutton(c), + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.minimizebutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.vertical + }, + margins = dpi(10), + widget = wibox.container.margin + }, + { + buttons = create_click_events(c), + layout = wibox.layout.flex.vertical + }, + { + { + awful.titlebar.widget.ontopbutton(c), + awful.titlebar.widget.floatingbutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.vertical + }, + margins = dpi(10), + widget = wibox.container.margin + }, + layout = wibox.layout.align.vertical + } +end + +local create_horizontal_bar = function(c, pos, bg, size) + + -- Check if passed position is valid + if (pos == 'left' or pos == 'right') then + pos = 'top' + bg = '#FF00FF' + end + + awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup { + { + { + awful.titlebar.widget.closebutton(c), + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.minimizebutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.horizontal + }, + margins = dpi(10), + widget = wibox.container.margin + }, + { + buttons = create_click_events(c), + layout = wibox.layout.flex.horizontal + }, + { + { + awful.titlebar.widget.ontopbutton(c), + awful.titlebar.widget.floatingbutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.horizontal + }, + margins = dpi(10), + widget = wibox.container.margin + }, + layout = wibox.layout.align.horizontal + } +end + +local create_vertical_bar_dialog = function(c, pos, bg, size) + + -- Check if passed position is valid + if (pos == 'top' or pos == 'bottom') then + pos = 'left' + bg = '#FF00FF' + end + + awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup { + { + { + awful.titlebar.widget.closebutton(c), + awful.titlebar.widget.minimizebutton(c), + awful.titlebar.widget.ontopbutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.vertical + }, + margins = dpi(10), + widget = wibox.container.margin + }, + { + buttons = create_click_events(c), + layout = wibox.layout.flex.vertical + }, + nil, + layout = wibox.layout.align.vertical + } +end + +local create_horizontal_bar_dialog = function(c, pos, bg, size) + + -- Check if passed position is valid + if (pos == 'left' or pos == 'right') then + pos = 'top' + bg = '#FF00FF' + end + + awful.titlebar(c, {position = pos, bg = bg, size = size}) : setup { + { + { + awful.titlebar.widget.closebutton(c), + awful.titlebar.widget.ontopbutton(c), + awful.titlebar.widget.minimizebutton(c), + spacing = dpi(7), + layout = wibox.layout.fixed.horizontal + }, + margins = dpi(10), + widget = wibox.container.margin + }, + { + buttons = create_click_events(c), + layout = wibox.layout.flex.horizontal + }, + nil, + layout = wibox.layout.align.horizontal + } +end + +client.connect_signal( + 'request::titlebars', + function(c) + + -- Customize here + if c.type == 'normal' then + + if c.class == 'kitty' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + elseif c.class == 'firefox' then + create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size) + + elseif c.class == 'XTerm' or c.class == 'UXTerm' then + create_horizontal_bar(c, 'top', + beautiful.xresources.get_current_theme().background, beautiful.titlebar_size) + + elseif c.class == 'ark' or c.class == 'dolphin' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + elseif c.instance == 'transmission-qt' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + elseif c.class == 'Gimp-2.10' or c.class == 'Inkscape' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'Com.github.johnfactotum.Foliate' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'Arandr' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'Ettercap' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size) + + elseif c.class == 'Google-chrome' or c.class == 'Chromium' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size) + + elseif c.class == 'TelegramDesktop' then + create_vertical_bar(c, 'left', '#17212b', beautiful.titlebar_size) + + elseif c.class == 'Kvantum Manager' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + elseif c.class == 'qt5ct' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + elseif c.class == 'Nemo' then + create_horizontal_bar(c, 'top', + beautiful.gtk.get_theme_variables().base_color, beautiful.titlebar_size) + + else + create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size) + end + + elseif c.type == 'dialog' then + + if c.role == 'GtkFileChooserDialog' then + create_vertical_bar_dialog(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'firefox' then + create_vertical_bar_dialog(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'Gimp-2.10' then + create_vertical_bar_dialog(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + elseif c.class == 'Arandr' then + create_vertical_bar(c, 'left', + beautiful.gtk.get_theme_variables().bg_color, beautiful.titlebar_size) + + else + create_vertical_bar_dialog(c, 'left', '#00000099', beautiful.titlebar_size) + end + + elseif c.type == 'modal' then + create_vertical_bar(c, 'left', '#00000099', beautiful.titlebar_size) + + else + create_vertical_bar(c, 'left', beautiful.background, beautiful.titlebar_size) + end + end +) diff --git a/.config/awesome/module/volume-osd.lua b/.config/awesome/module/volume-osd.lua new file mode 100644 index 0000000..efcaf26 --- /dev/null +++ b/.config/awesome/module/volume-osd.lua @@ -0,0 +1,268 @@ +local awful = require('awful') +local gears = require('gears') +local wibox = require('wibox') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +local osd_header = wibox.widget { + text = 'Volume', + font = 'Inter Bold 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local osd_value = wibox.widget { + text = '0%', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local slider_osd = wibox.widget { + nil, + { + id = 'vol_osd_slider', + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(2), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +local vol_osd_slider = slider_osd.vol_osd_slider + +vol_osd_slider:connect_signal( + 'property::value', + function() + local volume_level = vol_osd_slider:get_value() + awful.spawn('amixer -D pulse sset Master ' .. volume_level .. '%', false) + + -- Update textbox widget text + osd_value.text = volume_level .. '%' + + -- Update the volume slider if values here change + awesome.emit_signal('widget::volume:update', volume_level) + + if awful.screen.focused().show_vol_osd then + awesome.emit_signal( + 'module::volume_osd:show', + true + ) + end + end +) + +vol_osd_slider:connect_signal( + 'button::press', + function() + awful.screen.focused().show_vol_osd = true + end +) + +vol_osd_slider:connect_signal( + 'mouse::enter', + function() + awful.screen.focused().show_vol_osd = true + end +) + +-- The emit will come from the volume-slider +awesome.connect_signal( + 'module::volume_osd', + function(volume) + vol_osd_slider:set_value(volume) + end +) + +local icon = wibox.widget { + { + image = icons.volume, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin +} + +local volume_slider_osd = wibox.widget { + icon, + slider_osd, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal +} + +local osd_height = dpi(100) +local osd_width = dpi(300) +local osd_margin = dpi(10) + +screen.connect_signal( + 'request::desktop_decoration', + function(s) + local s = s or {} + s.show_vol_osd = false + + -- Create the box + s.volume_osd_overlay = awful.popup { + widget = { + -- Removing this block will cause an error... + }, + ontop = true, + visible = false, + type = 'notification', + screen = s, + height = osd_height, + width = osd_width, + maximum_height = osd_height, + maximum_width = osd_width, + offset = dpi(5), + shape = gears.shape.rectangle, + bg = beautiful.transparent, + preferred_anchors = 'middle', + preferred_positions = {'left', 'right', 'top', 'bottom'} + } + + s.volume_osd_overlay : setup { + { + { + { + layout = wibox.layout.align.horizontal, + expand = 'none', + forced_height = dpi(48), + osd_header, + nil, + osd_value + }, + volume_slider_osd, + layout = wibox.layout.fixed.vertical + }, + left = dpi(24), + right = dpi(24), + widget = wibox.container.margin + }, + bg = beautiful.background, + shape = gears.shape.rounded_rect, + widget = wibox.container.background() + } + + -- Reset timer on mouse hover + s.volume_osd_overlay:connect_signal( + 'mouse::enter', + function() + awful.screen.focused().show_vol_osd = true + awesome.emit_signal('module::volume_osd:rerun') + end + ) + end +) + +local hide_osd = gears.timer { + timeout = 2, + autostart = true, + callback = function() + local focused = awful.screen.focused() + focused.volume_osd_overlay.visible = false + focused.show_vol_osd = false + end +} + +awesome.connect_signal( + 'module::volume_osd:rerun', + function() + if hide_osd.started then + hide_osd:again() + else + hide_osd:start() + end + end +) + +local placement_placer = function() + local focused = awful.screen.focused() + + local right_panel = focused.right_panel + local left_panel = focused.left_panel + local volume_osd = focused.volume_osd_overlay + + if right_panel and left_panel then + if right_panel.visible then + awful.placement.bottom_left( + volume_osd, + { + margins = { + left = osd_margin, + right = 0, + top = 0, + bottom = osd_margin + }, + honor_workarea = true + } + ) + return + end + end + + if right_panel then + if right_panel.visible then + awful.placement.bottom_left( + volume_osd, + { + margins = { + left = osd_margin, + right = 0, + top = 0, + bottom = osd_margin + }, + honor_workarea = true + } + ) + return + end + end + + awful.placement.bottom_right( + volume_osd, + { + margins = { + left = 0, + right = osd_margin, + top = 0, + bottom = osd_margin, + }, + honor_workarea = true + } + ) +end + +awesome.connect_signal( + 'module::volume_osd:show', + function(bool) + placement_placer() + awful.screen.focused().volume_osd_overlay.visible = bool + if bool then + awesome.emit_signal('module::volume_osd:rerun') + awesome.emit_signal( + 'module::brightness_osd:show', + false + ) + else + if hide_osd.started then + hide_osd:stop() + end + end + end +) diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua new file mode 100644 index 0000000..8c0ed00 --- /dev/null +++ b/.config/awesome/rc.lua @@ -0,0 +1,81 @@ +-- ░█▀▀░█░░░█▀█░█▀█░█▀█░█░█ +-- ░█▀▀░█░░░█░█░█▀▀░█▀▀░░█░ +-- ░▀░░░▀▀▀░▀▀▀░▀░░░▀░░░░▀░ +-- Banner generated using `toilet -f pagga AwesomeWM" + +local gears = require('gears') +local beautiful = require('beautiful') +local awful = require('awful') +require('awful.autofocus') + +-- ░█▀▀░█░█░█▀▀░█░░░█░░ +-- ░▀▀█░█▀█░█▀▀░█░░░█░░ +-- ░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀ + +awful.util.shell = 'sh' + +-- ░▀█▀░█░█░█▀▀░█▄█░█▀▀ +-- ░░█░░█▀█░█▀▀░█░█░█▀▀ +-- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀ + +beautiful.init(require('theme')) + +-- ░█░░░█▀█░█░█░█▀█░█░█░▀█▀ +-- ░█░░░█▀█░░█░░█░█░█░█░░█░ +-- ░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░ + +require('layout') + +-- ░█▀▀░█▀█░█▀█░█▀▀░▀█▀░█▀▀░█░█░█▀▄░█▀█░▀█▀░▀█▀░█▀█░█▀█░█▀▀ +-- ░█░░░█░█░█░█░█▀▀░░█░░█░█░█░█░█▀▄░█▀█░░█░░░█░░█░█░█░█░▀▀█ +-- ░▀▀▀░▀▀▀░▀░▀░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀ + +require('configuration.client') +require('configuration.root') +require('configuration.tags') +root.keys(require('configuration.keys.global')) + +-- ░█▄█░█▀█░█▀▄░█░█░█░░░█▀▀░█▀▀ +-- ░█░█░█░█░█░█░█░█░█░░░█▀▀░▀▀█ +-- ░▀░▀░▀▀▀░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀ + +require('module.notifications') +require('module.auto-start') +require('module.exit-screen') +require('module.quake-terminal') +require('module.menu') +require('module.titlebar') +require('module.brightness-osd') +require('module.volume-osd') +require('module.lockscreen') +--require('module.dynamic-wallpaper') + +-- ░█░█░█▀█░█░░░█░░░█▀█░█▀█░█▀█░█▀▀░█▀▄ +-- ░█▄█░█▀█░█░░░█░░░█▀▀░█▀█░█▀▀░█▀▀░█▀▄ +-- ░▀░▀░▀░▀░▀▀▀░▀▀▀░▀░░░▀░▀░▀░░░▀▀▀░▀░▀ + +-- screen.connect_signal( +-- 'request::wallpaper', +-- function(s) +-- -- If wallpaper is a function, call it with the screen +-- if beautiful.wallpaper then +-- if type(beautiful.wallpaper) == 'string' then + +-- -- Check if beautiful.wallpaper is color/image +-- if beautiful.wallpaper:sub(1, #'#') == '#' then +-- -- If beautiful.wallpaper is color +-- gears.wallpaper.set(beautiful.wallpaper) + +-- elseif beautiful.wallpaper:sub(1, #'/') == '/' then +-- -- If beautiful.wallpaper is path/image +-- gears.wallpaper.maximized(beautiful.wallpaper, s) +-- end +-- else +-- beautiful.wallpaper(s) +-- end +-- end +-- end +-- ) +-- +-- #autostart apps +awful.spawn.with_shell('changebg') diff --git a/.config/awesome/rc.lua.bak b/.config/awesome/rc.lua.bak new file mode 100644 index 0000000..eb9d6eb --- /dev/null +++ b/.config/awesome/rc.lua.bak @@ -0,0 +1,78 @@ +-- ░█▀▀░█░░░█▀█░█▀█░█▀█░█░█ +-- ░█▀▀░█░░░█░█░█▀▀░█▀▀░░█░ +-- ░▀░░░▀▀▀░▀▀▀░▀░░░▀░░░░▀░ +-- Banner generated using `toilet -f pagga AwesomeWM" + +local gears = require('gears') +local beautiful = require('beautiful') +local awful = require('awful') +require('awful.autofocus') + +-- ░█▀▀░█░█░█▀▀░█░░░█░░ +-- ░▀▀█░█▀█░█▀▀░█░░░█░░ +-- ░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀ + +awful.util.shell = 'sh' + +-- ░▀█▀░█░█░█▀▀░█▄█░█▀▀ +-- ░░█░░█▀█░█▀▀░█░█░█▀▀ +-- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀ + +beautiful.init(require('theme')) + +-- ░█░░░█▀█░█░█░█▀█░█░█░▀█▀ +-- ░█░░░█▀█░░█░░█░█░█░█░░█░ +-- ░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░ + +require('layout') + +-- ░█▀▀░█▀█░█▀█░█▀▀░▀█▀░█▀▀░█░█░█▀▄░█▀█░▀█▀░▀█▀░█▀█░█▀█░█▀▀ +-- ░█░░░█░█░█░█░█▀▀░░█░░█░█░█░█░█▀▄░█▀█░░█░░░█░░█░█░█░█░▀▀█ +-- ░▀▀▀░▀▀▀░▀░▀░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀ + +require('configuration.client') +require('configuration.root') +require('configuration.tags') +root.keys(require('configuration.keys.global')) + +-- ░█▄█░█▀█░█▀▄░█░█░█░░░█▀▀░█▀▀ +-- ░█░█░█░█░█░█░█░█░█░░░█▀▀░▀▀█ +-- ░▀░▀░▀▀▀░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀ + +require('module.notifications') +require('module.auto-start') +require('module.exit-screen') +require('module.quake-terminal') +require('module.menu') +require('module.titlebar') +require('module.brightness-osd') +require('module.volume-osd') +require('module.lockscreen') +--require('module.dynamic-wallpaper') + +-- ░█░█░█▀█░█░░░█░░░█▀█░█▀█░█▀█░█▀▀░█▀▄ +-- ░█▄█░█▀█░█░░░█░░░█▀▀░█▀█░█▀▀░█▀▀░█▀▄ +-- ░▀░▀░▀░▀░▀▀▀░▀▀▀░▀░░░▀░▀░▀░░░▀▀▀░▀░▀ + +screen.connect_signal( + 'request::wallpaper', + function(s) + -- If wallpaper is a function, call it with the screen + if beautiful.wallpaper then + if type(beautiful.wallpaper) == 'string' then + + -- Check if beautiful.wallpaper is color/image + if beautiful.wallpaper:sub(1, #'#') == '#' then + -- If beautiful.wallpaper is color + gears.wallpaper.set(beautiful.wallpaper) + + elseif beautiful.wallpaper:sub(1, #'/') == '/' then + -- If beautiful.wallpaper is path/image + gears.wallpaper.maximized(beautiful.wallpaper, s) + end + else + beautiful.wallpaper(s) + end + end + end +) diff --git a/.config/awesome/theme/default-theme.lua b/.config/awesome/theme/default-theme.lua new file mode 100644 index 0000000..35b34e7 --- /dev/null +++ b/.config/awesome/theme/default-theme.lua @@ -0,0 +1,219 @@ +local gears = require('gears') +local beautiful = require('beautiful') + +local filesystem = gears.filesystem +local dpi = beautiful.xresources.apply_dpi +local gtk_variable = beautiful.gtk.get_theme_variables + +local theme_dir = filesystem.get_configuration_dir() .. '/theme' +local titlebar_theme = 'stoplight' +local titlebar_icon_path = theme_dir .. '/icons/titlebar/' .. titlebar_theme .. '/' +local tip = titlebar_icon_path + +-- Create theme table +local theme = {} + +-- Font +theme.font = 'Inter Regular 10' +theme.font_bold = 'Inter Bold 10' + +-- Menu icon theme +theme.icon_theme = 'Tela-blue-dark' + +local awesome_overrides = function(theme) + + theme.dir = theme_dir + theme.icons = theme_dir .. '/icons/' + + -- Default wallpaper path + theme.wallpaper = theme.dir .. '/wallpapers/morning-wallpaper.jpg' + + -- Default font + theme.font = 'Inter Regular 10' + + -- Foreground + theme.fg_normal = '#ffffffde' + theme.fg_focus = '#e4e4e4' + theme.fg_urgent = '#CC9393' + + theme.bg_normal = theme.background + theme.bg_focus = '#5a5a5a' + theme.bg_urgent = '#3F3F3F' + + -- System tray + theme.bg_systray = theme.background + theme.systray_icon_spacing = dpi(16) + + -- Titlebar + theme.titlebar_size = dpi(34) + theme.titlebar_bg_focus = gtk_variable().bg_color:sub(1,7) .. '66' + theme.titlebar_bg_normal = gtk_variable().base_color:sub(1,7) .. '66' + theme.titlebar_fg_focus = gtk_variable().fg_color + theme.titlebar_fg_normal = gtk_variable().fg_color + + -- Close Button + theme.titlebar_close_button_normal = tip .. 'close_normal.svg' + theme.titlebar_close_button_focus = tip .. 'close_focus.svg' + + -- Minimize Button + theme.titlebar_minimize_button_normal = tip .. 'minimize_normal.svg' + theme.titlebar_minimize_button_focus = tip .. 'minimize_focus.svg' + + -- Ontop Button + theme.titlebar_ontop_button_normal_inactive = tip .. 'ontop_normal_inactive.svg' + theme.titlebar_ontop_button_focus_inactive = tip .. 'ontop_focus_inactive.svg' + theme.titlebar_ontop_button_normal_active = tip .. 'ontop_normal_active.svg' + theme.titlebar_ontop_button_focus_active = tip .. 'ontop_focus_active.svg' + + -- Sticky Button + theme.titlebar_sticky_button_normal_inactive = tip .. 'sticky_normal_inactive.svg' + theme.titlebar_sticky_button_focus_inactive = tip .. 'sticky_focus_inactive.svg' + theme.titlebar_sticky_button_normal_active = tip .. 'sticky_normal_active.svg' + theme.titlebar_sticky_button_focus_active = tip .. 'sticky_focus_active.svg' + + -- Floating Button + theme.titlebar_floating_button_normal_inactive = tip .. 'floating_normal_inactive.svg' + theme.titlebar_floating_button_focus_inactive = tip .. 'floating_focus_inactive.svg' + theme.titlebar_floating_button_normal_active = tip .. 'floating_normal_active.svg' + theme.titlebar_floating_button_focus_active = tip .. 'floating_focus_active.svg' + + -- Maximized Button + theme.titlebar_maximized_button_normal_inactive = tip .. 'maximized_normal_inactive.svg' + theme.titlebar_maximized_button_focus_inactive = tip .. 'maximized_focus_inactive.svg' + theme.titlebar_maximized_button_normal_active = tip .. 'maximized_normal_active.svg' + theme.titlebar_maximized_button_focus_active = tip .. 'maximized_focus_active.svg' + + -- Hovered Close Button + theme.titlebar_close_button_normal_hover = tip .. 'close_normal_hover.svg' + theme.titlebar_close_button_focus_hover = tip .. 'close_focus_hover.svg' + + -- Hovered Minimize Buttin + theme.titlebar_minimize_button_normal_hover = tip .. 'minimize_normal_hover.svg' + theme.titlebar_minimize_button_focus_hover = tip .. 'minimize_focus_hover.svg' + + -- Hovered Ontop Button + theme.titlebar_ontop_button_normal_inactive_hover = tip .. 'ontop_normal_inactive_hover.svg' + theme.titlebar_ontop_button_focus_inactive_hover = tip .. 'ontop_focus_inactive_hover.svg' + theme.titlebar_ontop_button_normal_active_hover = tip .. 'ontop_normal_active_hover.svg' + theme.titlebar_ontop_button_focus_active_hover = tip .. 'ontop_focus_active_hover.svg' + + -- Hovered Sticky Button + theme.titlebar_sticky_button_normal_inactive_hover = tip .. 'sticky_normal_inactive_hover.svg' + theme.titlebar_sticky_button_focus_inactive_hover = tip .. 'sticky_focus_inactive_hover.svg' + theme.titlebar_sticky_button_normal_active_hover = tip .. 'sticky_normal_active_hover.svg' + theme.titlebar_sticky_button_focus_active_hover = tip .. 'sticky_focus_active_hover.svg' + + -- Hovered Floating Button + theme.titlebar_floating_button_normal_inactive_hover = tip .. 'floating_normal_inactive_hover.svg' + theme.titlebar_floating_button_focus_inactive_hover = tip .. 'floating_focus_inactive_hover.svg' + theme.titlebar_floating_button_normal_active_hover = tip .. 'floating_normal_active_hover.svg' + theme.titlebar_floating_button_focus_active_hover = tip .. 'floating_focus_active_hover.svg' + + -- Hovered Maximized Button + theme.titlebar_maximized_button_normal_inactive_hover = tip .. 'maximized_normal_inactive_hover.svg' + theme.titlebar_maximized_button_focus_inactive_hover = tip .. 'maximized_focus_inactive_hover.svg' + theme.titlebar_maximized_button_normal_active_hover = tip .. 'maximized_normal_active_hover.svg' + theme.titlebar_maximized_button_focus_active_hover = tip .. 'maximized_focus_active_hover.svg' + + -- UI Groups + theme.groups_title_bg = '#ffffff' .. '15' + theme.groups_bg = '#ffffff' .. '10' + theme.groups_radius = dpi(9) + + -- UI events + theme.leave_event = transparent + theme.enter_event = '#ffffff' .. '10' + theme.press_event = '#ffffff' .. '15' + theme.release_event = '#ffffff' .. '10' + + -- Client Decorations + + -- Borders + theme.border_focus = gtk_variable().bg_color + theme.border_normal = gtk_variable().base_color + theme.border_marked = '#CC9393' + theme.border_width = dpi(0) + theme.border_radius = dpi(9) + + -- Decorations + theme.useless_gap = dpi(4) + theme.client_shape_rectangle = gears.shape.rectangle + theme.client_shape_rounded = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, dpi(6)) + end + + -- Menu + theme.menu_font = 'Inter Regular 11' + theme.menu_submenu = '' -- ➤ + + theme.menu_height = dpi(34) + theme.menu_width = dpi(200) + theme.menu_border_width = dpi(20) + theme.menu_bg_focus = theme.accent .. 'CC' + + theme.menu_bg_normal = theme.background:sub(1,7) .. '33' + theme.menu_fg_normal = '#ffffff' + theme.menu_fg_focus = '#ffffff' + theme.menu_border_color = theme.background:sub(1,7) .. '5C' + + -- Tooltips + + theme.tooltip_bg = theme.background + theme.tooltip_border_color = theme.transparent + theme.tooltip_border_width = 0 + theme.tooltip_gaps = dpi(5) + theme.tooltip_shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, dpi(6)) + end + + -- Separators + theme.separator_color = '#f2f2f244' + + -- Layoutbox icons + theme.layout_max = theme.icons .. 'layouts/max.svg' + theme.layout_tile = theme.icons .. 'layouts/tile.svg' + theme.layout_dwindle = theme.icons .. 'layouts/dwindle.svg' + theme.layout_floating = theme.icons .. 'layouts/floating.svg' + + -- Taglist + theme.taglist_bg_empty = theme.background .. '99' + theme.taglist_bg_occupied = '#ffffff' .. '1A' + theme.taglist_bg_urgent = '#E91E63' .. '99' + theme.taglist_bg_focus = theme.background + theme.taglist_spacing = dpi(0) + + -- Tasklist + theme.tasklist_font = 'Inter Regular 10' + theme.tasklist_bg_normal = theme.background .. '99' + theme.tasklist_bg_focus = theme.background + theme.tasklist_bg_urgent = '#E91E63' .. '99' + theme.tasklist_fg_focus = '#DDDDDD' + theme.tasklist_fg_urgent = '#ffffff' + theme.tasklist_fg_normal = '#AAAAAA' + + -- Notification + theme.notification_position = 'top_right' + theme.notification_bg = theme.transparent + theme.notification_margin = dpi(5) + theme.notification_border_width = dpi(0) + theme.notification_border_color = theme.transparent + theme.notification_spacing = dpi(5) + theme.notification_icon_resize_strategy = 'center' + theme.notification_icon_size = dpi(32) + + -- Client Snap Theme + theme.snap_bg = theme.background + theme.snap_shape = gears.shape.rectangle + theme.snap_border_width = dpi(15) + + -- Hotkey popup + theme.hotkeys_font = 'Inter Bold' + theme.hotkeys_description_font = 'Inter Regular Regular' + theme.hotkeys_bg = theme.background + theme.hotkeys_group_margin = dpi(20) +end + +return { + theme = theme, + awesome_overrides = awesome_overrides +} diff --git a/.config/awesome/theme/floppy-theme/init.lua b/.config/awesome/theme/floppy-theme/init.lua new file mode 100644 index 0000000..7124c97 --- /dev/null +++ b/.config/awesome/theme/floppy-theme/init.lua @@ -0,0 +1,52 @@ +local filesystem = require('gears.filesystem') +local theme_dir = filesystem.get_configuration_dir() .. '/theme' + +local theme = {} + +theme.icons = theme_dir .. '/icons/' +theme.font = 'Inter Regular 10' +theme.font_bold = 'Inter Bold 10' + +-- Colorscheme +theme.system_black_dark = '#3D4C5F' +theme.system_black_light = '#56687E' + +theme.system_red_dark = '#EE4F84' +theme.system_red_light = '#F48FB1' + +theme.system_green_dark = '#53E2AE' +theme.system_green_light = '#A1EFD3' + +theme.system_yellow_dark = '#F1FF52' +theme.system_yellow_light = '#F1FA8C' + +theme.system_blue_dark = '#6498EF' +theme.system_blue_light = '#92B6F4' + +theme.system_magenta_dark = '#985EFF' +theme.system_magenta_light = '#BD99FF' + +theme.system_cyan_dark = '#24D1E7' +theme.system_cyan_light = '#87DFEB' + +theme.system_white_dark = '#E5E5E5' +theme.system_white_light = '#F8F8F2' + +-- Accent color +theme.accent = theme.system_blue_dark + +-- Background color +theme.background = '#000000' .. '66' + +-- Transparent +theme.transparent = '#00000000' + +-- Awesome icon +theme.awesome_icon = theme.icons .. 'awesome.svg' + +local awesome_overrides = function(theme) end + +return { + theme = theme, + awesome_overrides = awesome_overrides +} diff --git a/.config/awesome/theme/icons/awesome.svg b/.config/awesome/theme/icons/awesome.svg new file mode 100644 index 0000000..31d715c --- /dev/null +++ b/.config/awesome/theme/icons/awesome.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/battery-charge.svg b/.config/awesome/theme/icons/battery-charge.svg new file mode 100644 index 0000000..f8efe9c --- /dev/null +++ b/.config/awesome/theme/icons/battery-charge.svg @@ -0,0 +1,58 @@ + +image/svg+xml + + + + \ No newline at end of file diff --git a/.config/awesome/theme/icons/battery-discharge.svg b/.config/awesome/theme/icons/battery-discharge.svg new file mode 100644 index 0000000..908ce15 --- /dev/null +++ b/.config/awesome/theme/icons/battery-discharge.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/brightness-7.svg b/.config/awesome/theme/icons/brightness-7.svg new file mode 100644 index 0000000..862549e --- /dev/null +++ b/.config/awesome/theme/icons/brightness-7.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/chart-areaspline.svg b/.config/awesome/theme/icons/chart-areaspline.svg new file mode 100644 index 0000000..58bf0d3 --- /dev/null +++ b/.config/awesome/theme/icons/chart-areaspline.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/close.svg b/.config/awesome/theme/icons/close.svg new file mode 100644 index 0000000..bd89d79 --- /dev/null +++ b/.config/awesome/theme/icons/close.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/effects.svg b/.config/awesome/theme/icons/effects.svg new file mode 100644 index 0000000..e6c514b --- /dev/null +++ b/.config/awesome/theme/icons/effects.svg @@ -0,0 +1,91 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/harddisk.svg b/.config/awesome/theme/icons/harddisk.svg new file mode 100644 index 0000000..4c23f54 --- /dev/null +++ b/.config/awesome/theme/icons/harddisk.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/init.lua b/.config/awesome/theme/icons/init.lua new file mode 100644 index 0000000..5cf636b --- /dev/null +++ b/.config/awesome/theme/icons/init.lua @@ -0,0 +1,42 @@ +-- Icons directory +local dir = os.getenv('HOME') .. '/.config/awesome/theme/icons/' + + +return { + + -- Action Bar + web_browser = dir .. 'tag-list/' .. 'web-browser.svg', + text_editor = dir .. 'tag-list/' .. 'text-editor.svg', + social = dir .. 'tag-list/' .. 'social.svg', + file_manager = dir .. 'tag-list/' .. 'file-manager.svg', + multimedia = dir .. 'tag-list/' .. 'multimedia.svg', + games = dir .. 'tag-list/' .. 'games.svg', + development = dir .. 'tag-list/' .. 'development.svg', + sandbox = dir .. 'tag-list/' .. 'sandbox.svg', + terminal = dir .. 'tag-list/' .. 'terminal.svg', + graphics = dir .. 'tag-list/' .. 'graphics.svg', + menu = dir .. 'tag-list/' .. 'menu.svg', + close_small = dir .. 'tag-list/' .. 'close-small.svg', + + -- Others/System UI + close = dir .. 'close.svg', + logout = dir .. 'logout.svg', + sleep = dir .. 'power-sleep.svg', + power = dir .. 'power.svg', + lock = dir .. 'lock.svg', + restart = dir .. 'restart.svg', + search = dir .. 'magnify.svg', + volume = dir .. 'volume-high.svg', + brightness = dir .. 'brightness-7.svg', + effects = dir .. 'effects.svg', + chart = dir .. 'chart-areaspline.svg', + memory = dir .. 'memory.svg', + harddisk = dir .. 'harddisk.svg', + thermometer = dir .. 'thermometer.svg', + plus = dir .. 'plus.svg', + batt_charging = dir .. 'battery-charge.svg', + batt_discharging = dir .. 'battery-discharge.svg', + toggled_on = dir .. 'toggled-on.svg', + toggled_off = dir .. 'toggled-off.svg' + +} diff --git a/.config/awesome/theme/icons/layouts/dwindle.svg b/.config/awesome/theme/icons/layouts/dwindle.svg new file mode 100644 index 0000000..9e59058 --- /dev/null +++ b/.config/awesome/theme/icons/layouts/dwindle.svg @@ -0,0 +1,64 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/layouts/floating.svg b/.config/awesome/theme/icons/layouts/floating.svg new file mode 100644 index 0000000..5dcd846 --- /dev/null +++ b/.config/awesome/theme/icons/layouts/floating.svg @@ -0,0 +1,64 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/layouts/fullscreen.svg b/.config/awesome/theme/icons/layouts/fullscreen.svg new file mode 100644 index 0000000..6ba320b --- /dev/null +++ b/.config/awesome/theme/icons/layouts/fullscreen.svg @@ -0,0 +1,62 @@ + + + + + + + image/svg+xml + + + + + + + + diff --git a/.config/awesome/theme/icons/layouts/max.svg b/.config/awesome/theme/icons/layouts/max.svg new file mode 100644 index 0000000..f1b2b2d --- /dev/null +++ b/.config/awesome/theme/icons/layouts/max.svg @@ -0,0 +1,62 @@ + + + + + + + image/svg+xml + + + + + + + + diff --git a/.config/awesome/theme/icons/layouts/tile.svg b/.config/awesome/theme/icons/layouts/tile.svg new file mode 100644 index 0000000..ea62c5d --- /dev/null +++ b/.config/awesome/theme/icons/layouts/tile.svg @@ -0,0 +1,64 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/lock.svg b/.config/awesome/theme/icons/lock.svg new file mode 100644 index 0000000..ac383ed --- /dev/null +++ b/.config/awesome/theme/icons/lock.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/logout.svg b/.config/awesome/theme/icons/logout.svg new file mode 100644 index 0000000..4689c49 --- /dev/null +++ b/.config/awesome/theme/icons/logout.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/magnify.svg b/.config/awesome/theme/icons/magnify.svg new file mode 100644 index 0000000..40d9c1a --- /dev/null +++ b/.config/awesome/theme/icons/magnify.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/memory.svg b/.config/awesome/theme/icons/memory.svg new file mode 100644 index 0000000..0cf4b10 --- /dev/null +++ b/.config/awesome/theme/icons/memory.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/plus.svg b/.config/awesome/theme/icons/plus.svg new file mode 100644 index 0000000..737cad4 --- /dev/null +++ b/.config/awesome/theme/icons/plus.svg @@ -0,0 +1,58 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/power-sleep.svg b/.config/awesome/theme/icons/power-sleep.svg new file mode 100644 index 0000000..a4dbfc0 --- /dev/null +++ b/.config/awesome/theme/icons/power-sleep.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/power.svg b/.config/awesome/theme/icons/power.svg new file mode 100644 index 0000000..770943b --- /dev/null +++ b/.config/awesome/theme/icons/power.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/restart.svg b/.config/awesome/theme/icons/restart.svg new file mode 100644 index 0000000..f0c3367 --- /dev/null +++ b/.config/awesome/theme/icons/restart.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/ship-wheel.svg b/.config/awesome/theme/icons/ship-wheel.svg new file mode 100644 index 0000000..5237ed3 --- /dev/null +++ b/.config/awesome/theme/icons/ship-wheel.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/close-small.svg b/.config/awesome/theme/icons/tag-list/close-small.svg new file mode 100644 index 0000000..f244bae --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/close-small.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/development.svg b/.config/awesome/theme/icons/tag-list/development.svg new file mode 100644 index 0000000..773a538 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/development.svg @@ -0,0 +1,174 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/file-manager.svg b/.config/awesome/theme/icons/tag-list/file-manager.svg new file mode 100644 index 0000000..ba04747 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/file-manager.svg @@ -0,0 +1,138 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/games.svg b/.config/awesome/theme/icons/tag-list/games.svg new file mode 100644 index 0000000..6314387 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/games.svg @@ -0,0 +1,103 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/graphics.svg b/.config/awesome/theme/icons/tag-list/graphics.svg new file mode 100644 index 0000000..caefefb --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/graphics.svg @@ -0,0 +1,150 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/menu.svg b/.config/awesome/theme/icons/tag-list/menu.svg new file mode 100644 index 0000000..c95ecd7 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/menu.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/menu2.svg b/.config/awesome/theme/icons/tag-list/menu2.svg new file mode 100644 index 0000000..3e82e3d --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/menu2.svg @@ -0,0 +1,123 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/multimedia.svg b/.config/awesome/theme/icons/tag-list/multimedia.svg new file mode 100644 index 0000000..ff5f5b0 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/multimedia.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/sandbox.svg b/.config/awesome/theme/icons/tag-list/sandbox.svg new file mode 100644 index 0000000..67c1921 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/sandbox.svg @@ -0,0 +1,80 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/social.svg b/.config/awesome/theme/icons/tag-list/social.svg new file mode 100644 index 0000000..7217709 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/social.svg @@ -0,0 +1,92 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/terminal.svg b/.config/awesome/theme/icons/tag-list/terminal.svg new file mode 100644 index 0000000..3c4fc1f --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/terminal.svg @@ -0,0 +1,101 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/text-editor.svg b/.config/awesome/theme/icons/tag-list/text-editor.svg new file mode 100644 index 0000000..4aa63b8 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/text-editor.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/tag-list/web-browser.svg b/.config/awesome/theme/icons/tag-list/web-browser.svg new file mode 100644 index 0000000..4b97514 --- /dev/null +++ b/.config/awesome/theme/icons/tag-list/web-browser.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/thermometer.svg b/.config/awesome/theme/icons/thermometer.svg new file mode 100644 index 0000000..5c25a1e --- /dev/null +++ b/.config/awesome/theme/icons/thermometer.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg b/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg new file mode 100644 index 0000000..a245e7d --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/close_focus.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg new file mode 100644 index 0000000..fa1eddd --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/close_focus_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg b/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/close_normal.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg new file mode 100644 index 0000000..fa1eddd --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/close_normal_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg new file mode 100644 index 0000000..262337e --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg new file mode 100644 index 0000000..944a695 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg new file mode 100644 index 0000000..262337e --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg new file mode 100644 index 0000000..944a695 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_focus_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg new file mode 100644 index 0000000..944a695 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg new file mode 100644 index 0000000..944a695 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/floating_normal_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg new file mode 100644 index 0000000..8d22f56 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg new file mode 100644 index 0000000..fbfb447 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg new file mode 100644 index 0000000..8d22f56 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg new file mode 100644 index 0000000..fbfb447 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_focus_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg new file mode 100644 index 0000000..fbfb447 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg new file mode 100644 index 0000000..fbfb447 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/maximized_normal_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg new file mode 100644 index 0000000..0e5bebc --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg new file mode 100644 index 0000000..1414c2b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_focus_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg new file mode 100644 index 0000000..1414c2b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/minimize_normal_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg new file mode 100644 index 0000000..7493249 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg new file mode 100644 index 0000000..94e2ac7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg new file mode 100644 index 0000000..7493249 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg new file mode 100644 index 0000000..94e2ac7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_focus_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg new file mode 100644 index 0000000..94e2ac7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg new file mode 100644 index 0000000..94e2ac7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/ontop_normal_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg new file mode 100644 index 0000000..321d316 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg new file mode 100644 index 0000000..ad33389 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg new file mode 100644 index 0000000..321d316 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg new file mode 100644 index 0000000..ad33389 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_focus_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg new file mode 100644 index 0000000..ad33389 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_active_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg new file mode 100644 index 0000000..c2337bb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg new file mode 100644 index 0000000..ad33389 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/blocks/sticky_normal_inactive_hover.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/close_focus.svg b/.config/awesome/theme/icons/titlebar/lines/close_focus.svg new file mode 100644 index 0000000..85b31ec --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/close_focus.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg new file mode 100644 index 0000000..40aa9e1 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/close_focus_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/close_normal.svg b/.config/awesome/theme/icons/titlebar/lines/close_normal.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/close_normal.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg new file mode 100644 index 0000000..40aa9e1 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/close_normal_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg new file mode 100644 index 0000000..11b9bac --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg new file mode 100644 index 0000000..325c24a --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg new file mode 100644 index 0000000..11b9bac --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg new file mode 100644 index 0000000..779539e --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_focus_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg new file mode 100644 index 0000000..7286450 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg new file mode 100644 index 0000000..1441ea4 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/floating_normal_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg new file mode 100644 index 0000000..6891963 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg new file mode 100644 index 0000000..77f0650 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg new file mode 100644 index 0000000..6891963 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg new file mode 100644 index 0000000..77f0650 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_focus_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg new file mode 100644 index 0000000..77f0650 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg new file mode 100644 index 0000000..77f0650 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/maximized_normal_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg new file mode 100644 index 0000000..abe6ebb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/minimize_focus.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg new file mode 100644 index 0000000..49619d8 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/minimize_focus_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/minimize_normal.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg new file mode 100644 index 0000000..49619d8 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/minimize_normal_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg new file mode 100644 index 0000000..ed4ecfd --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg new file mode 100644 index 0000000..81e15d9 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg new file mode 100644 index 0000000..ed4ecfd --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg new file mode 100644 index 0000000..81e15d9 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_focus_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg new file mode 100644 index 0000000..81e15d9 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg new file mode 100644 index 0000000..81e15d9 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/ontop_normal_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg new file mode 100644 index 0000000..2945c0f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg new file mode 100644 index 0000000..2cef61b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg new file mode 100644 index 0000000..2945c0f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg new file mode 100644 index 0000000..2cef61b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_focus_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg new file mode 100644 index 0000000..2cef61b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_active_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg new file mode 100644 index 0000000..972d88f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg new file mode 100644 index 0000000..2cef61b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/lines/sticky_normal_inactive_hover.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg new file mode 100644 index 0000000..8b63331 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/close_focus.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg new file mode 100644 index 0000000..2d77a2f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/close_focus_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/close_normal.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg new file mode 100644 index 0000000..2d77a2f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/close_normal_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg new file mode 100644 index 0000000..ae9727f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg new file mode 100644 index 0000000..2faad37 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg new file mode 100644 index 0000000..ae9727f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg new file mode 100644 index 0000000..2faad37 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_focus_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg new file mode 100644 index 0000000..2faad37 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg new file mode 100644 index 0000000..2faad37 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/floating_normal_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg new file mode 100644 index 0000000..e522d74 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg new file mode 100644 index 0000000..7a5c055 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg new file mode 100644 index 0000000..e522d74 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg new file mode 100644 index 0000000..7a5c055 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_focus_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg new file mode 100644 index 0000000..7a5c055 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg new file mode 100644 index 0000000..7a5c055 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/maximized_normal_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg new file mode 100644 index 0000000..215d91c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg new file mode 100644 index 0000000..282d8b0 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_focus_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg new file mode 100644 index 0000000..282d8b0 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/minimize_normal_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg new file mode 100644 index 0000000..432f74f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg new file mode 100644 index 0000000..a3da6d2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg new file mode 100644 index 0000000..432f74f --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg new file mode 100644 index 0000000..a3da6d2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_focus_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg new file mode 100644 index 0000000..a3da6d2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg new file mode 100644 index 0000000..a3da6d2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/ontop_normal_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg new file mode 100644 index 0000000..47248cb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg new file mode 100644 index 0000000..fe22df2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg new file mode 100644 index 0000000..47248cb --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg new file mode 100644 index 0000000..fe22df2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_focus_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg new file mode 100644 index 0000000..fe22df2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_active_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg new file mode 100644 index 0000000..6acee08 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg new file mode 100644 index 0000000..fe22df2 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/stoplight/sticky_normal_inactive_hover.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/close_focus.svg b/.config/awesome/theme/icons/titlebar/win10/close_focus.svg new file mode 100644 index 0000000..d1bc232 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/close_focus.svg @@ -0,0 +1,116 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/close_normal.svg b/.config/awesome/theme/icons/titlebar/win10/close_normal.svg new file mode 100644 index 0000000..d013ac8 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/close_normal.svg @@ -0,0 +1,114 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg b/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg new file mode 100644 index 0000000..d1bc232 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/close_normal_hover.svg @@ -0,0 +1,116 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_active_hover.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_focus_inactive_hover.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg new file mode 100644 index 0000000..6f0faf1 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active.svg @@ -0,0 +1,108 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_active_hover.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg new file mode 100644 index 0000000..6f0faf1 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive.svg @@ -0,0 +1,108 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg new file mode 100644 index 0000000..cdda009 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/floating_normal_inactive_hover.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_active_hover.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_focus_inactive_hover.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg new file mode 100644 index 0000000..d9dea80 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active.svg @@ -0,0 +1,113 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_active_hover.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg new file mode 100644 index 0000000..d9dea80 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive.svg @@ -0,0 +1,113 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg new file mode 100644 index 0000000..6b6452c --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/maximized_normal_inactive_hover.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg new file mode 100644 index 0000000..b8a5cc7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/minimize_focus.svg @@ -0,0 +1,107 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg new file mode 100644 index 0000000..b8a5cc7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/minimize_focus_hover.svg @@ -0,0 +1,107 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg new file mode 100644 index 0000000..a3efb9b --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/minimize_normal.svg @@ -0,0 +1,119 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg b/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg new file mode 100644 index 0000000..b8a5cc7 --- /dev/null +++ b/.config/awesome/theme/icons/titlebar/win10/minimize_normal_hover.svg @@ -0,0 +1,107 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/icons/toggled-off.svg b/.config/awesome/theme/icons/toggled-off.svg new file mode 100644 index 0000000..a73de49 --- /dev/null +++ b/.config/awesome/theme/icons/toggled-off.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/toggled-on.svg b/.config/awesome/theme/icons/toggled-on.svg new file mode 100644 index 0000000..a75ef1c --- /dev/null +++ b/.config/awesome/theme/icons/toggled-on.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/theme/icons/volume-high.svg b/.config/awesome/theme/icons/volume-high.svg new file mode 100644 index 0000000..7a59aa1 --- /dev/null +++ b/.config/awesome/theme/icons/volume-high.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/theme/init.lua b/.config/awesome/theme/init.lua new file mode 100644 index 0000000..23b0af5 --- /dev/null +++ b/.config/awesome/theme/init.lua @@ -0,0 +1,12 @@ +local gtable = require('gears.table') +local default_theme = require('theme.default-theme') +-- PICK THEME HERE +local theme = require('theme.floppy-theme') + +local final_theme = {} +gtable.crush(final_theme, default_theme.theme) +gtable.crush(final_theme, theme.theme) +default_theme.awesome_overrides(final_theme) +theme.awesome_overrides(final_theme) + +return final_theme diff --git a/.config/awesome/theme/wallpapers/AUTHORS b/.config/awesome/theme/wallpapers/AUTHORS new file mode 100644 index 0000000..7de152e --- /dev/null +++ b/.config/awesome/theme/wallpapers/AUTHORS @@ -0,0 +1,9 @@ +The images are not mine. Links here: + +https://wall.alphacoders.com/big.php?i=988615 +https://wall.alphacoders.com/big.php?i=725593 +https://wall.alphacoders.com/big.php?i=863809 +https://wall.alphacoders.com/big.php?i=743289 +https://wall.alphacoders.com/big.php?i=805656 +https://hdqwalls.com/wallpaper/2560x1440/no-mans-sky-game-2019-4k +https://www.pinterest.ph/pin/216313588332943910/ diff --git a/.config/awesome/theme/wallpapers/locksreen-bg.jpg b/.config/awesome/theme/wallpapers/locksreen-bg.jpg new file mode 100644 index 0000000..b0c4d57 Binary files /dev/null and b/.config/awesome/theme/wallpapers/locksreen-bg.jpg differ diff --git a/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg b/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg new file mode 100644 index 0000000..0a50832 Binary files /dev/null and b/.config/awesome/theme/wallpapers/midnight-wallpaper.jpg differ diff --git a/.config/awesome/theme/wallpapers/morning-wallpaper.jpg b/.config/awesome/theme/wallpapers/morning-wallpaper.jpg new file mode 100644 index 0000000..f9063dd Binary files /dev/null and b/.config/awesome/theme/wallpapers/morning-wallpaper.jpg differ diff --git a/.config/awesome/theme/wallpapers/night-wallpaper.jpg b/.config/awesome/theme/wallpapers/night-wallpaper.jpg new file mode 100644 index 0000000..95408ec Binary files /dev/null and b/.config/awesome/theme/wallpapers/night-wallpaper.jpg differ diff --git a/.config/awesome/theme/wallpapers/noon-wallpaper.jpg b/.config/awesome/theme/wallpapers/noon-wallpaper.jpg new file mode 100644 index 0000000..81382cb Binary files /dev/null and b/.config/awesome/theme/wallpapers/noon-wallpaper.jpg differ diff --git a/.config/awesome/utilities/profile-image b/.config/awesome/utilities/profile-image new file mode 100755 index 0000000..350c9ea --- /dev/null +++ b/.config/awesome/utilities/profile-image @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Depends: Mugshot +# Written by manilarome + +awesome_dir="${HOME}/.config/awesome/" +user_profile_dir="${awesome_dir}/configuration/user-profile/" + +accountsservice_user_icons="/var/lib/AccountsService/icons/${USER}" + +# Check if user image exists +if [ -f "${user_profile_dir}${USER}.png" ]; +then + if [ -f "${accountsservice_user_icons}" ]; + then + if ! cmp --silent "${user_profile_dir}${USER}.png" "${accountsservice_user_icons}"; + then + cp "${accountsservice_user_icons}" "${user_profile_dir}${USER}.png" + fi + printf "${user_profile_dir}${USER}.png" + else + printf "${user_profile_dir}${USER}.png" + fi + exit; +else + if [ -f "${accountsservice_user_icons}" ]; + then + cp "${accountsservice_user_icons}" "${user_profile_dir}${USER}.png" + printf "${user_profile_dir}${USER}.png" + exit; + else + printf "default" + exit; + fi +fi \ No newline at end of file diff --git a/.config/awesome/utilities/snap b/.config/awesome/utilities/snap new file mode 100755 index 0000000..970cee2 --- /dev/null +++ b/.config/awesome/utilities/snap @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +# ---------------------------------------------------------------------------- +# --- Simple screenshot script using maim and AwesomeWM API +# -- +# -- Accepts `area` and `full` string args +# -- +# -- For more details check `man maim` +# -- +# -- @author manilarome <gerome.matilla07@gmail.com> +# -- @copyright 2020 manilarome +# -- @script snap +# ---------------------------------------------------------------------------- + +screenshot_dir=$(xdg-user-dir PICTURES)/Screenshots/ + +# Check save directory +# Create it if it doesn't exist +function check_dir() { + if [ ! -d "$screenshot_dir" ]; + then + mkdir -p "$screenshot_dir" + fi +} + +# Main function +function shot() { + + check_dir + + file_loc="${screenshot_dir}$(date +%Y%m%d_%H%M%S).png" + + maim_command="$1" + notif_message="$2" + + # Execute maim command + ${maim_command} "${file_loc}" + + # Exit if the user cancels the screenshot + # So it means there's no new screenshot image file + if [ ! -f "${file_loc}" ]; + then + exit; + fi + + # Copy to clipboard + xclip -selection clipboard -t image/png -i "${screenshot_dir}"/`ls -1 -t "${screenshot_dir}" | head -1` & + + awesome-client " + + -- IMPORTANT NOTE: THIS PART OF THE SCRIPT IS LUA! + naughty = require('naughty') + awful = require('awful') + beautiful = require('beautiful') + dpi = beautiful.xresources.apply_dpi + + local open_image = naughty.action { + name = 'Open', + icon_only = false, + } + + local open_folder = naughty.action { + name = 'Open Folder', + icon_only = false, + } + + local delete_image = naughty.action { + name = 'Delete', + icon_only = false, + } + + -- Execute the callback when 'Open' is pressed + open_image:connect_signal('invoked', function() + awful.spawn('xdg-open ' .. '${file_loc}', false) + end) + + open_folder:connect_signal('invoked', function() + awful.spawn('xdg-open ' .. '${screenshot_dir}', false) + end) + + -- Execute the callback when 'Delete' is pressed + delete_image:connect_signal('invoked', function() + awful.spawn('gio trash ' .. '${file_loc}', false) + end) + + -- Show notification + naughty.notification ({ + app_name = 'Screenshot Tool', + icon = '${file_loc}', + timeout = 10, + title = 'Snap!', + message = '${notif_message}', + actions = { open_image, open_folder, delete_image } + }) + " + +} + +# Check the args passed +if [ -z "$1" ] || ([ "$1" != 'full' ] && [ "$1" != 'area' ]); +then + echo " + Requires an argument: + area - Area screenshot + full - Fullscreen screenshot + + Example: + ./snap area + ./snap full + " +elif [ "$1" = 'full' ]; +then + msg="Full screenshot saved and copied to clipboard!" + shot 'maim -u -m 1' "${msg}" +elif [ "$1" = 'area' ]; +then + msg='Area screenshot saved and copied to clipboard!' + shot 'maim -u -s -n -m 1' "${msg}" +fi + diff --git a/.config/awesome/widget/airplane-mode/airplane_mode b/.config/awesome/widget/airplane-mode/airplane_mode new file mode 100644 index 0000000..c508d53 --- /dev/null +++ b/.config/awesome/widget/airplane-mode/airplane_mode @@ -0,0 +1 @@ +false diff --git a/.config/awesome/widget/airplane-mode/clickable-container.lua b/.config/awesome/widget/airplane-mode/clickable-container.lua new file mode 100755 index 0000000..f531740 --- /dev/null +++ b/.config/awesome/widget/airplane-mode/clickable-container.lua @@ -0,0 +1,35 @@ +local wibox = require('wibox') + +function build(widget) + local container = + wibox.widget { + widget, + widget = wibox.container.background, + } + local old_cursor, old_wibox + container:connect_signal( + 'mouse::enter', + function() + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + container:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + return container +end + +return build diff --git a/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg b/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg new file mode 100644 index 0000000..7a4c91c --- /dev/null +++ b/.config/awesome/widget/airplane-mode/icons/airplane-mode-off.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg b/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg new file mode 100644 index 0000000..70fc89d --- /dev/null +++ b/.config/awesome/widget/airplane-mode/icons/airplane-mode.svg @@ -0,0 +1,62 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/airplane-mode/init.lua b/.config/awesome/widget/airplane-mode/init.lua new file mode 100755 index 0000000..1a15c86 --- /dev/null +++ b/.config/awesome/widget/airplane-mode/init.lua @@ -0,0 +1,169 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local watch = awful.widget.watch +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.airplane-mode.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_dir = config_dir .. 'widget/airplane-mode/' +local widget_icon_dir = widget_dir .. 'icons/' +local icons = require('theme.icons') +local ap_state = false + +local action_name = wibox.widget { + text = 'Airplane Mode', + font = 'Inter Regular 11', + align = 'left', + widget = wibox.widget.textbox +} + +local button_widget = wibox.widget { + { + id = 'icon', + image = icons.toggled_off, + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal +} + +local widget_button = wibox.widget { + { + button_widget, + top = dpi(7), + bottom = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +local update_imagebox = function() + if ap_state then + button_widget.icon:set_image(icons.toggled_on) + else + button_widget.icon:set_image(icons.toggled_off) + end +end + +local check_airplane_mode_state = function() + + local cmd = 'cat ' .. widget_dir .. 'airplane_mode' + + awful.spawn.easy_async_with_shell( + cmd, + function(stdout) + local status = stdout + + if status:match("true") then + ap_state = true + elseif status:match("false") then + ap_state = false + else + ap_state = false + awful.spawn.easy_async_with_shell( + 'echo "false" > ' .. widget_dir .. 'airplane_mode', + function(stdout) + end + ) + end + + update_imagebox() + end + ) +end + +check_airplane_mode_state() + +local ap_off_cmd = [[ + + rfkill unblock wlan + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Network Manager', + title = 'Airplane mode disabled!', + message = 'Initializing network devices', + icon = ']] .. widget_icon_dir .. 'airplane-mode-off' .. '.svg' .. [[' + }) + " + ]] .. "echo false > " .. widget_dir .. "airplane_mode" .. [[ +]] + +local ap_on_cmd = [[ + + rfkill block wlan + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Network Manager', + title = 'Airplane mode enabled!', + message = 'Disabling radio devices', + icon = ']] .. widget_icon_dir .. 'airplane-mode' .. '.svg' .. [[' + }) + " + ]] .. "echo true > " .. widget_dir .. "airplane_mode" .. [[ +]] + + +local toggle_action = function() + if ap_state then + awful.spawn.easy_async_with_shell( + ap_off_cmd, + function(stdout) + ap_state = false + update_imagebox() + end + ) + else + awful.spawn.easy_async_with_shell( + ap_on_cmd, + function(stdout) + ap_state = true + update_imagebox() + end + ) + end +end + +widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_action() + end + ) + ) +) + +gears.timer { + timeout = 5, + autostart = true, + callback = function() + check_airplane_mode_state() + end +} + +local action_widget = wibox.widget { + { + action_name, + nil, + { + widget_button, + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.horizontal, + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return action_widget diff --git a/.config/awesome/widget/battery/icons/battery-alert-red.svg b/.config/awesome/widget/battery/icons/battery-alert-red.svg new file mode 100644 index 0000000..469b0ba --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-alert-red.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-alert.svg b/.config/awesome/widget/battery/icons/battery-alert.svg new file mode 100644 index 0000000..6ec71c1 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-alert.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-10.svg b/.config/awesome/widget/battery/icons/battery-charging-10.svg new file mode 100644 index 0000000..4de288a --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-10.svg @@ -0,0 +1,75 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-20.svg b/.config/awesome/widget/battery/icons/battery-charging-20.svg new file mode 100644 index 0000000..af759b5 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-20.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-30.svg b/.config/awesome/widget/battery/icons/battery-charging-30.svg new file mode 100644 index 0000000..f721545 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-30.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-50.svg b/.config/awesome/widget/battery/icons/battery-charging-50.svg new file mode 100644 index 0000000..42bb375 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-50.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-60.svg b/.config/awesome/widget/battery/icons/battery-charging-60.svg new file mode 100644 index 0000000..4057d33 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-60.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-80.svg b/.config/awesome/widget/battery/icons/battery-charging-80.svg new file mode 100644 index 0000000..5febc30 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-80.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-charging-90.svg b/.config/awesome/widget/battery/icons/battery-charging-90.svg new file mode 100644 index 0000000..544aa5d --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-charging-90.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-100.svg b/.config/awesome/widget/battery/icons/battery-discharging-100.svg new file mode 100644 index 0000000..b3d3337 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-100.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-20.svg b/.config/awesome/widget/battery/icons/battery-discharging-20.svg new file mode 100644 index 0000000..116a7f9 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-20.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-30.svg b/.config/awesome/widget/battery/icons/battery-discharging-30.svg new file mode 100644 index 0000000..d1f4463 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-30.svg @@ -0,0 +1,71 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-50.svg b/.config/awesome/widget/battery/icons/battery-discharging-50.svg new file mode 100644 index 0000000..8dca81e --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-50.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-60.svg b/.config/awesome/widget/battery/icons/battery-discharging-60.svg new file mode 100644 index 0000000..25eaca0 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-60.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-80.svg b/.config/awesome/widget/battery/icons/battery-discharging-80.svg new file mode 100644 index 0000000..5612658 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-80.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-discharging-90.svg b/.config/awesome/widget/battery/icons/battery-discharging-90.svg new file mode 100644 index 0000000..d11ab44 --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-discharging-90.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-fully-charged.svg b/.config/awesome/widget/battery/icons/battery-fully-charged.svg new file mode 100644 index 0000000..7e923fc --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-fully-charged.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery-unknown.svg b/.config/awesome/widget/battery/icons/battery-unknown.svg new file mode 100644 index 0000000..ad67bdf --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery-unknown.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/icons/battery.svg b/.config/awesome/widget/battery/icons/battery.svg new file mode 100644 index 0000000..adba7ac --- /dev/null +++ b/.config/awesome/widget/battery/icons/battery.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/battery/init.lua b/.config/awesome/widget/battery/init.lua new file mode 100644 index 0000000..ca0c3de --- /dev/null +++ b/.config/awesome/widget/battery/init.lua @@ -0,0 +1,209 @@ +local awful = require('awful') +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local naughty = require('naughty') +local watch = awful.widget.watch +local apps = require('configuration.apps') +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/battery/icons/' + +local return_button = function() + + local battery_imagebox = wibox.widget { + nil, + { + id = 'icon', + image = widget_icon_dir .. 'battery' .. '.svg', + widget = wibox.widget.imagebox, + resize = true + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical + } + + local battery_percentage_text = wibox.widget { + id = 'percent_text', + text = '100%', + font = 'Inter Bold 11', + align = 'center', + valign = 'center', + visible = false, + widget = wibox.widget.textbox + } + + + local battery_widget = wibox.widget { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(0), + battery_imagebox, + battery_percentage_text + } + + + local battery_button = wibox.widget { + { + battery_widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + battery_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn(apps.default.power_manager , false) + end + ) + ) + ) + + local battery_tooltip = awful.tooltip { + objects = {battery_button}, + text = 'None', + mode = 'outside', + align = 'right', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'right', 'left', 'top', 'bottom'} + } + + + local get_battery_info = function() + awful.spawn.easy_async_with_shell( + 'upower -i $(upower -e | grep BAT)', + function(stdout) + if stdout == nil or stdout == '' then + battery_tooltip:set_text('No battery detected!') + return + end + + -- Remove new line from the last line + battery_tooltip:set_text(stdout:sub(1, -2)) + end + ) + end + get_battery_info() + + battery_widget:connect_signal( + 'mouse::enter', + function() + get_battery_info() + end + ) + + local last_battery_check = os.time() + local notify_critcal_battery = true + + local show_battery_warning = function() + naughty.notification ({ + icon = widget_icon_dir .. 'battery-alert.svg', + app_name = 'System notification', + title = 'Battery is dying!', + message = 'Hey, I think we have a problem here. Save your work before reaching the oblivion.', + urgency = 'critical' + }) + end + + local update_battery = function(status) + + awful.spawn.easy_async_with_shell( + [[sh -c " + upower -i $(upower -e | grep BAT) | grep percentage | awk '{print \$2}' | tr -d '\n%' + "]], + function(stdout) + local battery_percentage = tonumber(stdout) + + -- Stop if null + if not battery_percentage then + return + end + + battery_widget.spacing = dpi(5) + battery_percentage_text.visible = true + battery_percentage_text:set_text(battery_percentage .. '%') + + local icon_name = 'battery' + + -- Fully charged + if (status == 'fully-charged' or status == 'charging') and battery_percentage == 100 then + icon_name = icon_name .. '-' .. 'fully-charged' + battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg')) + return + end + + -- Critical level warning message + if (battery_percentage > 0 and battery_percentage < 10) and status == 'discharging' then + icon_name = icon_name .. '-' .. 'alert-red' + + if os.difftime(os.time(), last_battery_check) > 300 or notify_critcal_battery then + last_battery_check = os.time() + notify_critcal_battery = false + show_battery_warning() + end + battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg')) + return + end + + -- Discharging + if battery_percentage > 0 and battery_percentage < 20 then + icon_name = icon_name .. '-' .. status .. '-' .. '10' + + elseif battery_percentage >= 20 and battery_percentage < 30 then + icon_name = icon_name .. '-' .. status .. '-' .. '20' + + elseif battery_percentage >= 30 and battery_percentage < 50 then + icon_name = icon_name .. '-' .. status .. '-' .. '30' + + elseif battery_percentage >= 50 and battery_percentage < 60 then + icon_name = icon_name .. '-' .. status .. '-' .. '50' + + elseif battery_percentage >= 60 and battery_percentage < 80 then + icon_name = icon_name .. '-' .. status .. '-' .. '60' + + elseif battery_percentage >= 80 and battery_percentage < 90 then + icon_name = icon_name .. '-' .. status .. '-' .. '80' + + elseif battery_percentage >= 90 and battery_percentage < 100 then + icon_name = icon_name .. '-' .. status .. '-' .. '90' + end + + battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. icon_name .. '.svg')) + end + ) + end + + -- Watch status if charging, discharging, fully-charged + watch( + [[sh -c " + upower -i $(upower -e | grep BAT) | grep state | awk '{print \$2}' | tr -d '\n' + "]], + 5, + function(widget, stdout) + local status = stdout:gsub('%\n', '') + + -- If no output or no battery detected + if status == nil or status == '' then + battery_widget.spacing = dpi(0) + battery_percentage_text.visible = false + battery_tooltip:set_text('No battery detected!') + battery_imagebox.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'battery-unknown' .. '.svg')) + return + end + + update_battery(status) + end + ) + + return battery_button +end + +return return_button diff --git a/.config/awesome/widget/blue-light/clickable-container.lua b/.config/awesome/widget/blue-light/clickable-container.lua new file mode 100755 index 0000000..f531740 --- /dev/null +++ b/.config/awesome/widget/blue-light/clickable-container.lua @@ -0,0 +1,35 @@ +local wibox = require('wibox') + +function build(widget) + local container = + wibox.widget { + widget, + widget = wibox.container.background, + } + local old_cursor, old_wibox + container:connect_signal( + 'mouse::enter', + function() + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + container:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + return container +end + +return build diff --git a/.config/awesome/widget/blue-light/init.lua b/.config/awesome/widget/blue-light/init.lua new file mode 100644 index 0000000..093fcb0 --- /dev/null +++ b/.config/awesome/widget/blue-light/init.lua @@ -0,0 +1,124 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.blue-light.clickable-container') +local icons = require('theme.icons') +local blue_light_state = nil + +local action_name = wibox.widget { + text = 'Blue Light', + font = 'Inter Regular 11', + align = 'left', + widget = wibox.widget.textbox +} + +local button_widget = wibox.widget { + { + id = 'icon', + image = icons.toggled_off, + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal +} + +local widget_button = wibox.widget { + { + button_widget, + top = dpi(7), + bottom = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + + +local update_imagebox = function() + local button_icon = button_widget.icon + if blue_light_state then + button_icon:set_image(icons.toggled_on) + else + button_icon:set_image(icons.toggled_off) + end +end + +local kill_state = function() + awful.spawn.easy_async_with_shell( + [[ + redshift -x + kill -9 $(pgrep redshift) + ]], + function(stdout) + stdout = tonumber(stdout) + if stdout then + blue_light_state = false + update_imagebox() + end + end + ) +end + +kill_state() + +local toggle_action = function() + awful.spawn.easy_async_with_shell( + [[ + if [ ! -z $(pgrep redshift) ]; + then + redshift -x && pkill redshift && killall redshift + echo 'OFF' + else + redshift -l 0:0 -t 4500:4500 -r &>/dev/null & + echo 'ON' + fi + ]], + function(stdout) + if stdout:match('ON') then + blue_light_state = true + else + blue_light_state = false + end + update_imagebox() + end + ) + +end + +widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_action() + end + ) + ) +) + +local action_widget = wibox.widget { + { + action_name, + nil, + { + widget_button, + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.horizontal, + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +awesome.connect_signal( + 'widget::blue_light:toggle', + function() + toggle_action() + end +) + +return action_widget diff --git a/.config/awesome/widget/bluetooth-toggle/clickable-container.lua b/.config/awesome/widget/bluetooth-toggle/clickable-container.lua new file mode 100644 index 0000000..f531740 --- /dev/null +++ b/.config/awesome/widget/bluetooth-toggle/clickable-container.lua @@ -0,0 +1,35 @@ +local wibox = require('wibox') + +function build(widget) + local container = + wibox.widget { + widget, + widget = wibox.container.background, + } + local old_cursor, old_wibox + container:connect_signal( + 'mouse::enter', + function() + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + container:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + return container +end + +return build diff --git a/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg b/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg new file mode 100644 index 0000000..f3e52ab --- /dev/null +++ b/.config/awesome/widget/bluetooth-toggle/icons/bluetooth-off.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/bluetooth-toggle/icons/loading.svg b/.config/awesome/widget/bluetooth-toggle/icons/loading.svg new file mode 100644 index 0000000..cd7bc0e --- /dev/null +++ b/.config/awesome/widget/bluetooth-toggle/icons/loading.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/bluetooth-toggle/init.lua b/.config/awesome/widget/bluetooth-toggle/init.lua new file mode 100644 index 0000000..a4d7016 --- /dev/null +++ b/.config/awesome/widget/bluetooth-toggle/init.lua @@ -0,0 +1,164 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local naughty = require('naughty') +local watch = awful.widget.watch +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.bluetooth-toggle.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/bluetooth-toggle/icons/' +local icons = require('theme.icons') +local device_state = false + +local action_name = wibox.widget { + text = 'Bluetooth Connection', + font = 'Inter Regular 11', + align = 'left', + widget = wibox.widget.textbox +} + +local button_widget = wibox.widget { + { + id = 'icon', + image = icons.toggled_off, + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal +} + +local widget_button = wibox.widget { + { + button_widget, + top = dpi(7), + bottom = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +local action_widget = wibox.widget { + { + action_name, + nil, + { + widget_button, + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.horizontal, + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + + +local update_imagebox = function() + if device_state then + button_widget.icon:set_image(icons.toggled_on) + else + button_widget.icon:set_image(icons.toggled_off) + end +end + + +local check_device_state = function() + awful.spawn.easy_async_with_shell( + 'rfkill list bluetooth', + function(stdout) + if stdout:match('Soft blocked: yes') then + device_state = false + else + device_state = true + end + update_imagebox() + end + ) +end + +check_device_state() + + +local power_on_cmd = [[ + rfkill unblock bluetooth + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Bluetooth Manager', + title = 'System Notification', + message = 'Initializing bluetooth device...', + icon = ']] .. widget_icon_dir .. 'loading' .. '.svg' .. [[' + }) + " + + # Add a delay here so we can enable the bluetooth + sleep 1 + + bluetoothctl power on +]] + +local power_off_cmd = [[ + bluetoothctl power off + rfkill block bluetooth + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Bluetooth Manager', + title = 'System Notification', + message = 'The bluetooth device has been disabled.', + icon = ']] .. widget_icon_dir .. 'bluetooth-off' .. '.svg' .. [[' + }) + " +]] + + +local toggle_action = function() + if device_state then + device_state = false + awful.spawn.easy_async_with_shell( + power_off_cmd, + function(stdout) + update_imagebox() + end + ) + else + device_state = true + awful.spawn.easy_async_with_shell( + power_on_cmd, + function(stdout) + update_imagebox() + end + ) + end +end + + +widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_action() + end + ) + ) +) + +watch( + 'rfkill list bluetooth', + 5, + function(_, stdout) + check_device_state() + collectgarbage('collect') + end +) + + +return action_widget diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg new file mode 100644 index 0000000..bbda6ad --- /dev/null +++ b/.config/awesome/widget/bluetooth/icons/bluetooth-connected.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg new file mode 100644 index 0000000..f3e52ab --- /dev/null +++ b/.config/awesome/widget/bluetooth/icons/bluetooth-off.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg b/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg new file mode 100644 index 0000000..029f145 --- /dev/null +++ b/.config/awesome/widget/bluetooth/icons/bluetooth-scanning.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/bluetooth/icons/bluetooth.svg b/.config/awesome/widget/bluetooth/icons/bluetooth.svg new file mode 100644 index 0000000..32fbc3e --- /dev/null +++ b/.config/awesome/widget/bluetooth/icons/bluetooth.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/bluetooth/icons/loading.svg b/.config/awesome/widget/bluetooth/icons/loading.svg new file mode 100644 index 0000000..cd7bc0e --- /dev/null +++ b/.config/awesome/widget/bluetooth/icons/loading.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/bluetooth/init.lua b/.config/awesome/widget/bluetooth/init.lua new file mode 100644 index 0000000..153ef3b --- /dev/null +++ b/.config/awesome/widget/bluetooth/init.lua @@ -0,0 +1,83 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local naughty = require('naughty') +local watch = awful.widget.watch +local dpi = require('beautiful').xresources.apply_dpi + +local apps = require('configuration.apps') + +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() + +local widget_icon_dir = config_dir .. 'widget/bluetooth/icons/' + +local return_button = function() + + local widget = + wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'bluetooth-off' .. '.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn(apps.default.bluetooth_manager, false) + end + ) + ) + ) + + local bluetooth_tooltip = awful.tooltip + { + objects = {widget_button}, + mode = 'outside', + align = 'right', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'right', 'left', 'top', 'bottom'} + } + + watch( + 'rfkill list bluetooth', + 5, + function(_, stdout) + local widget_icon_name = nil + if stdout:match('Soft blocked: yes') then + widget_icon_name = 'bluetooth-off' + bluetooth_tooltip.markup = 'Bluetooth is off' + else + widget_icon_name = 'bluetooth' + bluetooth_tooltip.markup = 'Bluetooth is on' + end + widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg') + collectgarbage('collect') + end, + widget + ) + + return widget_button + +end + +return return_button \ No newline at end of file diff --git a/.config/awesome/widget/blur-slider/clickable-container.lua b/.config/awesome/widget/blur-slider/clickable-container.lua new file mode 100644 index 0000000..f531740 --- /dev/null +++ b/.config/awesome/widget/blur-slider/clickable-container.lua @@ -0,0 +1,35 @@ +local wibox = require('wibox') + +function build(widget) + local container = + wibox.widget { + widget, + widget = wibox.container.background, + } + local old_cursor, old_wibox + container:connect_signal( + 'mouse::enter', + function() + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + container:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + return container +end + +return build diff --git a/.config/awesome/widget/blur-slider/init.lua b/.config/awesome/widget/blur-slider/init.lua new file mode 100644 index 0000000..4d7275b --- /dev/null +++ b/.config/awesome/widget/blur-slider/init.lua @@ -0,0 +1,194 @@ +local wibox = require('wibox') +local gears = require('gears') +local awful = require('awful') +local beautiful = require('beautiful') +local spawn = awful.spawn +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') +local clickable_container = require('widget.clickable-container') + +local action_name = wibox.widget { + text = 'Blur Strength', + font = 'Inter Bold 10', + align = 'left', + widget = wibox.widget.textbox +} + +local icon = wibox.widget { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + image = icons.effects, + resize = true, + widget = wibox.widget.imagebox + }, + nil +} + +local action_level = wibox.widget { + { + icon, + widget = clickable_container, + }, + bg = beautiful.transparent, + shape = gears.shape.circle, + widget = wibox.container.background +} + +local slider = wibox.widget { + nil, + { + id = 'blur_strength_slider', + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(2), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider, + }, + nil, + expand = 'none', + forced_height = dpi(24), + layout = wibox.layout.align.vertical +} + +local blur_slider = slider.blur_strength_slider + +local update_slider_value = function() + + awful.spawn.easy_async_with_shell( + [[bash -c " + grep -F 'strength =' $HOME/.config/awesome/configuration/picom.conf | + awk 'NR==1 {print $3}' | tr -d ';' + "]], + function(stdout, stderr) + local strength = stdout:match('%d+') + blur_strength = tonumber(strength) / 20 * 100 + blur_slider:set_value(tonumber(blur_strength)) + start_up = false + end + ) +end + +-- Update on startup +update_slider_value() + +local action_jump = function() + local sli_value = blur_slider:get_value() + local new_value = 0 + + if sli_value >= 0 and sli_value < 25 then + new_value = 25 + elseif sli_value >= 25 and sli_value < 50 then + new_value = 50 + elseif sli_value >= 50 and sli_value < 100 then + new_value = 100 + else + new_value = 0 + end + blur_slider:set_value(new_value) +end + +action_level:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + nil, + function() + action_jump() + end + ) + ) +) + +local adjust_blur = function(power) + + awful.spawn.with_shell( + [[bash -c " + sed -i 's/.*strength = .*/ strength = ]] .. power .. [[;/g' \ + $HOME/.config/awesome/configuration/picom.conf + "]] + ) +end + +blur_slider:connect_signal( + 'property::value', + function() + if not start_up then + strength = blur_slider:get_value() / 50 * 10 + adjust_blur(strength) + end + end +) + +-- Adjust slider value to change blur strength +awesome.connect_signal( + 'widget::blur:increase', + function() + + -- On startup, the slider.value returns nil so... + if blur_slider:get_value() == nil then + return + end + + local blur_value = blur_slider:get_value() + 10 + + -- No more than 100! + if blur_value > 100 then + blur_slider:set_value(100) + return + end + + blur_slider:set_value(blur_value) + end +) + +-- Decrease blur +awesome.connect_signal( + 'widget::blur:decrease', + function() + + -- On startup, the slider.value returns nil so... + if blur_slider:get_value() == nil then + return + end + + local blur_value = blur_slider:get_value() - 10 + + -- No negatives! + if blur_value < 0 then + blur_slider:set_value(0) + return + end + + blur_slider:set_value(blur_value) + end +) + +local volume_setting = wibox.widget { + { + { + action_level, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return volume_setting diff --git a/.config/awesome/widget/blur-toggle/clickable-container.lua b/.config/awesome/widget/blur-toggle/clickable-container.lua new file mode 100644 index 0000000..f531740 --- /dev/null +++ b/.config/awesome/widget/blur-toggle/clickable-container.lua @@ -0,0 +1,35 @@ +local wibox = require('wibox') + +function build(widget) + local container = + wibox.widget { + widget, + widget = wibox.container.background, + } + local old_cursor, old_wibox + container:connect_signal( + 'mouse::enter', + function() + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + container:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + return container +end + +return build diff --git a/.config/awesome/widget/blur-toggle/init.lua b/.config/awesome/widget/blur-toggle/init.lua new file mode 100644 index 0000000..fe30b3f --- /dev/null +++ b/.config/awesome/widget/blur-toggle/init.lua @@ -0,0 +1,139 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local clickable_container = require('widget.blur-toggle.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi +local filesystem = gears.filesystem +local config_dir = filesystem.get_configuration_dir() +local icons = require('theme.icons') +local apps = require('configuration.apps') +local frame_status = nil + +local action_name = wibox.widget { + text = 'Blur Effects', + font = 'Inter Regular 11', + align = 'left', + widget = wibox.widget.textbox +} + +local button_widget = wibox.widget { + { + id = 'icon', + image = icons.toggled_off, + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal +} + +local widget_button = wibox.widget { + { + button_widget, + top = dpi(7), + bottom = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +local update_imagebox = function() + if action_status then + button_widget.icon:set_image(icons.toggled_on) + else + button_widget.icon:set_image(icons.toggled_off) + end +end + +local check_blur_status = function() + awful.spawn.easy_async_with_shell( + [[bash -c " + grep -F 'method = \"none\";' ]] .. config_dir .. [[/configuration/picom.conf | tr -d '[\"\;\=\ ]' + "]], + function(stdout, stderr) + if stdout:match('methodnone') then + action_status = false + else + action_status = true + end + + update_imagebox() + end + ) +end + +check_blur_status() + +local toggle_blur = function(togglemode) + + local toggle_blur_script = [[bash -c " + # Check picom if it's not running then start it + if [ -z $(pgrep picom) ]; then + picom -b --experimental-backends --dbus --config ]] .. config_dir .. [[configuration/picom.conf + fi + + case ]] .. togglemode .. [[ in + 'enable') + sed -i -e 's/method = \"none\"/method = \"dual_kawase\"/g' \"]] .. config_dir .. [[configuration/picom.conf\" + ;; + 'disable') + sed -i -e 's/method = \"dual_kawase\"/method = \"none\"/g' \"]] .. config_dir .. [[configuration/picom.conf\" + ;; + esac + "]] + + -- Run the script + awful.spawn.with_shell(toggle_blur_script) + +end + +local toggle_blur_fx = function() + local state = nil + if action_status then + action_status = false + state = 'disable' + else + action_status = true + state = 'enable' + end + toggle_blur(state) + update_imagebox() +end + +widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_blur_fx() + end + ) + ) +) + +local action_widget = wibox.widget { + { + action_name, + nil, + { + widget_button, + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.horizontal, + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +awesome.connect_signal( + 'widget::blur:toggle', + function() + toggle_blur_fx() + end +) + + +return action_widget diff --git a/.config/awesome/widget/brightness-slider/init.lua b/.config/awesome/widget/brightness-slider/init.lua new file mode 100644 index 0000000..aa53692 --- /dev/null +++ b/.config/awesome/widget/brightness-slider/init.lua @@ -0,0 +1,180 @@ +local wibox = require('wibox') +local gears = require('gears') +local awful = require('awful') +local beautiful = require('beautiful') +local spawn = awful.spawn +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') +local clickable_container = require('widget.clickable-container') + +local icon = wibox.widget { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + image = icons.brightness, + resize = true, + widget = wibox.widget.imagebox + }, + nil +} + +local action_level = wibox.widget { + { + icon, + widget = clickable_container + }, + bg = beautiful.transparent, + shape = gears.shape.circle, + widget = wibox.container.background +} + +local slider = wibox.widget { + nil, + { + id = 'brightness_slider', + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(2), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider, + }, + nil, + expand = 'none', + forced_height = dpi(24), + layout = wibox.layout.align.vertical +} + + +local brightness_slider = slider.brightness_slider + +brightness_slider:connect_signal( + 'property::value', + function() + local brightness_level = brightness_slider:get_value() + + spawn('light -S ' .. + math.max(brightness_level, 5), + false + ) + + -- Update brightness osd + awesome.emit_signal( + 'module::brightness_osd', + brightness_level + ) + end +) + +brightness_slider:buttons( + gears.table.join( + awful.button( + {}, + 4, + nil, + function() + if brightness_slider:get_value() > 100 then + brightness_slider:set_value(100) + return + end + brightness_slider:set_value(brightness_slider:get_value() + 5) + end + ), + awful.button( + {}, + 5, + nil, + function() + if brightness_slider:get_value() < 0 then + brightness_slider:set_value(0) + return + end + brightness_slider:set_value(brightness_slider:get_value() - 5) + end + ) + ) +) + + +local update_slider = function() + awful.spawn.easy_async_with_shell( + 'light -G', + function(stdout) + local brightness = string.match(stdout, '(%d+)') + brightness_slider:set_value(tonumber(brightness)) + end + ) +end + +-- Update on startup +update_slider() + +local action_jump = function() + local sli_value = brightness_slider:get_value() + local new_value = 0 + + if sli_value >= 0 and sli_value < 50 then + new_value = 50 + elseif sli_value >= 50 and sli_value < 100 then + new_value = 100 + else + new_value = 0 + end + brightness_slider:set_value(new_value) +end + +action_level:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + nil, + function() + action_jump() + end + ) + ) +) + +-- The emit will come from the global keybind +awesome.connect_signal( + 'widget::brightness', + function() + update_slider() + end +) + +-- The emit will come from the OSD +awesome.connect_signal( + 'widget::brightness:update', + function(value) + brightness_slider:set_value(tonumber(value)) + end +) + +local brightness_setting = wibox.widget { + { + { + action_level, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return brightness_setting diff --git a/.config/awesome/widget/calculator/icons/kb-off.svg b/.config/awesome/widget/calculator/icons/kb-off.svg new file mode 100644 index 0000000..0bcea86 --- /dev/null +++ b/.config/awesome/widget/calculator/icons/kb-off.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/calculator/icons/kb.svg b/.config/awesome/widget/calculator/icons/kb.svg new file mode 100644 index 0000000..edccdc8 --- /dev/null +++ b/.config/awesome/widget/calculator/icons/kb.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/calculator/init.lua b/.config/awesome/widget/calculator/init.lua new file mode 100644 index 0000000..ff3e279 --- /dev/null +++ b/.config/awesome/widget/calculator/init.lua @@ -0,0 +1,476 @@ +---------------------------------------------------------------------------- +--- Basic Calculator Widget +-- +-- +-- For more details check my repos README.md +-- +-- +-- @author manilarome <gerome.matilla07@gmail.com> +-- @copyright 2019 manilarome +-- @widget calculator +---------------------------------------------------------------------------- + +-- A basic calculator widget +-- Supports keyboard input! +-- Just hover your cursor above the calculator widget and start typing +-- Stop keygrabbing by leaving the calculator + +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/calculator/icons/' + +local calculator_screen = wibox.widget { + { + id = 'calcu_screen', + text = '0', + font = 'Inter Regular 20', + align = 'right', + valign = 'center', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin +} + +-- Evaluate +local calculate = function () + + local calcu_screen = calculator_screen.calcu_screen + + local string_expression = calcu_screen:get_text() + + if string_expression:sub(-1):match('[%+%-%/%*%^%.]') then + return + end + + + local func = assert(load('return ' .. string_expression)) + local ans = tostring(func()) + + -- Convert -nan to undefined + if ans == '-nan' then + calcu_screen:set_text('undefined') + return + end + + -- Set the answer in textbox + calcu_screen:set_text(ans) + +end + +local txt_on_screen = function() + + screen_text = calculator_screen.calcu_screen:get_text() + + return screen_text == 'inf' or screen_text == 'undefined' or screen_text == 'SYNTAX ERROR' or #screen_text == 1 +end + +-- Delete the last digit in screen + +local delete_value = function() + + calcu_screen = calculator_screen.calcu_screen + + -- Set the screen text to 0 if conditions met + if txt_on_screen() then + calcu_screen:set_text('0') + else + -- Delete the last digit + calcu_screen:set_text(calcu_screen:get_text():sub(1, -2)) + end +end + +-- Clear screen +local clear_screen = function() + + calculator_screen.calcu_screen:set_text('0') +end + +-- The one that filters and checks the user input to avoid errors and bugs +local format_screen = function(value) + + local calcu_screen = calculator_screen.calcu_screen + + -- If the screen has only 0 + if calcu_screen:get_text() == '0' then + + -- Check if the button pressed sends a value of either +, -, /, *, ^, . + + if value:sub(-1):match('[%+%/%*%^%.]') then + + calcu_screen:set_text(calcu_screen:get_text() .. tostring(value)) + + else + + calcu_screen:set_text(value) + + end + + elseif calcu_screen:get_text() == 'inf' or + calcu_screen:get_text() == 'undefined' or + calcu_screen:get_text() == 'SYNTAX ERROR' then + + -- Clear screen if an operator is selected + if value:sub(-1):match('[%+%/%*%^%.]') then + clear_screen() + + else + -- Replace screen txt with the number value pressed + clear_screen() + calcu_screen:set_text(tostring(value)) + end + + else + + -- Don't let the user to input two or more consecutive arithmetic operators and decimals + if calcu_screen:get_text():sub(-1):match('[%+%-%/%*%^%.]') and value:sub(-1):match('[%+%-%/%*%^%.%%]') then + + -- Get the operator from button pressed + local string_eval = calcu_screen:get_text():sub(-1):gsub('[%+%-%/%*%^%.]', value) + + -- This will prevent the user to input consecutive operators and decimals + -- It will replace the previous operator with the value of input + calcu_screen:set_text(calcu_screen:get_text():sub(1, -2)) + + -- Concatenate the value operator to the screen string to replace the deleted operator + calcu_screen:set_text(calcu_screen:get_text() .. tostring(string_eval)) + + else + -- Concatenate the value to screen string + calcu_screen:set_text(calcu_screen:get_text() .. tostring(value)) + + end + end + +end + +-- Shape generator +local build_shape = function (position, radius) + + -- Position represents the position of rounded corners + if position == 'top' then + return function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, false, false, radius) + end + + elseif position == 'top_left' then + return function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, false, false, false, radius) + end + + elseif position == 'top_right' then + return function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, false, true, false, false, radius) + end + + elseif position == 'bottom_right' then + return function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, false, false, true, false, radius) + end + + elseif position == 'bottom_left' then + return function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, false, false, false, true, radius) + end + + else + return function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, radius) + end + + end +end + +-- Themes widgets +local decorate_widget = function(widget_arg, pos, rad) + return wibox.widget { + widget_arg, + bg = beautiful.groups_bg, + shape = build_shape(pos, rad), + widget = wibox.container.background + } +end + +-- Build a button +local build_button_widget = function(text, rcp, rad) + + local value = text + + local build_textbox = wibox.widget { + { + id = 'btn_name', + text = value, + font = 'Inter 12', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox, + }, + margins = dpi(5), + widget = wibox.container.margin + } + + local build_button = wibox.widget { + { + build_textbox, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + build_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function () + + if value == 'C' then + clear_screen() + + elseif value == '=' then + -- Calculate and error handling + if not pcall(calculate) then + calculator_screen.calcu_screen:set_text('SYNTAX ERROR') + end + + elseif value == 'DEL' then + delete_value() + + else + format_screen(value) + + end + end + ) + ) + ) + + return decorate_widget(build_button, rcp, rad) + +end + +local keygrab_running = false + +local kb_imagebox = wibox.widget { + + id = 'kb_icon', + image = widget_icon_dir .. 'kb-off' .. '.svg', + resize = true, + forced_height = dpi(15), + widget = wibox.widget.imagebox +} + +local kb_button_widget = wibox.widget { + { + { + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + kb_imagebox, + nil + }, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + }, + bg = beautiful.groups_bg, + shape = build_shape('bottom_left', beautiful.groups_radius), + widget = wibox.container.background +} + +local toggle_btn_keygrab = function() + + if keygrab_running then + kb_imagebox:set_image(widget_icon_dir .. 'kb-off' .. '.svg') + awesome.emit_signal('widget::calc_stop_keygrab') + keygrab_running = false + else + kb_imagebox:set_image(widget_icon_dir .. 'kb' .. '.svg') + awesome.emit_signal('widget::calc_start_keygrab') + keygrab_running = true + end + +end + +local kb_button = kb_button_widget + +kb_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_btn_keygrab() + end + ) + ) +) + +local calcu_keygrabber = awful.keygrabber { + + auto_start = true, + stop_event = 'release', + start_callback = function() + + keygrab_running = true + kb_imagebox:set_image(widget_icon_dir .. 'kb' .. '.svg') + + end, + stop_callback = function() + + keygrab_running = false + kb_imagebox:set_image(widget_icon_dir .. 'kb-off' .. '.svg') + + end, + keypressed_callback = function(self, mod, key, command) + + if #key == 1 and (key:match('%d+') or key:match('[%+%-%/%*%^%.]')) then + format_screen(key) + + elseif key == 'BackSpace' then + delete_value() + + elseif key == 'Escape' then + clear_screen() + + elseif key == 'x' then + awesome.emit_signal('widget::calc_stop_keygrab') + + elseif key == '=' or key == 'Return' then + -- Calculate + if not pcall(calculate) then + calculator_screen.calcu_screen:set_text('SYNTAX ERROR') + end + + end + + end, +} + +local calculator_body = wibox.widget { + layout = wibox.layout.fixed.vertical, + spacing = dpi(1), + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + decorate_widget(calculator_screen, 'top', beautiful.groups_radius), + }, + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + build_button_widget('C', 'flat' , 0), + build_button_widget('^', 'flat', 0), + build_button_widget('/', 'flat', 0), + build_button_widget('DEL', 'flat', 0), + }, + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + build_button_widget('7', 'flat', 0), + build_button_widget('8', 'flat', 0), + build_button_widget('9', 'flat', 0), + build_button_widget('*', 'flat', 0), + }, + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + build_button_widget('4', 'flat', 0), + build_button_widget('5', 'flat', 0), + build_button_widget('6', 'flat', 0), + build_button_widget('-', 'flat', 0), + }, + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + build_button_widget('1', 'flat', 0), + build_button_widget('2', 'flat', 0), + build_button_widget('3', 'flat', 0), + build_button_widget('+', 'flat', 0), + }, + { + spacing = dpi(1), + layout = wibox.layout.flex.horizontal, + kb_button, + build_button_widget('0', 'flat', 0), + build_button_widget('.', 'flat', 0), + build_button_widget('=', 'bottom_right', beautiful.groups_radius) + }, +} + +calculator_body:connect_signal( + 'mouse::enter', + function() + -- Start keygrabbing + calcu_keygrabber:start() + end +) + +calculator_body:connect_signal( + 'mouse::leave', + function() + -- Stop keygrabbing + calcu_keygrabber:stop() + end +) + +awesome.connect_signal( + 'widget::calc_start_keygrab', + function() + -- Stop keygrabbing + calcu_keygrabber:start() + end +) + +awesome.connect_signal( + 'widget::calc_stop_keygrab', + function() + -- Stop keygrabbing + calcu_keygrabber:stop() + end +) + +local calcu_tooltip = awful.tooltip { + + objects = {kb_button}, + mode = 'outside', + align = 'right', + delay_show = 1, + preferred_positions = {'right', 'left', 'top', 'bottom'}, + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + markup = [[ + Tips: + Enable keyboard support by hovering your mouse above the calculator. + Or toggle it on/off by pressing the keyboard button. + Only numbers, arithmetic operators, and decimal point is accepted. + + Keyboard bindings: + = and Return to get the answer. + BackSpace to delete the last digit. + Escape clears the screen. + x stops keygrabbing. + + Note: + While in keygrabbing mode, your keyboard's focus will be on the calculator. + So you're AwesomeWM keybinding will stop working. + + Stopping the keygrabbing mode: + * Move away your cursor from the calculator. + * Toggle it off using the keyboard button. + * Press x. + ]] +} + +return calculator_body diff --git a/.config/awesome/widget/clickable-container/init.lua b/.config/awesome/widget/clickable-container/init.lua new file mode 100644 index 0000000..6b57aa2 --- /dev/null +++ b/.config/awesome/widget/clickable-container/init.lua @@ -0,0 +1,59 @@ +local wibox = require('wibox') +local beautiful = require('beautiful') + +local create_click_events = function(widget) + + local container = wibox.widget { + widget, + widget = wibox.container.background + } + + -- Old and new widget + local old_cursor, old_wibox + + -- Mouse hovers on the widget + container:connect_signal( + 'mouse::enter', + function() + container.bg = beautiful.groups_bg + -- Hm, no idea how to get the wibox from this signal's arguments... + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + -- Mouse leaves the widget + container:connect_signal( + 'mouse::leave', + function() + container.bg = beautiful.leave_event + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + -- Mouse pressed the widget + container:connect_signal( + 'button::press', + function() + container.bg = beautiful.press_event + end + ) + + -- Mouse releases the widget + container:connect_signal( + 'button::release', + function() + container.bg = beautiful.release_event + end + ) + + return container +end + +return create_click_events diff --git a/.config/awesome/widget/clock/init.lua b/.config/awesome/widget/clock/init.lua new file mode 100644 index 0000000..809fb1f --- /dev/null +++ b/.config/awesome/widget/clock/init.lua @@ -0,0 +1,158 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local config = require('configuration.config') +local military_mode = config.widget.clock.military_mode or false + +local create_clock = function(s) + + local clock_format = nil + if not military_mode then + clock_format = '%I:%M %p' + else + clock_format = '%H:%M' + end + + s.clock_widget = wibox.widget.textclock( + clock_format, + 1 + ) + + s.clock_widget = wibox.widget { + { + s.clock_widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + s.clock_widget:connect_signal( + 'mouse::enter', + function() + local w = mouse.current_wibox + if w then + old_cursor, old_wibox = w.cursor, w + w.cursor = 'hand1' + end + end + ) + + s.clock_widget:connect_signal( + 'mouse::leave', + function() + if old_wibox then + old_wibox.cursor = old_cursor + old_wibox = nil + end + end + ) + + s.clock_tooltip = awful.tooltip + { + objects = {s.clock_widget}, + mode = 'outside', + delay_show = 1, + preferred_positions = {'right', 'left', 'top', 'bottom'}, + preferred_alignments = {'middle', 'front', 'back'}, + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + timer_function = function() + local ordinal = nil + + local day = os.date('%d') + local month = os.date('%B') + + local first_digit = string.sub(day, 0, 1) + local last_digit = string.sub(day, -1) + + if first_digit == '0' then + day = last_digit + end + + if last_digit == '1' and day ~= '11' then + ordinal = 'st' + elseif last_digit == '2' and day ~= '12' then + ordinal = 'nd' + elseif last_digit == '3' and day ~= '13' then + ordinal = 'rd' + else + ordinal = 'th' + end + + local date_str = 'Today is the ' .. + '' .. day .. ordinal .. + ' of ' .. month .. '.\n' .. + 'And it\'s fucking ' .. os.date('%A') + + return date_str + end, + } + + s.clock_widget:connect_signal( + 'button::press', + function(self, lx, ly, button) + -- Hide the tooltip when you press the clock widget + if s.clock_tooltip.visible and button == 1 then + s.clock_tooltip.visible = false + end + end + ) + + s.month_calendar = awful.widget.calendar_popup.month({ + start_sunday = true, + spacing = dpi(5), + font = 'Inter Regular 10', + long_weekdays = true, + margin = dpi(5), + screen = s, + style_month = { + border_width = dpi(0), + bg_color = beautiful.background, + padding = dpi(20), + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, true, true, true, true, beautiful.groups_radius + ) + end + }, + style_header = { + border_width = 0, + bg_color = beautiful.transparent + }, + style_weekday = { + border_width = 0, + bg_color = beautiful.transparent + }, + style_normal = { + border_width = 0, + bg_color = beautiful.transparent + }, + style_focus = { + border_width = dpi(0), + border_color = beautiful.fg_normal, + bg_color = beautiful.accent, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, true, true, true, true, dpi(4) + ) + end, + }, + }) + + s.month_calendar:attach( + s.clock_widget, + 'tc', + { + on_pressed = true, + on_hover = false + } + ) + + return s.clock_widget +end + +return create_clock diff --git a/.config/awesome/widget/cpu-meter/init.lua b/.config/awesome/widget/cpu-meter/init.lua new file mode 100644 index 0000000..b68f44b --- /dev/null +++ b/.config/awesome/widget/cpu-meter/init.lua @@ -0,0 +1,74 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local watch = require('awful.widget.watch') +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') + +local total_prev = 0 +local idle_prev = 0 + +local slider = wibox.widget { + nil, + { + id = 'cpu_usage', + max_value = 100, + value = 29, + forced_height = dpi(2), + color = beautiful.fg_normal, + background_color = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + widget = wibox.widget.progressbar + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +watch( + [[bash -c " + cat /proc/stat | grep '^cpu ' + "]], + 10, + function(_, stdout) + local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice = + stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s') + + local total = user + nice + system + idle + iowait + irq + softirq + steal + + local diff_idle = idle - idle_prev + local diff_total = total - total_prev + local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 + + slider.cpu_usage:set_value(diff_usage) + + total_prev = total + idle_prev = idle + collectgarbage('collect') + end +) + +local cpu_meter = wibox.widget { + { + { + { + image = icons.chart, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return cpu_meter diff --git a/.config/awesome/widget/email/icons/email-1.svg b/.config/awesome/widget/email/icons/email-1.svg new file mode 100644 index 0000000..9170d0b --- /dev/null +++ b/.config/awesome/widget/email/icons/email-1.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-2.svg b/.config/awesome/widget/email/icons/email-2.svg new file mode 100644 index 0000000..58406a7 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-2.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-3.svg b/.config/awesome/widget/email/icons/email-3.svg new file mode 100644 index 0000000..597b144 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-3.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-4.svg b/.config/awesome/widget/email/icons/email-4.svg new file mode 100644 index 0000000..dc915fb --- /dev/null +++ b/.config/awesome/widget/email/icons/email-4.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-5.svg b/.config/awesome/widget/email/icons/email-5.svg new file mode 100644 index 0000000..935140c --- /dev/null +++ b/.config/awesome/widget/email/icons/email-5.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-6.svg b/.config/awesome/widget/email/icons/email-6.svg new file mode 100644 index 0000000..edf1298 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-6.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-7.svg b/.config/awesome/widget/email/icons/email-7.svg new file mode 100644 index 0000000..980d79c --- /dev/null +++ b/.config/awesome/widget/email/icons/email-7.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-8.svg b/.config/awesome/widget/email/icons/email-8.svg new file mode 100644 index 0000000..4c6618a --- /dev/null +++ b/.config/awesome/widget/email/icons/email-8.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-9+.svg b/.config/awesome/widget/email/icons/email-9+.svg new file mode 100644 index 0000000..53a0a68 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-9+.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-9.svg b/.config/awesome/widget/email/icons/email-9.svg new file mode 100644 index 0000000..9c65b74 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-9.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email-unread.svg b/.config/awesome/widget/email/icons/email-unread.svg new file mode 100644 index 0000000..829d3a9 --- /dev/null +++ b/.config/awesome/widget/email/icons/email-unread.svg @@ -0,0 +1,117 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/email/icons/email.svg b/.config/awesome/widget/email/icons/email.svg new file mode 100644 index 0000000..a8860b4 --- /dev/null +++ b/.config/awesome/widget/email/icons/email.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/email/init.lua b/.config/awesome/widget/email/init.lua new file mode 100644 index 0000000..7116158 --- /dev/null +++ b/.config/awesome/widget/email/init.lua @@ -0,0 +1,410 @@ +local awful = require('awful') +local gears = require('gears') +local wibox = require('wibox') +local naughty = require('naughty') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/email/icons/' + +local config = require('configuration.config') +local secrets = { + email_address = config.widget.email.address, + app_password = config.widget.email.app_password, + imap_server = config.widget.email.imap_server, + port = config.widget.email.port +} + +local unread_email_count = 0 +local startup_show = true + +local scroll_container = function(widget) + return wibox.widget { + widget, + id = 'scroll_container', + max_size = 345, + speed = 75, + expand = true, + direction = 'h', + step_function = wibox.container.scroll + .step_functions.waiting_nonlinear_back_and_forth, + fps = 30, + layout = wibox.container.scroll.horizontal, + } +end + +local email_icon_widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'email.svg', + resize = true, + forced_height = dpi(45), + forced_width = dpi(45), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local email_from_text = wibox.widget { + font = 'Inter Regular 10', + markup = 'From:', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_recent_from = wibox.widget { + font = 'Inter Regular 10', + markup = 'loading@stdout.sh', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_subject_text = wibox.widget { + font = 'Inter Regular 10', + markup = 'Subject:', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_recent_subject = wibox.widget { + font = 'Inter Regular 10', + markup = 'Loading data', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_date_text = wibox.widget { + font = 'Inter Regular 10', + markup = 'Local Date:', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_recent_date = wibox.widget { + font = 'Inter Regular 10', + markup = 'Loading date...', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local email_report = wibox.widget{ + { + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(10), + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + email_icon_widget, + nil + }, + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + { + email_from_text, + scroll_container(email_recent_from), + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal + }, + { + email_subject_text, + scroll_container(email_recent_subject), + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal + }, + { + email_date_text, + scroll_container(email_recent_date), + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal + } + }, + nil + } + }, + margins = dpi(10), + widget = wibox.container.margin + }, + forced_height = dpi(92), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) +end, +widget = wibox.container.background +} + +local email_details_tooltip = awful.tooltip +{ + text = 'Loading...', + objects = {email_icon_widget}, + mode = 'outside', + align = 'right', + preferred_positions = {'left', 'right', 'top', 'bottom'}, + margin_leftright = dpi(8), + margin_topbottom = dpi(8) +} + +local fetch_email_command = [[ +python3 - < 1 then + title = 'You have ' .. unread_counter .. ' unread emails!' + else + title = 'You have ' .. unread_counter .. ' unread email!' + end + + naughty.notification ({ + app_name = 'Email', + title = title, + message = email_data, + timeout = 30, + icon = widget_icon_dir .. 'email-unread.svg' + }) +end + +local notify_new_email = function(count, from, subject) + if not startup_show and (tonumber(count) > tonumber(unread_email_count)) then + unread_email_count = tonumber(count) + + local message = "From: " .. from .. + "\nSubject: " .. subject + + naughty.notification ({ + app_name = 'Email', + title = 'You have a new unread email!', + message = message, + timeout = 10, + icon = widget_icon_dir .. 'email-unread.svg' + }) + else + unread_email_count = tonumber(count) + end + +end + +local set_email_data_tooltip = function(email_data) + local email_data = email_data:match('(From:.*)') + local counter = "Unread Count: " .. unread_email_count + email_details_tooltip:set_markup(counter .. '\n\n' .. email_data) +end + +local set_widget_markup = function(from, subject, date, tooltip) + + email_recent_from:set_markup(from:gsub('%\n', '')) + email_recent_subject:set_markup(subject:gsub('%\n', '')) + email_recent_date:set_markup(date:gsub('%\n', '')) + + if tooltip then + email_details_tooltip:set_markup(tooltip) + end +end + +local set_no_connection_msg = function() + set_widget_markup( + 'message@stderr.sh', + 'Check network connection!', + os.date('%d-%m-%Y %H:%M:%S'), + 'No internet connection!' + ) +end + +local set_invalid_credentials_msg = function() + set_widget_markup( + 'message@stderr.sh', + 'Invalid Credentials!', + os.date('%d-%m-%Y %H:%M:%S'), + 'You have an invalid credentials!' + ) +end + +local set_latest_email_data = function(email_data) + + local unread_count = email_data:match('Unread Count: (.-)From:'):sub(1, -2) + local recent_from = email_data:match('From: (.-)Subject:'):sub(1, -2) + local recent_subject = email_data:match('Subject: (.-)Local Date:'):sub(1, -2) + local recent_date = email_data:match('Local Date: (.-)\n') + + recent_from = recent_from:match('<(.*)>') or recent_from:match('<(.*)>') or recent_from + + local count = tonumber(unread_count) + if count > 0 and count <= 9 then + email_icon_widget.icon:set_image(widget_icon_dir .. 'email-'.. tostring(count) .. '.svg') + elseif count > 9 then + email_icon_widget.icon:set_image(widget_icon_dir .. 'email-9+.svg') + end + + set_widget_markup( + recent_from, + recent_subject, + recent_date + ) + + notify_new_email(unread_count, recent_from, recent_subject) +end + +local set_empty_inbox_msg = function() + set_widget_markup( + 'empty@stdout.sh', + 'Empty inbox', + os.date('%d-%m-%Y %H:%M:%S'), + 'Empty inbox.' + ) +end + +local fetch_email_data = function() + awful.spawn.easy_async_with_shell( + fetch_email_command, + function(stdout) + stdout = gears.string.xml_escape(stdout:sub(1, -2)) + + if stdout:match('Temporary failure in name resolution') then + set_no_connection_msg() + return + elseif stdout:match('Invalid credentials') then + set_invalid_credentials_msg() + return + elseif stdout:match('Unread Count: 0') then + email_icon_widget.icon:set_image(widget_icon_dir .. 'email.svg') + set_empty_inbox_msg() + return + elseif not stdout:match('Unread Count: (.-)From:') then + return + elseif not stdout or stdout == '' then + return + end + + set_latest_email_data(stdout) + set_email_data_tooltip(stdout) + + if startup_show then + notify_all_unread_email(stdout) + startup_show = false + end + end + ) +end + +local set_missing_secrets_msg = function() + set_widget_markup( + 'message@stderr.sh', + 'Credentials are missing!', + os.date('%d-%m-%Y %H:%M:%S'), + 'Missing credentials!' + ) +end + +local check_secrets = function() + if secrets.email_address == '' or secrets.app_password == '' or secrets.imap_server == '' or secrets.port == '' then + set_missing_secrets_msg() + return + else + fetch_email_data() + end +end + +check_secrets() + +local update_widget_timer = gears.timer { + timeout = 30, + autostart = true, + call_now = true, + callback = function() + check_secrets() + end +} + +email_report:connect_signal( + 'mouse::enter', + function() + check_secrets() + end +) + +awesome.connect_signal( + 'system::network_connected', + function() + gears.timer.start_new( + 5, + function() + check_secrets() + end + ) + end +) + +return email_report diff --git a/.config/awesome/widget/end-session/init.lua b/.config/awesome/widget/end-session/init.lua new file mode 100644 index 0000000..4914848 --- /dev/null +++ b/.config/awesome/widget/end-session/init.lua @@ -0,0 +1,68 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +local create_widget = function() + local exit_widget = { + { + { + { + image = icons.logout, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + { + text = 'End work session', + font = 'Inter Regular 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin + } + + local exit_button = wibox.widget { + { + exit_widget, + widget = clickable_container + + }, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background + } + + exit_button:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + nil, + function() + screen.primary.left_panel:toggle() + awesome.emit_signal('module::exit_screen:show') + end + ) + ) + ) + + return exit_button +end + +return create_widget diff --git a/.config/awesome/widget/harddrive-meter/init.lua b/.config/awesome/widget/harddrive-meter/init.lua new file mode 100644 index 0000000..b3972c3 --- /dev/null +++ b/.config/awesome/widget/harddrive-meter/init.lua @@ -0,0 +1,61 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local watch = require('awful.widget.watch') +local icons = require('theme.icons') + +local dpi = beautiful.xresources.apply_dpi + +local slider = wibox.widget { + nil, + { + id = 'hdd_usage', + max_value = 100, + value = 29, + forced_height = dpi(2), + color = beautiful.fg_normal, + background_color = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + widget = wibox.widget.progressbar + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +watch( + [[bash -c "df -h /home|grep '^/' | awk '{print $5}'"]], + 10, + function(_, stdout) + local space_consumed = stdout:match('(%d+)') + slider.hdd_usage:set_value(tonumber(space_consumed)) + collectgarbage('collect') + end +) + + +local harddrive_meter = wibox.widget { + { + { + { + image = icons.harddisk, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return harddrive_meter diff --git a/.config/awesome/widget/info-center-switch/init.lua b/.config/awesome/widget/info-center-switch/init.lua new file mode 100644 index 0000000..7583439 --- /dev/null +++ b/.config/awesome/widget/info-center-switch/init.lua @@ -0,0 +1,128 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +-- Variable used for switching panel modes +right_panel_mode = 'today_mode' + +local active_button = beautiful.groups_title_bg +local inactive_button = beautiful.transparent + +local notif_text = wibox.widget +{ + text = 'Notifications', + font = 'Inter Bold 11', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local notif_button = clickable_container( + wibox.container.margin( + notif_text, dpi(0), dpi(0), dpi(7), dpi(7) + ) +) + +local wrap_notif = wibox.widget { + notif_button, + forced_width = dpi(140), + bg = inactive_button, + border_width = dpi(1), + border_color = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, false, true, true, false, beautiful.groups_radius + ) + end, + widget = wibox.container.background +} + +local today_text = wibox.widget { + text = 'Today', + font = 'Inter Bold 11', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local today_button = clickable_container( + wibox.container.margin( + today_text, dpi(0), dpi(0), dpi(7), dpi(7) + ) +) + +local wrap_today = wibox.widget { + today_button, + forced_width = dpi(140), + bg = active_button, + border_width = dpi(1), + border_color = beautiful.groups_title_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, true, false, false, true, beautiful.groups_radius + ) + end, + widget = wibox.container.background +} + +local switcher = wibox.widget { + expand = 'none', + layout = wibox.layout.fixed.horizontal, + wrap_today, + wrap_notif +} + +function switch_rdb_pane(right_panel_mode) + + local focused = awful.screen.focused() + + if right_panel_mode == 'notif_mode' then + + -- Update button color + wrap_notif.bg = active_button + wrap_today.bg = inactive_button + + -- Change panel content of right-panel.lua + focused.right_panel:switch_pane(right_panel_mode) + + elseif right_panel_mode == 'today_mode' then + + -- Update button color + wrap_notif.bg = inactive_button + wrap_today.bg = active_button + + -- Change panel content of right-panel.lua + focused.right_panel:switch_pane(right_panel_mode) + end +end + +notif_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + switch_rdb_pane('notif_mode') + end + ) + ) +) + +today_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + switch_rdb_pane('today_mode') + end + ) + ) +) + +return switcher diff --git a/.config/awesome/widget/info-center-toggle/icons/info-center.svg b/.config/awesome/widget/info-center-toggle/icons/info-center.svg new file mode 100644 index 0000000..c60cf96 --- /dev/null +++ b/.config/awesome/widget/info-center-toggle/icons/info-center.svg @@ -0,0 +1,111 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/info-center-toggle/init.lua b/.config/awesome/widget/info-center-toggle/init.lua new file mode 100644 index 0000000..cad8656 --- /dev/null +++ b/.config/awesome/widget/info-center-toggle/init.lua @@ -0,0 +1,47 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local dpi = require('beautiful').xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/info-center-toggle/icons/' +local clickable_container = require('widget.clickable-container') + +local return_button = function() + + local widget = + wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'info-center.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.screen.focused().right_panel:toggle() + end + ) + ) + ) + + return widget_button +end + +return return_button diff --git a/.config/awesome/widget/layoutbox/init.lua b/.config/awesome/widget/layoutbox/init.lua new file mode 100644 index 0000000..1171f84 --- /dev/null +++ b/.config/awesome/widget/layoutbox/init.lua @@ -0,0 +1,51 @@ +local wibox = require('wibox') +local awful = require('awful') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +local layout_box = function(s) + local layoutbox = wibox.widget { + { + awful.widget.layoutbox(s), + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + layoutbox:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + function() + awful.layout.inc(1) + end + ), + awful.button( + {}, + 3, + function() + awful.layout.inc(-1) + end + ), + awful.button( + {}, + 4, + function() + awful.layout.inc(1) + end + ), + awful.button( + {}, + 5, + function() + awful.layout.inc(-1) + end + ) + ) + ) + return layoutbox +end + +return layout_box \ No newline at end of file diff --git a/.config/awesome/widget/mpd/content/album-cover.lua b/.config/awesome/widget/mpd/content/album-cover.lua new file mode 100755 index 0000000..54bd42b --- /dev/null +++ b/.config/awesome/widget/mpd/content/album-cover.lua @@ -0,0 +1,19 @@ +local gears = require('gears') +local awful = require('awful') +local wibox = require('wibox') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/mpd/icons/' + +local album_cover_img = wibox.widget { + { + id = 'cover', + image = widget_icon_dir .. 'vinyl.svg', + resize = true, + clip_shape = gears.shape.rounded_rect, + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.vertical +} + +return album_cover_img diff --git a/.config/awesome/widget/mpd/content/init.lua b/.config/awesome/widget/mpd/content/init.lua new file mode 100644 index 0000000..9ab0ffd --- /dev/null +++ b/.config/awesome/widget/mpd/content/init.lua @@ -0,0 +1,9 @@ +-- Return UI Table +return { + album_cover = require('widget.mpd.content.album-cover'), + progress_bar = require('widget.mpd.content.progress-bar'), + track_time = require('widget.mpd.content.track-time'), + song_info = require('widget.mpd.content.song-info'), + media_buttons = require('widget.mpd.content.media-buttons'), + volume_slider = require('widget.mpd.content.volume-slider'), +} \ No newline at end of file diff --git a/.config/awesome/widget/mpd/content/media-buttons.lua b/.config/awesome/widget/mpd/content/media-buttons.lua new file mode 100755 index 0000000..dc460dd --- /dev/null +++ b/.config/awesome/widget/mpd/content/media-buttons.lua @@ -0,0 +1,121 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/mpd/icons/' +local media_buttons = {} + +media_buttons.play_button_image = wibox.widget { + { + id = 'play', + image = widget_icon_dir .. 'play.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal +} + +media_buttons.next_button_image = wibox.widget { + { + id = 'next', + image = widget_icon_dir .. 'next.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal +} + +media_buttons.prev_button_image = wibox.widget { + { + id = 'prev', + image = widget_icon_dir .. 'prev.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal +} + +media_buttons.repeat_button_image = wibox.widget { + { + id = 'rep', + image = widget_icon_dir .. 'repeat-on.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal +} + +media_buttons.random_button_image = wibox.widget { + { + id = 'rand', + image = widget_icon_dir .. 'random-on.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal +} + +media_buttons.play_button = wibox.widget { + { + media_buttons.play_button_image, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +media_buttons.next_button = wibox.widget { + { + media_buttons.next_button_image, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container +} + +media_buttons.prev_button = wibox.widget { + { + media_buttons.prev_button_image, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container +} + +media_buttons.repeat_button = wibox.widget { + { + media_buttons.repeat_button_image, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container +} + +media_buttons.random_button = wibox.widget { + { + media_buttons.random_button_image, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container +} + +media_buttons.navigate_buttons = wibox.widget { + expand = 'none', + layout = wibox.layout.align.horizontal, + media_buttons.repeat_button, + { + layout = wibox.layout.fixed.horizontal, + media_buttons.prev_button, + media_buttons.play_button, + media_buttons.next_button, + forced_height = dpi(35), + }, + media_buttons.random_button, + forced_height = dpi(35), +} + +return media_buttons \ No newline at end of file diff --git a/.config/awesome/widget/mpd/content/progress-bar.lua b/.config/awesome/widget/mpd/content/progress-bar.lua new file mode 100755 index 0000000..a103340 --- /dev/null +++ b/.config/awesome/widget/mpd/content/progress-bar.lua @@ -0,0 +1,21 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi + +local progressbar = wibox.widget { + { + id = 'music_bar', + max_value = 100, + forced_height = dpi(3), + forced_width = dpi(100), + color = '#ffffff', + background_color = '#ffffff20', + shape = gears.shape.rounded_bar, + widget = wibox.widget.progressbar + }, + layout = wibox.layout.stack +} + +return progressbar diff --git a/.config/awesome/widget/mpd/content/song-info.lua b/.config/awesome/widget/mpd/content/song-info.lua new file mode 100755 index 0000000..5264780 --- /dev/null +++ b/.config/awesome/widget/mpd/content/song-info.lua @@ -0,0 +1,64 @@ +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi +local song_info = {} + +song_info.music_title = wibox.widget { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + { + id = 'title', + text = 'The song title is here', + font = 'Inter Bold 12', + align = 'center', + valign = 'center', + ellipsize = 'end', + widget = wibox.widget.textbox + }, + id = 'scroll_container', + max_size = 345, + speed = 75, + expand = true, + direction = 'h', + step_function = wibox.container.scroll + .step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + layout = wibox.container.scroll.horizontal + }, + nil +} + +song_info.music_artist = wibox.widget { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + { + id = 'artist', + text = 'The artist name is here', + font = 'Inter 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + }, + id = 'scroll_container', + max_size = 345, + speed = 75, + expand = true, + direction = 'h', + step_function = wibox.container.scroll + .step_functions.waiting_nonlinear_back_and_forth, + layout = wibox.container.scroll.horizontal, + fps = 60 + }, + nil +} + +song_info.music_info = wibox.widget { + layout = wibox.layout.fixed.vertical, + song_info.music_title, + song_info.music_artist +} + +return song_info diff --git a/.config/awesome/widget/mpd/content/track-time.lua b/.config/awesome/widget/mpd/content/track-time.lua new file mode 100755 index 0000000..6ffb565 --- /dev/null +++ b/.config/awesome/widget/mpd/content/track-time.lua @@ -0,0 +1,37 @@ +local beautiful = require('beautiful') +local gears = require('gears') +local awful = require('awful') +local wibox = require('wibox') +local dpi = beautiful.xresources.apply_dpi + +local time_info = {} + +time_info.time_status = wibox.widget { + id = 'statustime', + text = '00:00', + font = 'Inter 8', + align = 'center', + valign = 'center', + forced_height = dpi(10), + widget = wibox.widget.textbox +} + +time_info.time_duration = wibox.widget { + id = 'durationtime', + text = '00:00', + font = 'Inter 8', + align = 'center', + valign = 'center', + forced_height = dpi(10), + widget = wibox.widget.textbox +} + +time_info.time_track = wibox.widget { + expand = 'none', + layout = wibox.layout.align.horizontal, + time_info.time_status, + nil, + time_info.time_duration +} + +return time_info diff --git a/.config/awesome/widget/mpd/content/volume-slider.lua b/.config/awesome/widget/mpd/content/volume-slider.lua new file mode 100755 index 0000000..70151d8 --- /dev/null +++ b/.config/awesome/widget/mpd/content/volume-slider.lua @@ -0,0 +1,23 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi + +local slider = {} + +slider.vol_slider = wibox.widget { + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(5), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider, +} + +return slider diff --git a/.config/awesome/widget/mpd/icons/music.svg b/.config/awesome/widget/mpd/icons/music.svg new file mode 100755 index 0000000..a2aa04e --- /dev/null +++ b/.config/awesome/widget/mpd/icons/music.svg @@ -0,0 +1,62 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/next.svg b/.config/awesome/widget/mpd/icons/next.svg new file mode 100644 index 0000000..7df5063 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/next.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/pause.svg b/.config/awesome/widget/mpd/icons/pause.svg new file mode 100644 index 0000000..9fc7767 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/pause.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/play.svg b/.config/awesome/widget/mpd/icons/play.svg new file mode 100755 index 0000000..3a56779 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/play.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/prev.svg b/.config/awesome/widget/mpd/icons/prev.svg new file mode 100644 index 0000000..0e39d34 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/prev.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/random-off.svg b/.config/awesome/widget/mpd/icons/random-off.svg new file mode 100755 index 0000000..76f2e06 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/random-off.svg @@ -0,0 +1,64 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/random-on.svg b/.config/awesome/widget/mpd/icons/random-on.svg new file mode 100755 index 0000000..3baf2ed --- /dev/null +++ b/.config/awesome/widget/mpd/icons/random-on.svg @@ -0,0 +1,64 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/repeat-off.svg b/.config/awesome/widget/mpd/icons/repeat-off.svg new file mode 100644 index 0000000..00a4c06 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/repeat-off.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/repeat-on.svg b/.config/awesome/widget/mpd/icons/repeat-on.svg new file mode 100644 index 0000000..6917ca6 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/repeat-on.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/mpd/icons/vinyl.svg b/.config/awesome/widget/mpd/icons/vinyl.svg new file mode 100755 index 0000000..d26a4a8 --- /dev/null +++ b/.config/awesome/widget/mpd/icons/vinyl.svg @@ -0,0 +1,5698 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/mpd/init.lua b/.config/awesome/widget/mpd/init.lua new file mode 100755 index 0000000..eb4d25b --- /dev/null +++ b/.config/awesome/widget/mpd/init.lua @@ -0,0 +1,73 @@ +local gears = require('gears') +local awful = require('awful') +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/mpd/icons/' +local clickable_container = require('widget.clickable-container') +local music_box = require('widget.mpd.music-box') +local toggle_music_box = music_box.toggle_music_box + +local return_button = function() + local widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'music.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + local music_tooltip = awful.tooltip + { + objects = {widget_button}, + text = 'None', + mode = 'outside', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + align = 'right', + preferred_positions = {'right', 'left', 'top', 'bottom'} + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + music_tooltip.visible = false + awesome.emit_signal('widget::music', 'mouse') + end + ) + ) + ) + + widget_button:connect_signal( + "mouse::enter", + function() + awful.spawn.easy_async_with_shell( + 'mpc status', + function(stdout) + music_tooltip.text = string.gsub(stdout, '\n$', '') + end + ) + end + ) + + + return widget_button + +end + +return return_button diff --git a/.config/awesome/widget/mpd/mpd-music-updater.lua b/.config/awesome/widget/mpd/mpd-music-updater.lua new file mode 100755 index 0000000..c155caf --- /dev/null +++ b/.config/awesome/widget/mpd/mpd-music-updater.lua @@ -0,0 +1,460 @@ +local gears = require('gears') +local awful = require('awful') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/mpd/icons/' +local ui_content = require('widget.mpd.content') + +local album_cover = ui_content.album_cover +local prog_bar = ui_content.progress_bar +local track_time = ui_content.track_time +local song_info = ui_content.song_info +local vol_slider = ui_content.volume_slider +local media_buttons = ui_content.media_buttons + +local apps = require('configuration.apps') + +local update_cover = function() + + local extract_script = [=[ + MUSIC_DIR="$(xdg-user-dir MUSIC)" + TMP_DIR="/tmp/awesomewm/${USER}/" + TMP_COVER_PATH=${TMP_DIR}"cover.jpg" + TMP_SONG="${TMP_DIR}current-song" + + CHECK_EXIFTOOL=$(command -v exiftool) + + if [ ! -d "${TMP_DIR}" ]; then + mkdir -p "${TMP_DIR}"; + fi + + if [ ! -z "$CHECK_EXIFTOOL" ]; then + + SONG="$MUSIC_DIR/$(mpc -p 6600 --format "%file%" current)" + PICTURE_TAG="-Picture" + + if [[ "$SONG" == *".m4a" ]]; then + PICTURE_TAG="-CoverArt" + fi + + # Extract album cover using perl-image-exiftool + exiftool -b "$PICTURE_TAG" "$SONG" > "$TMP_COVER_PATH" + + else + + #Extract image using ffmpeg + cp "$MUSIC_DIR/$(mpc --format %file% current)" "$TMP_SONG" + + ffmpeg \ + -hide_banner \ + -loglevel 0 \ + -y \ + -i "$TMP_SONG" \ + -vf scale=300:-1 \ + "$TMP_COVER_PATH" > /dev/null 2>&1 + + rm "$TMP_SONG" + fi + + img_data=$(identify $TMP_COVER_PATH 2>&1) + + # Delete the cover.jpg if it's not a valid image + if [[ $img_data == *"insufficient"* ]]; then + rm $TMP_COVER_PATH + fi + + if [ -f $TMP_COVER_PATH ]; then + echo $TMP_COVER_PATH; + fi + ]=] + + awful.spawn.easy_async_with_shell( + extract_script, + function(stdout) + local album_icon = widget_icon_dir .. 'vinyl.svg' + + if not (stdout == nil or stdout == '') then + album_icon = stdout:gsub('%\n', '') + end + + album_cover.cover:set_image(gears.surface.load_uncached(album_icon)) + + album_cover:emit_signal('widget::redraw_needed') + album_cover:emit_signal('widget::layout_changed') + + collectgarbage('collect') + end + ) +end + +local update_progress_bar = function() + awful.spawn.easy_async_with_shell( + [[ + mpc status | awk 'NR==2 { split($4, a); print a[1]}' | tr -d '[\%\(\)]' + ]], + function(stdout) + local progress_bar = prog_bar.music_bar + if stdout ~= nil then + progress_bar:set_value(tonumber(stdout)) + else + progress_bar:set_value(0) + end + end + ) +end + +local update_time_progress = function() + awful.spawn.easy_async_with_shell( + [[ + mpc status | awk 'NR==2 { split($3, a, "/"); print a[1]}' | tr -d '[\%\(\)]' + ]], + function(stdout) + local time_status = track_time.time_status + if stdout ~= nil then + time_status:set_text(tostring(stdout)) + else + time_status:set_text('00:00') + end + end + ) + +end + +local update_time_duration = function() + awful.spawn.easy_async_with_shell( + [[ + mpc --format %time% current + ]], + function(stdout) + local time_duration = track_time.time_duration + if stdout ~= nil then + time_duration:set_text(tostring(stdout)) + else + time_duration:set_text('99:59') + end + end + ) +end + +local update_file = function() + awful.spawn.easy_async_with_shell( + [[ + mpc -f %file% current + ]], + function(stdout) + file_name = stdout:gsub('%\n','') + end + ) + return file_name +end + +local update_title = function() + + awful.spawn.easy_async_with_shell( + [[ + mpc -f %title% current + ]], + function(stdout) + + -- Remove new lines + local title = stdout:gsub('%\n', '') + + local title_widget = song_info.music_title + local title_text = song_info.music_title:get_children_by_id('title')[1] + + -- Make sure it's not null + if not (title == nil or title == '') then + title_text:set_text(title) + else + + awful.spawn.easy_async_with_shell( + [[ + mpc -f %file% current + ]], + function(stdout) + + if not (stdout == nil or stdout == '') then + + file_name = stdout:gsub('%\n','') + + file_name = file_name:sub(1, title:len() - 5) .. '' + + title_text:set_text(file_name) + + else + -- Set title + title_text:set_text('Play some music!') + + end + title_widget:emit_signal('widget::redraw_needed') + title_widget:emit_signal('widget::layout_changed') + end + ) + + end + + title_widget:emit_signal('widget::redraw_needed') + title_widget:emit_signal('widget::layout_changed') + + collectgarbage('collect') + end + ) +end + +local update_artist = function() + awful.spawn.easy_async_with_shell( + [[ + mpc -f %artist% current + ]], + function(stdout) + + -- Remove new lines + local artist = stdout:gsub('%\n', '') + + local artist_widget = song_info.music_artist + + local artist_text = artist_widget:get_children_by_id('artist')[1] + + if not (artist == nil or artist == '') then + + artist_text:set_text(artist) + + else + + + awful.spawn.easy_async_with_shell( + [[ + mpc -f %file% current + ]], + function(stdout) + if not (stdout == nil or stdout == '') then + + artist_text:set_text('unknown artist') + + else + artist_text:set_text('or play some porn?') + + end + artist_widget:emit_signal('widget::redraw_needed') + artist_widget:emit_signal('widget::layout_changed') + end + ) + end + + artist_widget:emit_signal('widget::redraw_needed') + artist_widget:emit_signal('widget::layout_changed') + end + ) +end + +local update_volume_slider = function() + awful.spawn.easy_async_with_shell( + [[ + mpc volume + ]], + function(stdout) + local volume_slider = vol_slider.vol_slider + if stdout:match('n/a') then + return + end + volume_slider:set_value(tonumber(stdout:match('%d+'))) + end + ) +end + +local check_if_playing = function() + awful.spawn.easy_async_with_shell( + [[ + mpc status | awk 'NR==2' | grep -o playing + ]], + function(stdout) + local play_button_img = media_buttons.play_button_image.play + if not (stdout == nil or stdout == '') then + play_button_img:set_image(widget_icon_dir .. 'pause.svg') + update_volume_slider() + else + play_button_img:set_image(widget_icon_dir .. 'play.svg') + end + end + ) +end + +local check_repeat_status = function() + awful.spawn.easy_async_with_shell( + [[ + mpc status | sed -n '/random/p' | cut -c23-24 | sed 's/^[ \t]*//' + ]], + function(stdout) + local repeat_button_img = media_buttons.repeat_button_image.rep + if stdout:match('on') then + repeat_button_img:set_image(widget_icon_dir .. 'repeat-on.svg') + else + repeat_button_img:set_image(widget_icon_dir .. 'repeat-off.svg') + end + end + ) +end + +local check_random_status = function() + awful.spawn.easy_async_with_shell( + [[ + mpc status | sed -n '/random/p' | cut -c37-38 | sed 's/^[ \t]*//' + ]], + function(stdout) + + local random_button_image = media_buttons.random_button_image.rand + + if stdout:match("on") then + random_button_image:set_image(widget_icon_dir .. 'random-on.svg') + else + random_button_image:set_image(widget_icon_dir .. 'random-off.svg') + end + end + ) +end + +vol_slider.vol_slider:connect_signal( + 'property::value', + function() + awful.spawn.easy_async_with_shell( + 'mpc volume ' .. vol_slider.vol_slider:get_value(), + function() end + ) + end +) + +local update_all_content = function() + update_progress_bar() + update_time_progress() + update_time_duration() + update_title() + update_artist() + update_cover() + check_if_playing() + check_repeat_status() + check_random_status() + update_volume_slider() +end + +-- Update progress bar and time every N seconds +gears.timer.start_new( + 10, + function() + update_progress_bar() + update_time_progress() + return true + end +) + +local mpd_startup = [[ +# Let's make sure that MPD is running. +if [ -z $(pgrep mpd) ]; then mpd; fi +]] + +local mpd_change_event_listener = [[ +sh -c ' +mpc idleloop player +' +]] + +local kill_mpd_change_event_listener = [[ +ps x | +grep "mpc idleloop player" | +grep -v grep | +awk '{print $1}' | +xargs kill +]] + +awful.spawn.easy_async_with_shell( + mpd_startup, + function () + awful.spawn.easy_async_with_shell( + kill_mpd_change_event_listener, + function () + update_all_content() + awful.spawn.with_line_callback( + mpd_change_event_listener, + { + stdout = function(line) + update_all_content() + end + } + ) + end + ) + end +) + +media_buttons.play_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('mpc toggle') + end + ) + ) +) + +media_buttons.next_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('mpc next') + end + ) + ) +) + +media_buttons.prev_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('mpc prev') + end + ) + ) +) + +media_buttons.repeat_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.easy_async_with_shell( + 'mpc repeat', + function () + check_repeat_status() + end + ) + end + ) + ) +) + +media_buttons.random_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.easy_async_with_shell( + 'mpc random', + function () + check_random_status() + end + ) + end + ) + ) +) diff --git a/.config/awesome/widget/mpd/music-box.lua b/.config/awesome/widget/mpd/music-box.lua new file mode 100755 index 0000000..150ded8 --- /dev/null +++ b/.config/awesome/widget/mpd/music-box.lua @@ -0,0 +1,158 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local music_func = {} + +screen.connect_signal('request::desktop_decoration', function(s) + + -- Set music box geometry + local music_box_margin = dpi(5) + local music_box_height = dpi(375) + local music_box_width = dpi(260) + local music_box_x = nil + + + s.musicpop = awful.popup { + widget = { + -- Removing this block will cause an error... + }, + ontop = true, + visible = false, + type = 'dock', + screen = s, + width = music_box_width, + height = music_box_height, + maximum_width = music_box_width, + maximum_height = music_box_height, + offset = dpi(5), + shape = gears.shape.rectangle, + bg = beautiful.transparent, + preferred_anchors = {'middle', 'back', 'front'}, + preferred_positions = {'left', 'right', 'top', 'bottom'}, + + } + + local ui_content = require('widget.mpd.content') + + s.album = ui_content.album_cover + s.progress_bar = ui_content.progress_bar + s.time_track = ui_content.track_time.time_track + s.song_info = ui_content.song_info.music_info + s.media_buttons = ui_content.media_buttons.navigate_buttons + s.volume_slider = ui_content.volume_slider.vol_slider + + s.musicpop : setup { + { + { + layout = wibox.layout.fixed.vertical, + expand = 'none', + spacing = dpi(8), + { + s.album, + bottom = dpi(5), + widget = wibox.container.margin, + }, + { + layout = wibox.layout.fixed.vertical, + { + spacing = dpi(4), + layout = wibox.layout.fixed.vertical, + s.progress_bar, + s.time_track, + }, + s.song_info, + s.media_buttons, + s.volume_slider, + }, + }, + top = dpi(15), + left = dpi(15), + right = dpi(15), + widget = wibox.container.margin + + }, + bg = beautiful.background, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect( + cr, width, height, true, true, true, true, beautiful.groups_radius + ) + end, + widget = wibox.container.background() + } + + s.backdrop_music = wibox { + ontop = true, + visible = false, + screen = s, + type = 'utility', + input_passthrough = false, + bg = beautiful.transparent, + x = s.geometry.x, + y = s.geometry.y, + width = s.geometry.width, + height = s.geometry.height + } + + local toggle_music_box = function(type) + + local focused = awful.screen.focused() + local music_box = focused.musicpop + local music_backdrop = focused.backdrop_music + + if music_box.visible then + music_backdrop.visible = not music_backdrop.visible + music_box.visible = not music_box.visible + + else + + if type == 'keyboard' then + music_backdrop.visible = true + music_box.visible = true + awful.placement.top_right( + music_box, + { + margins = { + top = dpi(5), + right = dpi(music_box_x or 5) + }, + honor_workarea = true + }) + else + local widget_button = mouse.current_widget_geometry + + music_backdrop.visible = true + music_box:move_next_to(widget_button) + music_box_x = (focused.geometry.width - music_box.x) - music_box_width + end + end + end + + awesome.connect_signal( + 'widget::music', + function(type) + toggle_music_box(type) + end + ) + + s.backdrop_music:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_music_box() + end + ) + ) + ) +end) + + +music_func.toggle_music_box = toggle_music_box + +local mpd_updater = require('widget.mpd.mpd-music-updater') + +return music_func diff --git a/.config/awesome/widget/mpd/spotify-music-updater.lua b/.config/awesome/widget/mpd/spotify-music-updater.lua new file mode 100644 index 0000000..40331f6 --- /dev/null +++ b/.config/awesome/widget/mpd/spotify-music-updater.lua @@ -0,0 +1,324 @@ +local gears = require('gears') +local awful = require('awful') +local naughty = require('naughty') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/music/icons/' + +local ui_content = require('widget.music.content') + +local album_cover = ui_content.album_cover +local prog_bar = ui_content.progress_bar +local track_time = ui_content.track_time +local song_info = ui_content.song_info +local vol_slider = ui_content.volume_slider +local media_buttons = ui_content.media_buttons + +-- We can't set/get the data for these +-- So let's hide them + +prog_bar.visible = false +track_time.time_status.visible = false +track_time.time_duration.visible = false +media_buttons.repeat_button.visible = false +media_buttons.random_button.visible = false + + +local update_cover = function() + local get_art_url = [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \ + string:'org.mpris.MediaPlayer2.Player' string:'Metadata' | + egrep -A 1 "artUrl"| egrep -v "artUrl" | awk -F '"' '{print $2}' | + sed -e 's/open.spotify.com/i.scdn.co/g' + ]] + + awful.spawn.easy_async_with_shell( + get_art_url, + function(link) + + local download_art = [[ + tmp_dir="/tmp/awesomewm/${USER}/" + tmp_cover_path=${tmp_dir}"cover.jpg" + + if [ ! -d $tmp_dir ]; then + mkdir -p $tmp_dir; + fi + + if [ -f $tmp_cover_path]; then + rm $tmp_cover_path + fi + + wget -O $tmp_cover_path ]] ..link .. [[ + + echo $tmp_cover_path + ]] + + awful.spawn.easy_async_with_shell( + download_art, + function(stdout) + + local album_icon = stdout:gsub('%\n', '') + + album_cover.cover:set_image(gears.surface.load_uncached(album_icon)) + + album_cover:emit_signal("widget::redraw_needed") + album_cover:emit_signal("widget::layout_changed") + + collectgarbage('collect') + end + ) + end + ) +end + + +local update_title = function() + awful.spawn.easy_async_with_shell( + [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata' | + egrep -A 1 "title" | egrep -v "title" | awk -F '"' '{print $2}' + ]], + function(stdout) + + local title = stdout:gsub('%\n', '') + + local title_widget = song_info.music_title + + local title_text = song_info.music_title:get_children_by_id('title')[1] + + title_text:set_text(title) + + title_widget:emit_signal("widget::redraw_needed") + title_widget:emit_signal("widget::layout_changed") + + collectgarbage('collect') + end + ) +end + + +local update_artist = function() + + + awful.spawn.easy_async_with_shell( + [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'| + egrep -A 2 "artist" | egrep -v "artist" | egrep -v "array" | awk -F '"' '{print $2}' + ]], + function(stdout) + + -- Remove new lines + local artist = stdout:gsub('%\n', '') + + if (stdout == nil or stdout == '') then + artist = 'Advertisement' + end + + local artist_widget = song_info.music_artist + + local artist_text = artist_widget:get_children_by_id('artist')[1] + + artist_text:set_text(artist) + + artist_widget:emit_signal("widget::redraw_needed") + artist_widget:emit_signal("widget::layout_changed") + + collectgarbage('collect') + end + ) +end + + +local update_volume_slider = function() + +-- Stop. Don't indent. +-- It's python. Nuff said + local get_volume = [[ +python - < 100: + arg = 100 + subprocess.run(['pactl', 'set-sink-input-volume', sink_id, str(arg) + '%']) + +END + ]] + + awful.spawn.easy_async_with_shell( + set_volume, + function(stdout) end + ) + +end + + +vol_slider.vol_slider:connect_signal( + 'property::value', + function() + local volume_slider = vol_slider.vol_slider + set_spotify_volume(tostring(volume_slider:get_value())) + end +) + + +local update_all_content = function() + -- Add a delay + gears.timer.start_new(2, function() + update_title() + update_artist() + update_cover() + check_if_playing() + update_volume_slider() + end) +end + + +update_all_content() + + +media_buttons.play_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.easy_async_with_shell( + [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause + ]], + function() + check_if_playing() + end + ) + end + ) + ) +) + + +media_buttons.next_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.easy_async_with_shell( + [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next + ]], + function() + update_all_content() + end + ) + end + ) + ) +) + + +media_buttons.prev_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.easy_async_with_shell( + [[ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous + ]], + function() + update_all_content() + end + ) + end + ) + ) +) \ No newline at end of file diff --git a/.config/awesome/widget/network/icons/airplane-mode-off.svg b/.config/awesome/widget/network/icons/airplane-mode-off.svg new file mode 100644 index 0000000..7a4c91c --- /dev/null +++ b/.config/awesome/widget/network/icons/airplane-mode-off.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/airplane-mode.svg b/.config/awesome/widget/network/icons/airplane-mode.svg new file mode 100644 index 0000000..70fc89d --- /dev/null +++ b/.config/awesome/widget/network/icons/airplane-mode.svg @@ -0,0 +1,62 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/loading.svg b/.config/awesome/widget/network/icons/loading.svg new file mode 100755 index 0000000..cd7bc0e --- /dev/null +++ b/.config/awesome/widget/network/icons/loading.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-off.svg b/.config/awesome/widget/network/icons/wifi-off.svg new file mode 100755 index 0000000..dbcbc7a --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-off.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg new file mode 100755 index 0000000..7a8de11 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-1-alert.svg @@ -0,0 +1,71 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg new file mode 100755 index 0000000..9bcf910 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-1-lock.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-1.svg b/.config/awesome/widget/network/icons/wifi-strength-1.svg new file mode 100755 index 0000000..9e90049 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-1.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg new file mode 100755 index 0000000..970987a --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-2-alert.svg @@ -0,0 +1,71 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg new file mode 100755 index 0000000..cbedd27 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-2-lock.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-2.svg b/.config/awesome/widget/network/icons/wifi-strength-2.svg new file mode 100755 index 0000000..e65871e --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-2.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg new file mode 100755 index 0000000..e1b5a5f --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-3-alert.svg @@ -0,0 +1,71 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg new file mode 100755 index 0000000..865d01a --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-3-lock.svg @@ -0,0 +1,62 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-3.svg b/.config/awesome/widget/network/icons/wifi-strength-3.svg new file mode 100755 index 0000000..cec90d5 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-3.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg new file mode 100755 index 0000000..2d9d47d --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-4-alert.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg b/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg new file mode 100755 index 0000000..fb51f35 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-4-lock.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-4.svg b/.config/awesome/widget/network/icons/wifi-strength-4.svg new file mode 100755 index 0000000..259a3a9 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-4.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg new file mode 100755 index 0000000..3e4c33a --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-alert-outline.svg @@ -0,0 +1,48 @@ + +image/svg+xml + + \ No newline at end of file diff --git a/.config/awesome/widget/network/icons/wifi-strength-alert.svg b/.config/awesome/widget/network/icons/wifi-strength-alert.svg new file mode 100755 index 0000000..ca80f6c --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-alert.svg @@ -0,0 +1,65 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-empty.svg b/.config/awesome/widget/network/icons/wifi-strength-empty.svg new file mode 100755 index 0000000..0a1380a --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-empty.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg new file mode 100755 index 0000000..3edc636 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-lock-outline.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg new file mode 100755 index 0000000..2f9b636 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-off-outline.svg @@ -0,0 +1,48 @@ + +image/svg+xml + + \ No newline at end of file diff --git a/.config/awesome/widget/network/icons/wifi-strength-off.svg b/.config/awesome/widget/network/icons/wifi-strength-off.svg new file mode 100755 index 0000000..12cb043 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-off.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wifi-strength-outline.svg b/.config/awesome/widget/network/icons/wifi-strength-outline.svg new file mode 100755 index 0000000..00fcd26 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi-strength-outline.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/network/icons/wifi.svg b/.config/awesome/widget/network/icons/wifi.svg new file mode 100755 index 0000000..7887868 --- /dev/null +++ b/.config/awesome/widget/network/icons/wifi.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.config/awesome/widget/network/icons/wired-alert.svg b/.config/awesome/widget/network/icons/wired-alert.svg new file mode 100755 index 0000000..60ad378 --- /dev/null +++ b/.config/awesome/widget/network/icons/wired-alert.svg @@ -0,0 +1,63 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wired-off.svg b/.config/awesome/widget/network/icons/wired-off.svg new file mode 100755 index 0000000..35481c0 --- /dev/null +++ b/.config/awesome/widget/network/icons/wired-off.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/icons/wired.svg b/.config/awesome/widget/network/icons/wired.svg new file mode 100755 index 0000000..00441ac --- /dev/null +++ b/.config/awesome/widget/network/icons/wired.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/network/init.lua b/.config/awesome/widget/network/init.lua new file mode 100755 index 0000000..105dd50 --- /dev/null +++ b/.config/awesome/widget/network/init.lua @@ -0,0 +1,358 @@ +---------------------------------------------------------------------------- +--- Simple Network Widget +-- +-- Depends: iproute2, iw +-- +-- +-- @author manilarome <gerome.matilla07@gmail.com> +-- @copyright 2020 manilarome +-- @widget network +---------------------------------------------------------------------------- + +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local naughty = require('naughty') +local dpi = require('beautiful').xresources.apply_dpi +local apps = require('configuration.apps') +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/network/icons/' +local config = require('configuration.config') + +-- Configuration +local interfaces = { + wlan_interface = config.widget.network.wireless_interface or 'wlan0', + lan_interface = config.widget.network.wired_interface or 'enp0s25' +} + +local network_mode = nil + +local return_button = function() + + local update_notify_no_access = true + local notify_no_access_quota = 0 + + local startup = true + local reconnect_startup = true + local notify_new_wifi_conn = false + + local widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'wifi-strength-off' .. '.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn(apps.default.network_manager, false) + end + ) + ) + ) + + local network_tooltip = awful.tooltip { + text = 'Loading...', + objects = {widget_button}, + mode = 'outside', + align = 'right', + preferred_positions = {'left', 'right', 'top', 'bottom'}, + margin_leftright = dpi(8), + margin_topbottom = dpi(8) + } + + local check_internet_health = [=[ + status_ping=0 + + packets="$(ping -q -w2 -c2 1.1.1.1 | grep -o "100% packet loss")" + if [ ! -z "${packets}" ]; + then + status_ping=0 + else + status_ping=1 + fi + + if [ $status_ping -eq 0 ]; + then + echo 'Connected but no internet' + fi + ]=] + + -- Awesome/System startup + local update_startup = function() + if startup then + startup = false + end + end + + -- Consider reconnecting a startup + local update_reconnect_startup = function(status) + reconnect_startup = status + end + + -- Update tooltip + local update_tooltip = function(message) + network_tooltip:set_markup(message) + end + + local network_notify = function(message, title, app_name, icon) + naughty.notification({ + message = message, + title = title, + app_name = app_name, + icon = icon + }) + end + + -- Wireless mode / Update + local update_wireless = function() + + network_mode = 'wireless' + + -- Create wireless connection notification + local notify_connected = function(essid) + local message = 'You are now connected to \"' .. essid .. '\"' + local title = 'Connection Established' + local app_name = 'System Notification' + local icon = widget_icon_dir .. 'wifi.svg' + network_notify(message, title, app_name, icon) + end + + -- Get wifi essid and bitrate + local update_wireless_data = function(strength, healthy) + awful.spawn.easy_async_with_shell( + [[ + iw dev ]] .. interfaces.wlan_interface .. [[ link + ]], + function(stdout) + local essid = stdout:match('SSID: (.-)\n') or 'N/A' + local bitrate = stdout:match('tx bitrate: (.+/s)') or 'N/A' + local message = 'Connected to: ' .. (essid or 'Loading...*') .. + '\nWireless Interface: ' .. interfaces.wlan_interface .. + '\nWiFi-Strength: ' .. tostring(wifi_strength) .. '%' .. + '\nBit rate: ' .. tostring(bitrate) .. '' + + if healthy then + update_tooltip(message) + else + update_tooltip('Connected but no internet!\n' .. message) + end + + if reconnect_startup or startup then + notify_connected(essid) + update_reconnect_startup(false) + end + end + ) + end + + -- Update wifi icon based on wifi strength and health + local update_wireless_icon = function(strength) + awful.spawn.easy_async_with_shell( + check_internet_health, + function(stdout) + local widget_icon_name = 'wifi-strength' + if not stdout:match('Connected but no internet') then + if startup or reconnect_startup then + awesome.emit_signal('system::network_connected') + end + widget_icon_name = widget_icon_name .. '-' .. tostring(strength) + update_wireless_data(wifi_strength_rounded, true) + else + widget_icon_name = widget_icon_name .. '-' .. tostring(strength) .. '-alert' + update_wireless_data(wifi_strength_rounded, false) + end + widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg') + end + ) + end + + -- Get wifi strength + local update_wireless_strength = function() + awful.spawn.easy_async_with_shell( + [[ + awk 'NR==3 {printf "%3.0f" ,($3/70)*100}' /proc/net/wireless + ]], + function(stdout) + if not tonumber(stdout) then + return + end + wifi_strength = tonumber(stdout) + local wifi_strength_rounded = math.floor(wifi_strength / 25 + 0.5) + update_wireless_icon(wifi_strength_rounded) + end + ) + end + + update_wireless_strength() + update_startup() + end + + local update_wired = function() + + network_mode = 'wired' + + local notify_connected = function() + local message = 'Connected to internet with \"' .. interfaces.lan_interface .. '\"' + local title = 'Connection Established' + local app_name = 'System Notification' + local icon = widget_icon_dir .. 'wired.svg' + network_notify(message, title, app_name, icon) + end + + awful.spawn.easy_async_with_shell( + check_internet_health, + function(stdout) + + local widget_icon_name = 'wired' + + if stdout:match('Connected but no internet') then + widget_icon_name = widget_icon_name .. '-alert' + update_tooltip( + 'Connected but no internet!' .. + '\nEthernet Interface: ' .. interfaces.lan_interface .. '' + ) + else + update_tooltip('Ethernet Interface: ' .. interfaces.lan_interface .. '') + if startup or reconnect_startup then + awesome.emit_signal('system::network_connected') + notify_connected() + update_startup(false) + end + update_reconnect_startup(false) + end + widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg') + end + ) + end + + local update_disconnected = function() + + local notify_wireless_disconnected = function(essid) + local message = 'Wi-Fi network has been disconnected' + local title = 'Connection Disconnected' + local app_name = 'System Notification' + local icon = widget_icon_dir .. 'wifi-strength-off.svg' + network_notify(message, title, app_name, icon) + end + + local notify_wired_disconnected = function(essid) + local message = 'Ethernet network has been disconnected' + local title = 'Connection Disconnected' + local app_name = 'System Notification' + local icon = widget_icon_dir .. 'wired-off.svg' + network_notify(message, title, app_name, icon) + end + + local widget_icon_name = 'wifi-strength-off' + + if network_mode == 'wireless' then + widget_icon_name = 'wifi-strength-off' + if not reconnect_startup then + update_reconnect_startup(true) + notify_wireless_disconnected() + end + elseif network_mode == 'wired' then + widget_icon_name = 'wired-off' + if not reconnect_startup then + update_reconnect_startup(true) + notify_wired_disconnected() + end + end + update_tooltip('Network is currently disconnected') + widget.icon:set_image(widget_icon_dir .. widget_icon_name .. '.svg') + end + + local check_network_mode = function() + awful.spawn.easy_async_with_shell( + [=[ + wireless="]=] .. tostring(interfaces.wlan_interface) .. [=[" + wired="]=] .. tostring(interfaces.lan_interface) .. [=[" + net="/sys/class/net/" + + wired_state="down" + wireless_state="down" + network_mode="" + + # Check network state based on interface's operstate value + function check_network_state() { + # Check what interface is up + if [[ "${wireless_state}" == "up" ]]; + then + network_mode='wireless' + elif [[ "${wired_state}" == "up" ]]; + then + network_mode='wired' + else + network_mode='No internet connection' + fi + } + + # Check if network directory exist + function check_network_directory() { + if [[ -n "${wireless}" && -d "${net}${wireless}" ]]; + then + wireless_state="$(cat "${net}${wireless}/operstate")" + fi + if [[ -n "${wired}" && -d "${net}${wired}" ]]; then + wired_state="$(cat "${net}${wired}/operstate")" + fi + check_network_state + } + + # Start script + function print_network_mode() { + # Call to check network dir + check_network_directory + # Print network mode + printf "${network_mode}" + } + + print_network_mode + + ]=], + function(stdout) + local mode = stdout:gsub('%\n', '') + if stdout:match('No internet connection') then + update_disconnected() + elseif stdout:match('wireless') then + update_wireless() + elseif stdout:match('wired') then + update_wired() + end + end + ) + end + + local network_updater = gears.timer { + timeout = 5, + autostart = true, + call_now = true, + callback = function() + check_network_mode() + end + } + + return widget_button +end + +return return_button diff --git a/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua b/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua new file mode 100644 index 0000000..447f95d --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/empty-notifbox.lua @@ -0,0 +1,65 @@ +-- This returns the "Wow, such empty." message. + +local wibox = require('wibox') + +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = require('gears').filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/notif-center/icons/' + +local empty_notifbox = wibox.widget { + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + { + expand = 'none', + layout = wibox.layout.align.horizontal, + nil, + { + image = widget_icon_dir .. 'empty-notification' .. '.svg', + resize = true, + forced_height = dpi(35), + forced_width = dpi(35), + widget = wibox.widget.imagebox, + }, + nil + }, + { + text = 'Wow, such empty.', + font = 'Inter Bold 14', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + }, + { + text = 'Come back later.', + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + }, + }, + margins = dpi(20), + widget = wibox.container.margin + +} + + +local separator_for_empty_msg = wibox.widget +{ + orientation = 'vertical', + opacity = 0.0, + widget = wibox.widget.separator +} + +-- Make empty_notifbox center +local centered_empty_notifbox = wibox.widget { + expand = 'none', + layout = wibox.layout.align.vertical, + separator_for_empty_msg, + empty_notifbox, + separator_for_empty_msg +} + +return centered_empty_notifbox + diff --git a/.config/awesome/widget/notif-center/build-notifbox/init.lua b/.config/awesome/widget/notif-center/build-notifbox/init.lua new file mode 100644 index 0000000..c4aa484 --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/init.lua @@ -0,0 +1,80 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local naughty = require('naughty') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/notif-center/icons/' + +local empty_notifbox = require('widget.notif-center.build-notifbox.empty-notifbox') +local notifbox_scroller = require('widget.notif-center.build-notifbox.notifbox-scroller') + +local notif_core = {} + +notif_core.remove_notifbox_empty = true + +notif_core.notifbox_layout = wibox.widget { + layout = wibox.layout.fixed.vertical, + spacing = dpi(7), + empty_notifbox +} + +notifbox_scroller(notif_core.notifbox_layout) + +notif_core.reset_notifbox_layout = function() + notif_core.notifbox_layout:reset() + notif_core.notifbox_layout:insert(1, empty_notifbox) + notif_core.remove_notifbox_empty = true +end + +local notifbox_add = function(n, notif_icon, notifbox_color) + if #notif_core.notifbox_layout.children == 1 and notif_core.remove_notifbox_empty then + notif_core.notifbox_layout:reset(notif_core.notifbox_layout) + notif_core.remove_notifbox_empty = false + end + + local notifbox_box = require('widget.notif-center.build-notifbox.notifbox-builder') + notif_core.notifbox_layout:insert( + 1, + notifbox_box( + n, + notif_icon, + n.title, + n.message, + n.app_name, + notifbox_color + ) + ) +end + +local notifbox_add_expired = function(n, notif_icon, notifbox_color) + n:connect_signal( + 'destroyed', + function(self, reason, keep_visble) + if reason == 1 then + notifbox_add(n, notif_icon, notifbox_color) + end + end + ) +end + +naughty.connect_signal( + 'request::display', + function(n) + local notifbox_color = beautiful.groups_bg + if n.urgency == 'critical' then + notifbox_color = n.bg .. '66' + end + + local notif_icon = n.icon or n.app_icon + if not notif_icon then + notif_icon = widget_icon_dir .. 'new-notif' .. '.svg' + end + + notifbox_add_expired(n, notif_icon, notifbox_color) + end +) + +return notif_core diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua new file mode 100644 index 0000000..e721232 --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-builder.lua @@ -0,0 +1,177 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = beautiful.xresources.apply_dpi + +local builder = require('widget.notif-center.build-notifbox.notifbox-ui-elements') +local notifbox_core = require('widget.notif-center.build-notifbox') + +local notifbox_layout = notifbox_core.notifbox_layout +local remove_notifbox_empty = notifbox_core.remove_notifbox_empty +local reset_notifbox_layout = notifbox_core.reset_notifbox_layout + +local return_date_time = function(format) + return os.date(format) +end + +local parse_to_seconds = function(time) + local hourInSec = tonumber(string.sub(time, 1, 2)) * 3600 + local minInSec = tonumber(string.sub(time, 4, 5)) * 60 + local getSec = tonumber(string.sub(time, 7, 8)) + return (hourInSec + minInSec + getSec) +end + +notifbox_box = function(notif, icon, title, message, app, bgcolor) + + local time_of_pop = return_date_time('%H:%M:%S') + local exact_time = return_date_time('%I:%M %p') + local exact_date_time = return_date_time('%b %d, %I:%M %p') + + local notifbox_timepop = wibox.widget { + id = 'time_pop', + markup = nil, + font = 'Inter Regular 10', + align = 'left', + valign = 'center', + visible = true, + widget = wibox.widget.textbox + } + + local notifbox_dismiss = builder.notifbox_dismiss() + + local time_of_popup = gears.timer { + timeout = 60, + call_now = true, + autostart = true, + callback = function() + + local time_difference = nil + + time_difference = parse_to_seconds(return_date_time('%H:%M:%S')) - parse_to_seconds(time_of_pop) + time_difference = tonumber(time_difference) + + if time_difference < 60 then + notifbox_timepop:set_markup('now') + + elseif time_difference >= 60 and time_difference < 3600 then + local time_in_minutes = math.floor(time_difference / 60) + notifbox_timepop:set_markup(time_in_minutes .. 'm ago') + + elseif time_difference >= 3600 and time_difference < 86400 then + notifbox_timepop:set_markup(exact_time) + + elseif time_difference >= 86400 then + notifbox_timepop:set_markup(exact_date_time) + return false + + end + + collectgarbage('collect') + end + } + + local notifbox_template = wibox.widget { + id = 'notifbox_template', + expand = 'none', + { + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + { + expand = 'none', + layout = wibox.layout.align.horizontal, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(5), + builder.notifbox_icon(icon), + builder.notifbox_appname(app), + }, + nil, + { + notifbox_timepop, + notifbox_dismiss, + layout = wibox.layout.fixed.horizontal + } + }, + { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + { + builder.notifbox_title(title), + builder.notifbox_message(message), + layout = wibox.layout.fixed.vertical + }, + builder.notifbox_actions(notif), + }, + + }, + margins = dpi(10), + widget = wibox.container.margin + }, + bg = bgcolor, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background, + } + + -- Put the generated template to a container + local notifbox = wibox.widget { + notifbox_template, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background + } + + -- Delete notification box + local notifbox_delete = function() + notifbox_layout:remove_widgets(notifbox, true) + end + + -- Delete notifbox on LMB + notifbox:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + function() + if #notifbox_layout.children == 1 then + reset_notifbox_layout() + else + notifbox_delete() + end + collectgarbage('collect') + end + ) + ) + ) + + -- Add hover, and mouse leave events + notifbox_template:connect_signal( + 'mouse::enter', + function() + notifbox.bg = beautiful.groups_bg + notifbox_timepop.visible = false + notifbox_dismiss.visible = true + end + ) + + notifbox_template:connect_signal( + 'mouse::leave', + function() + notifbox.bg = beautiful.tranparent + notifbox_timepop.visible = true + notifbox_dismiss.visible = false + end + ) + + collectgarbage('collect') + + return notifbox +end + + +return notifbox_box \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua new file mode 100644 index 0000000..3fe79da --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-geometry.lua @@ -0,0 +1,33 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') + +local find_widget_in_wibox = function(wb, widget) + local function find_widget_in_hierarchy(h, widget) + if h:get_widget() == widget then + return h + end + local result + + for _, ch in ipairs(h:get_children()) do + result = result or find_widget_in_hierarchy(ch, widget) + end + return result + end + local h = wb._drawable._widget_hierarchy + return h and find_widget_in_hierarchy(h, widget) +end + + +local focused = awful.screen.focused() +local h = find_widget_in_wibox(focused.top_panel, focused.music) +local x, y, width, height = h:get_matrix_to_device():transform_rectangle(0, 0, h:get_size()) +-- local geo = focused.mywibox:geometry() + + +-- x, y = x + geo.x, y + geo.y + +-- print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height) + + +naughty.notification({message=tostring(height)}) \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua new file mode 100644 index 0000000..f05d323 --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-scroller.lua @@ -0,0 +1,37 @@ +local awful = require('awful') +local gears = require('gears') + +local add_button_event = function(widget) + + widget:buttons( + gears.table.join( + awful.button( + {}, + 4, + nil, + function() + if #widget.children == 1 then + return + end + widget:insert(1, widget.children[#widget.children]) + widget:remove(#widget.children) + end + ), + awful.button( + {}, + 5, + nil, + function() + if #widget.children == 1 then + return + end + widget:insert(#widget.children + 1, widget.children[1]) + widget:remove(1) + end + ) + ) + ) + +end + +return add_button_event \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua b/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua new file mode 100644 index 0000000..ef5e574 --- /dev/null +++ b/.config/awesome/widget/notif-center/build-notifbox/notifbox-ui-elements.lua @@ -0,0 +1,136 @@ +local wibox = require('wibox') +local beautiful = require('beautiful') +local naughty = require('naughty') +local gears = require('gears') + +local dpi = beautiful.xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/notif-center/icons/' + +local clickable_container = require('widget.clickable-container') + +local ui_noti_builder = {} + +-- Notification icon container +ui_noti_builder.notifbox_icon = function(ico_image) + local noti_icon = wibox.widget { + { + id = 'icon', + resize = true, + forced_height = dpi(25), + forced_width = dpi(25), + widget = wibox.widget.imagebox + }, + layout = wibox.layout.fixed.horizontal + } + noti_icon.icon:set_image(ico_image) + return noti_icon +end + +-- Notification title container +ui_noti_builder.notifbox_title = function(title) + return wibox.widget { + markup = title, + font = 'Inter Bold 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + } +end + +-- Notification message container +ui_noti_builder.notifbox_message = function(msg) + return wibox.widget { + markup = msg, + font = 'Inter Regular 11', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + } +end + +-- Notification app name container +ui_noti_builder.notifbox_appname = function(app) + return wibox.widget { + markup = app, + font = 'Inter Bold 12', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + } +end + +-- Notification actions container +ui_noti_builder.notifbox_actions = function(n) + actions_template = wibox.widget { + notification = n, + base_layout = wibox.widget { + spacing = dpi(0), + layout = wibox.layout.flex.horizontal + }, + widget_template = { + { + { + { + { + id = 'text_role', + font = 'Inter Regular 10', + widget = wibox.widget.textbox + }, + widget = wibox.container.place + }, + widget = clickable_container + }, + bg = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + forced_height = 30, + widget = wibox.container.background + }, + margins = 4, + widget = wibox.container.margin + }, + style = { underline_normal = false, underline_selected = true }, + widget = naughty.list.actions, + } + + return actions_template +end + + +-- Notification dismiss button +ui_noti_builder.notifbox_dismiss = function() + + local dismiss_imagebox = wibox.widget { + { + id = 'dismiss_icon', + image = widget_icon_dir .. 'delete.svg', + resize = true, + forced_height = dpi(5), + widget = wibox.widget.imagebox + }, + layout = wibox.layout.fixed.horizontal + } + + local dismiss_button = wibox.widget { + { + dismiss_imagebox, + margins = dpi(5), + widget = wibox.container.margin + }, + widget = clickable_container + } + + local notifbox_dismiss = wibox.widget { + dismiss_button, + visible = false, + bg = beautiful.groups_title_bg, + shape = gears.shape.circle, + widget = wibox.container.background + } + + return notifbox_dismiss +end + + +return ui_noti_builder \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/clear-all/init.lua b/.config/awesome/widget/notif-center/clear-all/init.lua new file mode 100644 index 0000000..7c14657 --- /dev/null +++ b/.config/awesome/widget/notif-center/clear-all/init.lua @@ -0,0 +1,61 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/notif-center/icons/' + +local notifbox_core = require('widget.notif-center.build-notifbox') +local reset_notifbox_layout = notifbox_core.reset_notifbox_layout + +local clear_all_imagebox = wibox.widget { + { + image = widget_icon_dir .. 'clear_all.svg', + resize = true, + forced_height = dpi(20), + forced_width = dpi(20), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local clear_all_button = wibox.widget { + { + clear_all_imagebox, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +clear_all_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + reset_notifbox_layout() + end + ) + ) +) + +local clear_all_button_wrapped = wibox.widget { + nil, + { + clear_all_button, + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +return clear_all_button_wrapped \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/dont-disturb/disturb_status b/.config/awesome/widget/notif-center/dont-disturb/disturb_status new file mode 100644 index 0000000..c508d53 --- /dev/null +++ b/.config/awesome/widget/notif-center/dont-disturb/disturb_status @@ -0,0 +1 @@ +false diff --git a/.config/awesome/widget/notif-center/dont-disturb/init.lua b/.config/awesome/widget/notif-center/dont-disturb/init.lua new file mode 100644 index 0000000..b135b65 --- /dev/null +++ b/.config/awesome/widget/notif-center/dont-disturb/init.lua @@ -0,0 +1,122 @@ +local awful = require('awful') +local naughty = require('naughty') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() + +local widget_dir = config_dir .. 'widget/notif-center/dont-disturb/' +local widget_icon_dir = config_dir .. 'widget/notif-center/icons/' + +_G.dont_disturb = false + +local dont_disturb_imagebox = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'dont-disturb-mode.svg', + resize = true, + forced_height = dpi(20), + forced_width = dpi(20), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local function update_icon() + + local widget_icon_name = nil + local dd_icon = dont_disturb_imagebox.icon + + if dont_disturb then + widget_icon_name = 'toggled-on' + dd_icon:set_image(widget_icon_dir .. 'dont-disturb-mode.svg') + else + widget_icon_name = 'toggled-off' + dd_icon:set_image(widget_icon_dir .. 'notify-mode.svg') + end +end + +local check_disturb_status = function() + + awful.spawn.easy_async_with_shell( + 'cat ' .. widget_dir .. 'disturb_status', + function(stdout) + + local status = stdout + + if status:match('true') then + dont_disturb = true + elseif status:match('false') then + dont_disturb = false + else + dont_disturb = false + awful.spawn.with_shell('echo "false" > ' .. widget_dir .. 'disturb_status') + end + + update_icon() + end + ) +end + +check_disturb_status() + +local toggle_disturb = function() + if dont_disturb then + dont_disturb = false + else + dont_disturb = true + end + awful.spawn.with_shell('echo "' .. tostring(dont_disturb) .. '" > ' .. widget_dir .. 'disturb_status') + update_icon() +end + +local dont_disturb_button = wibox.widget { + { + dont_disturb_imagebox, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +dont_disturb_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + toggle_disturb() + end + ) + ) +) + +local dont_disturb_wrapped = wibox.widget { + nil, + { + dont_disturb_button, + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +-- Create a notification sound +naughty.connect_signal( + 'request::display', + function(n) + if not dont_disturb then + awful.spawn.with_shell('canberra-gtk-play -i message') + end + end +) + +return dont_disturb_wrapped \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/icons/clear_all.svg b/.config/awesome/widget/notif-center/icons/clear_all.svg new file mode 100644 index 0000000..3f5b9b4 --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/clear_all.svg @@ -0,0 +1,91 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/notif-center/icons/delete.svg b/.config/awesome/widget/notif-center/icons/delete.svg new file mode 100644 index 0000000..3f1f88c --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg b/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg new file mode 100644 index 0000000..d5dc170 --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/dont-disturb-mode.svg @@ -0,0 +1,64 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/.config/awesome/widget/notif-center/icons/empty-notification.svg b/.config/awesome/widget/notif-center/icons/empty-notification.svg new file mode 100644 index 0000000..df4154c --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/empty-notification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.config/awesome/widget/notif-center/icons/new-notif.svg b/.config/awesome/widget/notif-center/icons/new-notif.svg new file mode 100644 index 0000000..630b90a --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/new-notif.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/notif-center/icons/notify-mode.svg b/.config/awesome/widget/notif-center/icons/notify-mode.svg new file mode 100644 index 0000000..92b960b --- /dev/null +++ b/.config/awesome/widget/notif-center/icons/notify-mode.svg @@ -0,0 +1,91 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/notif-center/init.lua b/.config/awesome/widget/notif-center/init.lua new file mode 100644 index 0000000..bdc544b --- /dev/null +++ b/.config/awesome/widget/notif-center/init.lua @@ -0,0 +1,38 @@ +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi + +local notif_header = wibox.widget { + text = 'Notification Center', + font = 'Inter Bold 16', + align = 'left', + valign = 'bottom', + widget = wibox.widget.textbox +} + +local notif_center = function(s) + + s.dont_disturb = require('widget.notif-center.dont-disturb') + s.clear_all = require('widget.notif-center.clear-all') + s.notifbox_layout = require('widget.notif-center.build-notifbox').notifbox_layout + + return wibox.widget { + expand = 'none', + layout = wibox.layout.fixed.vertical, + spacing = dpi(10), + { + expand = 'none', + layout = wibox.layout.align.horizontal, + notif_header, + nil, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(5), + s.dont_disturb, + s.clear_all + }, + }, + s.notifbox_layout + } +end + +return notif_center \ No newline at end of file diff --git a/.config/awesome/widget/open-default-app/init.lua b/.config/awesome/widget/open-default-app/init.lua new file mode 100644 index 0000000..bb7ac8a --- /dev/null +++ b/.config/awesome/widget/open-default-app/init.lua @@ -0,0 +1,52 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +local create_open_default_button = function(s) + s.add_button = wibox.widget { + { + { + { + { + image = icons.plus, + resize = true, + widget = wibox.widget.imagebox + }, + margins = dpi(4), + widget = wibox.container.margin + }, + widget = clickable_container + }, + bg = beautiful.transparent, + shape = gears.shape.circle, + widget = wibox.container.background + }, + margins = dpi(4), + widget = wibox.container.margin + } + + s.add_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn( + awful.screen.focused().selected_tag.default_app, + { + tag = mouse.screen.selected_tag + } + ) + end + ) + ) + ) + return s.add_button +end + +return create_open_default_button diff --git a/.config/awesome/widget/package-updater/icons/package-up.svg b/.config/awesome/widget/package-updater/icons/package-up.svg new file mode 100644 index 0000000..2251baa --- /dev/null +++ b/.config/awesome/widget/package-updater/icons/package-up.svg @@ -0,0 +1,48 @@ + +image/svg+xml + + \ No newline at end of file diff --git a/.config/awesome/widget/package-updater/icons/package.svg b/.config/awesome/widget/package-updater/icons/package.svg new file mode 100644 index 0000000..7d4b2f9 --- /dev/null +++ b/.config/awesome/widget/package-updater/icons/package.svg @@ -0,0 +1,48 @@ + +image/svg+xml + + \ No newline at end of file diff --git a/.config/awesome/widget/package-updater/init.lua b/.config/awesome/widget/package-updater/init.lua new file mode 100644 index 0000000..2f52244 --- /dev/null +++ b/.config/awesome/widget/package-updater/init.lua @@ -0,0 +1,105 @@ +local awful = require('awful') +local naughty = require('naughty') +local wibox = require('wibox') +local gears = require('gears') + +local watch = awful.widget.watch + +local apps = require('configuration.apps') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/package-updater/icons/' + +local update_available = false +local number_of_updates_available = nil +local update_package = nil + +local return_button = function() + + local widget = wibox.widget { + { + id = 'icon', + widget = wibox.widget.imagebox, + image = widget_icon_dir .. 'package.svg', + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + + if update_available then + awful.spawn(apps.default.package_manager .. ' --updates', false) + + else + awful.spawn(apps.default.package_manager, false) + + end + end + ) + ) + ) + + awful.tooltip( + { + objects = {widget_button}, + mode = 'outside', + align = 'right', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + timer_function = function() + + if update_available then + return update_package:gsub('\n$', '') + else + return 'We are up-to-date!' + end + + end, + preferred_positions = {'right', 'left', 'top', 'bottom'} + } + ) + + watch( + 'pamac checkupdates', + 60, + function(_, stdout) + number_of_updates_available = tonumber(stdout:match('.-\n'):match('%d*')) + update_package = stdout + local icon_name = nil + if number_of_updates_available ~= nil then + update_available = true + icon_name = 'package-up' + else + update_available = false + icon_name = 'package' + + end + + widget.icon:set_image(widget_icon_dir .. icon_name .. '.svg') + collectgarbage('collect') + end + ) + + return widget_button +end + +return return_button diff --git a/.config/awesome/widget/ram-meter/init.lua b/.config/awesome/widget/ram-meter/init.lua new file mode 100644 index 0000000..c630e81 --- /dev/null +++ b/.config/awesome/widget/ram-meter/init.lua @@ -0,0 +1,60 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') +local watch = require('awful.widget.watch') +local icons = require('theme.icons') + +local dpi = beautiful.xresources.apply_dpi + +local slider = wibox.widget { + nil, + { + id = 'ram_usage', + max_value = 100, + value = 29, + forced_height = dpi(2), + color = beautiful.fg_normal, + background_color = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + widget = wibox.widget.progressbar + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +watch( + 'bash -c "free | grep -z Mem.*Swap.*"', + 10, + function(_, stdout) + local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = + stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)') + slider.ram_usage:set_value(used / total * 100) + collectgarbage('collect') + end +) + +local ram_meter = wibox.widget { + { + { + { + image = icons.memory, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return ram_meter diff --git a/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua b/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua new file mode 100644 index 0000000..5fe2e4b --- /dev/null +++ b/.config/awesome/widget/ram-meter/temperature/temperature-meter.lua @@ -0,0 +1,63 @@ +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local watch = require('awful.widget.watch') +local icons = require('theme.icons') + +local dpi = beautiful.xresources.apply_dpi + +local slider = wibox.widget { + nil, + { + id = 'temp_status', + max_value = 100, + value = 29, + forced_height = dpi(2), + color = beautiful.fg_normal, + background_color = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + widget = wibox.widget.progressbar + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +local max_temp = 80 + +watch( + 'bash -c "cat /sys/class/thermal/thermal_zone0/temp"', + 5, + function(_, stdout) + local temp = stdout:match('(%d+)') + slider.temp_status:set_value((temp / 1000) / max_temp * 100) + collectgarbage('collect') + end +) + + +local temperature_meter = wibox.widget { + { + { + { + image = icons.thermometer, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return temperature_meter diff --git a/.config/awesome/widget/screen-recorder/icons/audio.svg b/.config/awesome/widget/screen-recorder/icons/audio.svg new file mode 100644 index 0000000..2f8668f --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/audio.svg @@ -0,0 +1,71 @@ + +image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/.config/awesome/widget/screen-recorder/icons/back.svg b/.config/awesome/widget/screen-recorder/icons/back.svg new file mode 100644 index 0000000..f0e76e5 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/back.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/icons/close-screen.svg b/.config/awesome/widget/screen-recorder/icons/close-screen.svg new file mode 100644 index 0000000..3f1f88c --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/close-screen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg b/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg new file mode 100644 index 0000000..63134d5 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/recorder-countdown.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-off.svg b/.config/awesome/widget/screen-recorder/icons/recorder-off.svg new file mode 100644 index 0000000..8ade140 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/recorder-off.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/icons/recorder-on.svg b/.config/awesome/widget/screen-recorder/icons/recorder-on.svg new file mode 100644 index 0000000..29800ca --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/recorder-on.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/icons/recording-button.svg b/.config/awesome/widget/screen-recorder/icons/recording-button.svg new file mode 100644 index 0000000..4caa7b3 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/recording-button.svg @@ -0,0 +1,86 @@ + +image/svg+xml + + + + + + + + + + + + \ No newline at end of file diff --git a/.config/awesome/widget/screen-recorder/icons/settings.svg b/.config/awesome/widget/screen-recorder/icons/settings.svg new file mode 100644 index 0000000..2c5a0b9 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/settings.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg b/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg new file mode 100644 index 0000000..986f9dd --- /dev/null +++ b/.config/awesome/widget/screen-recorder/icons/start-recording-button.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/screen-recorder/init.lua b/.config/awesome/widget/screen-recorder/init.lua new file mode 100644 index 0000000..1dabee6 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/init.lua @@ -0,0 +1,9 @@ +local recorder_table = require('widget.screen-recorder.screen-recorder-ui') +require('widget.screen-recorder.screen-recorder-ui-backend') +local screen_rec_toggle_button = recorder_table.screen_rec_toggle_button + +local return_button = function() + return screen_rec_toggle_button +end + +return return_button diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-config.lua b/.config/awesome/widget/screen-recorder/screen-recorder-config.lua new file mode 100644 index 0000000..faf7593 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/screen-recorder-config.lua @@ -0,0 +1,22 @@ +local user_preferences = {} +local config = require('configuration.config') + +-- Screen WIDTHxHEIGHT +user_preferences.user_resolution = config.widget.screen_recorder.resolution or '1366x768' + +-- Offset x,y +user_preferences.user_offset = config.widget.screen_recorder.offset or '0,0' + +-- bool true or false +user_preferences.user_audio = config.widget.screen_recorder.audio or false + +-- String $HOME +user_preferences.user_save_directory = config.widget.screen_recorder.save_directory or '$(xdg-user-dir VIDEOS)/Recordings/' + +-- String +user_preferences.user_mic_lvl = config.widget.screen_recorder.mic_level or '20' + +-- String +user_preferences.user_fps = config.widget.screen_recorder.fps or '30' + +return user_preferences diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua b/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua new file mode 100644 index 0000000..b55ef0a --- /dev/null +++ b/.config/awesome/widget/screen-recorder/screen-recorder-scripts.lua @@ -0,0 +1,169 @@ +local awful = require('awful') +local naughty = require('naughty') +local user_config = require('widget.screen-recorder.screen-recorder-config') +local scripts_tbl = {} +local ffmpeg_pid = nil + +-- Get user settings +scripts_tbl.user_resolution = user_config.user_resolution +scripts_tbl.user_offset = user_config.user_offset +scripts_tbl.user_audio = user_config.user_audio +scripts_tbl.user_dir = user_config.user_save_directory +scripts_tbl.user_mic_lvl = user_config.user_mic_lvl +scripts_tbl.user_fps = user_config.user_fps + +scripts_tbl.update_user_settings = function(res, offset, audio) + scripts_tbl.user_resolution = res + scripts_tbl.user_offset = offset + scripts_tbl.user_audio = audio +end + +scripts_tbl.check_settings = function() + -- For debugging purpose only + -- naughty.notification({ + -- message=scripts_tbl.user_resolution .. ' ' .. scripts_tbl.user_offset .. tostring(scripts_tbl.user_audio) + -- }) +end + +local create_save_directory = function() + + local create_dir_cmd = [[ + dir="]] .. scripts_tbl.user_dir .. [[" + + if [ ! -d "$dir" ]; then + mkdir -p "$dir" + fi + ]] + + awful.spawn.easy_async_with_shell( + create_dir_cmd, + function(stdout) end + ) +end + +create_save_directory() + +local kill_existing_recording_ffmpeg = function() + -- Let's killall ffmpeg instance first after awesome (re)-starts if there's any + awful.spawn.easy_async_with_shell( + [[ + ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill + ]], + function(stdout) end + ) +end + +kill_existing_recording_ffmpeg() + +local turn_on_the_mic = function() + awful.spawn.easy_async_with_shell( + [[ + amixer set Capture cap + amixer set Capture ]].. scripts_tbl.user_mic_lvl ..[[% + ]], + function() end + ) +end + +local ffmpeg_stop_recording = function() + -- Let's killall ffmpeg instance first after awesome (re)-starts if there's any + awful.spawn.easy_async_with_shell( + [[ + ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill -2 + ]], + function(stdout) end + ) +end + +local create_notification = function(file_dir) + local open_video = naughty.action { + name = 'Open', + icon_only = false, + } + + local delete_video = naughty.action { + name = 'Delete', + icon_only = false, + } + + open_video:connect_signal( + 'invoked', + function() + awful.spawn('xdg-open ' .. file_dir, false) + end + ) + + delete_video:connect_signal( + 'invoked', + function() + awful.spawn('gio trash ' .. file_dir, false) + end + ) + + naughty.notification ({ + app_name = 'Screen Recorder', + timeout = 60, + title = 'Recording Finished!', + message = 'Recording can now be viewed.', + actions = { open_video, delete_video } + }) +end + +local ffmpeg_start_recording = function(audio, filename) + local add_audio_str = ' ' + + if audio then + turn_on_the_mic() + add_audio_str = '-f pulse -ac 2 -i default' + end + + ffmpeg_pid = awful.spawn.easy_async_with_shell( + [[ + file_name=]] .. filename .. [[ + + ffmpeg -video_size ]] .. scripts_tbl.user_resolution .. [[ -framerate ]] .. scripts_tbl.user_fps .. [[ -f x11grab \ + -i :0.0+]] .. scripts_tbl.user_offset .. ' ' .. add_audio_str .. [[ -c:v libx264 -crf 20 -profile:v baseline -level 3.0 -pix_fmt yuv420p $file_name + ]], + function(stdout, stderr) + if stderr and stderr:match('Invalid argument') then + naughty.notification({ + app_name = 'Screen Recorder', + title = 'Invalid Configuration!', + message = 'Please, put a valid settings!', + timeout = 60, + urgency = 'normal' + }) + awesome.emit_signal('widget::screen_recorder') + return + end + create_notification(filename) + end + ) +end + +local create_unique_filename = function(audio) + awful.spawn.easy_async_with_shell( + [[ + dir="]] .. scripts_tbl.user_dir .. [[" + date=$(date '+%Y-%m-%d_%H-%M-%S') + format=.mp4 + + echo "${dir}${date}${format}" | tr -d '\n' + ]], + function(stdout) + local filename = stdout + ffmpeg_start_recording(audio, filename) + end + ) +end + +scripts_tbl.start_recording = function(audio_mode) + create_save_directory() + create_unique_filename(audio_mode) +end + +scripts_tbl.stop_recording = function() + ffmpeg_stop_recording() +end + +return scripts_tbl diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua b/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua new file mode 100644 index 0000000..2b03e31 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/screen-recorder-ui-backend.lua @@ -0,0 +1,454 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local naughty = require('naughty') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/screen-recorder/icons/' + +-- The screen-recorders scripting +local screen_rec_backend = require('widget.screen-recorder.screen-recorder-scripts') + +-- The screen-recorder's UI +local screen_rec_ui = require('widget.screen-recorder.screen-recorder-ui') + +-- User Preferences +local sr_user_resolution = screen_rec_backend.user_resolution +local sr_user_offset = screen_rec_backend.user_offset +local sr_user_audio = screen_rec_backend.user_audio +local sr_user_update = screen_rec_backend.update_user_settings + +-- Panel UIs +local sr_toggle_imgbox = screen_rec_ui.screen_rec_toggle_imgbox +local sr_toggle_button = screen_rec_ui.screen_rec_toggle_button +local sr_countdown_text = screen_rec_ui.screen_rec_countdown_txt +local sr_main_imgbox = screen_rec_ui.screen_rec_main_imgbox +local sr_main_button = screen_rec_ui.screen_rec_main_button +local sr_audio_imgbox = screen_rec_ui.screen_rec_audio_imgbox +local sr_audio_button = screen_rec_ui.screen_rec_audio_button +local sr_settings_button = screen_rec_ui.screen_rec_settings_button +local sr_close_button = screen_rec_ui.screen_rec_close_button + + +-- Settings UIs +local sr_back_button = screen_rec_ui.screen_rec_back_button +local sr_resolution_box = screen_rec_ui.screen_rec_res_txtbox +local sr_offset_box = screen_rec_ui.screen_rec_offset_txtbox +local sr_resolution_tbox = sr_resolution_box:get_children_by_id('res_tbox')[1] +local sr_offset_tbox = sr_offset_box:get_children_by_id('offset_tbox')[1] + + +-- Main Scripts +local sr_start_recording = screen_rec_backend.start_recording +local sr_stop_recording = screen_rec_backend.stop_recording + +-- Active Screen Recorder +local sr_screen = nil + +-- Active textbox +local sr_active_tbox = nil + + +-- Status variables +local status_countdown = false +local status_recording = false +local status_audio = sr_user_audio + + +-- Update UI on startup using the user config +sr_resolution_tbox:set_markup('' .. sr_user_resolution .. "") +sr_offset_tbox:set_markup('' .. sr_user_offset .. "") + +local sr_res_default_markup = sr_resolution_tbox:get_markup() +local sr_offset_default_markup = sr_offset_tbox:get_markup() + + +if status_audio then + sr_audio_button.bg = '#EE4F84' .. '66' +else + sr_audio_button.bg = beautiful.groups_bg +end + +-- Textbox ui manipulators +local emphasize_inactive_tbox = function() + if sr_active_tbox == 'res_tbox' then + sr_resolution_box.shape_border_width = dpi(0) + sr_resolution_box.shape_border_color = beautiful.transparent + elseif sr_active_tbox == 'offset_tbox' then + sr_offset_box.shape_border_width = dpi(0) + sr_offset_box.shape_border_color = beautiful.transparent + end + sr_active_tbox = nil +end + +local emphasize_active_tbox = function() + if sr_active_tbox == 'res_tbox' then + sr_resolution_box.border_width = dpi(1) + sr_resolution_box.border_color = '#F2F2F2AA' + elseif sr_active_tbox == 'offset_tbox' then + sr_offset_box.border_width = dpi(1) + sr_offset_box.border_color = '#F2F2F2AA' + end +end + +-- Delete, reset and write to the textbox +local write_to_textbox = function(char) + if sr_active_tbox == 'res_tbox' and (char:match('%d') or char == 'x') then + if sr_resolution_tbox:get_markup() == sr_res_default_markup then + sr_resolution_tbox:set_text('') + end + if tonumber(#sr_resolution_tbox:get_text()) <= 8 then + sr_resolution_tbox:set_text(sr_resolution_tbox:get_text() .. char) + end + elseif sr_active_tbox == 'offset_tbox' and (char:match('%d') or char == ',') then + if sr_offset_tbox:get_markup() == sr_offset_default_markup then + sr_offset_tbox:set_text('') + end + sr_offset_tbox:set_text(sr_offset_tbox:get_text() .. char) + end +end + +local reset_textbox = function() + if sr_active_tbox == 'res_tbox' then + sr_resolution_tbox:set_markup(sr_res_default_markup) + elseif sr_active_tbox == 'offset_tbox' then + sr_offset_tbox:set_markup(sr_offset_default_markup) + end + emphasize_inactive_tbox() +end + +-- Set audio mode +local sr_audio_mode = function() + if not status_recording and not status_countdown then + if status_audio then + status_audio = false + sr_audio_button.bg = beautiful.groups_bg + else + status_audio = true + sr_audio_button.bg = '#EE4F84' .. '66' + end + end +end + +local delete_key = function() + if sr_active_tbox == 'res_tbox' then + if tonumber(#sr_resolution_tbox:get_text()) == 1 then + reset_textbox() + return + end + sr_resolution_tbox:set_text(sr_resolution_tbox:get_text():sub(1, -2)) + elseif sr_active_tbox == 'offset_tbox' then + if tonumber(#sr_offset_tbox:get_text()) == 1 then + reset_textbox() + return + end + sr_offset_tbox:set_text(sr_offset_tbox:get_text():sub(1, -2)) + end +end + +local apply_new_settings = function() + + -- Get the text on texbox + sr_user_resolution = sr_resolution_tbox:get_text() + sr_user_offset = sr_offset_tbox:get_text() + + -- Apply new settings + sr_user_update(sr_user_resolution, sr_user_offset, status_audio) + + -- Debugger + screen_rec_backend.check_settings() +end + +-- Settings Key grabber +local settings_updater = awful.keygrabber { + auto_start = true, + stop_event = 'release', + keypressed_callback = function(self, mod, key, command) + if key == 'BackSpace' then + delete_key() + end + end, + keyreleased_callback = function(self, mod, key, command) + if key == 'Return' then + apply_new_settings() + self:stop() + end + + if key == 'Escape' then + self:stop() + reset_textbox() + end + + if key:match('%d') or key == 'x' or key == ',' then + write_to_textbox(key) + end + + end +} + +-- Textboxes +sr_resolution_tbox:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + emphasize_inactive_tbox() + sr_active_tbox = 'res_tbox' + emphasize_active_tbox() + settings_updater:start() + end + ) + ) +) + +sr_offset_tbox:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + emphasize_inactive_tbox() + sr_active_tbox = 'offset_tbox' + emphasize_active_tbox() + settings_updater:start() + end + ) + ) +) + +-- UI switcher +local sr_navigation_reset = function() + if sr_screen then + local recorder_panel = sr_screen:get_children_by_id('recorder_panel')[1] + local recorder_settings = sr_screen:get_children_by_id('recorder_settings')[1] + recorder_settings.visible = false + recorder_panel.visible = true + end +end + +local sr_navigation = function() + if sr_screen then + local recorder_panel = sr_screen:get_children_by_id('recorder_panel')[1] + local recorder_settings = sr_screen:get_children_by_id('recorder_settings')[1] + if recorder_panel.visible then + recorder_panel.visible = false + recorder_settings.visible = true + else + recorder_settings.visible = false + recorder_panel.visible = true + end + end +end + +sr_settings_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + if not status_recording and not status_countdown then + sr_navigation() + end + end + ) + ) +) + +sr_back_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + + -- Save settings + apply_new_settings() + + -- Reset textbox UI + emphasize_inactive_tbox() + + -- Go back to UI Panel + sr_navigation() + end + ) + ) +) + +-- Close button functions and buttons +local screen_rec_close = function() + + for s in screen do + s.recorder_screen.visible = false + end + settings_updater:stop() + sr_navigation_reset() + sr_screen = nil +end + +sr_close_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + screen_rec_close() + end + ) + ) +) + +-- Right click to exit +local screen_close_on_rmb = function(widget) + widget:buttons( + gears.table.join( + awful.button( + {}, + 3, + nil, + function() + screen_rec_close() + end + ) + ) + ) +end + +-- Open recorder screen +sr_toggle_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + for s in screen do + s.recorder_screen.visible = false + end + sr_screen = awful.screen.focused().recorder_screen + screen_close_on_rmb(sr_screen) + sr_screen.visible = not sr_screen.visible + end + ) + ) +) + +-- Start Recording +local sr_recording_start = function() + status_countdown = false + status_recording = true + local sr_screen = awful.screen.focused().recorder_screen + + -- Hide recorder screen + sr_screen.visible = false + + -- Manipulate UIs + sr_toggle_imgbox:set_image(widget_icon_dir .. 'recording-button' .. '.svg') + sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-on' .. '.svg') + + sr_start_recording(status_audio) +end + +-- Stop Recording +local sr_recording_stop = function() + status_recording = false + status_audio = false + + -- Manipulate UIs + sr_toggle_imgbox:set_image(widget_icon_dir .. 'start-recording-button' .. '.svg') + sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-off' .. '.svg') + sr_stop_recording() +end + +awesome.connect_signal( + 'widget::screen_recorder', + function() + sr_recording_stop() + end +) + +-- Countdown timer functions +local countdown_timer = nil +local counter_timer = function() + status_countdown = true + local seconds = 3 + countdown_timer = gears.timer.start_new( + 1, + function() + if seconds == 0 then + sr_countdown_text.opacity = 0.0 + + -- Start recording function + sr_recording_start() + sr_countdown_text:emit_signal('widget::redraw_needed') + return false + else + sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-countdown' .. '.svg') + sr_countdown_text.opacity = 1.0 + sr_countdown_text:set_text(tostring(seconds)) + sr_countdown_text:emit_signal('widget::redraw_needed') + end + seconds = seconds - 1 + return true + end + ) +end + +-- Stop Countdown timer +local sr_countdown_stop = function() + countdown_timer:stop() + status_countdown = false + sr_main_imgbox:set_image(widget_icon_dir .. 'recorder-off' .. '.svg') + sr_countdown_text.opacity = 0.0 + sr_countdown_text:emit_signal('widget::redraw_needed') +end + +sr_audio_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + sr_audio_mode() + end + ) + ) +) + +-- Main button functions and buttons +local status_checker = function() + if status_recording and not status_countdown then + + -- Stop recording + sr_recording_stop() + return + elseif not status_recording and status_countdown then + + -- Stop timer + sr_countdown_stop() + return + end + + -- Start counting down + counter_timer() +end + +sr_main_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + status_checker() + end + ) + ) +) diff --git a/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua b/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua new file mode 100644 index 0000000..c877d89 --- /dev/null +++ b/.config/awesome/widget/screen-recorder/screen-recorder-ui.lua @@ -0,0 +1,343 @@ +local awful = require('awful') +local gears = require('gears') +local wibox = require('wibox') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/screen-recorder/icons/' +local record_tbl = {} + +-- Panel UI +record_tbl.screen_rec_toggle_imgbox = wibox.widget { + image = widget_icon_dir .. 'start-recording-button' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_toggle_button = wibox.widget { + { + record_tbl.screen_rec_toggle_imgbox, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +record_tbl.screen_rec_countdown_txt = wibox.widget { + id = 'countdown_text', + font = 'Inter Bold 64', + text = '4', + align = 'center', + valign = 'bottom', + opacity = 0.0, + widget = wibox.widget.textbox +} + +record_tbl.screen_rec_main_imgbox = wibox.widget { + image = widget_icon_dir .. 'recorder-off' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_main_button = wibox.widget { + { + { + { + record_tbl.screen_rec_main_imgbox, + margins = dpi(24), + widget = wibox.container.margin + }, + widget = clickable_container + }, + forced_width = dpi(200), + forced_height = dpi(200), + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background + }, + margins = dpi(24), + widget = wibox.container.margin +} + +record_tbl.screen_rec_audio_imgbox = wibox.widget { + image = widget_icon_dir .. 'audio' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_audio_button = wibox.widget { + { + nil, + { + { + record_tbl.screen_rec_audio_imgbox, + margins = dpi(16), + widget = wibox.container.margin + }, + widget = clickable_container + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical + }, + forced_width = dpi(60), + forced_height = dpi(60), + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background +} + +record_tbl.screen_rec_close_imgbox = wibox.widget { + image = widget_icon_dir .. 'close-screen' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_close_button = wibox.widget { + { + nil, + { + { + record_tbl.screen_rec_close_imgbox, + margins = dpi(16), + widget = wibox.container.margin + }, + widget = clickable_container + }, + nil, + expand = 'none', + layout = wibox.layout.align.horizontal + }, + forced_width = dpi(60), + forced_height = dpi(60), + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background +} + +record_tbl.screen_rec_settings_imgbox = wibox.widget { + image = widget_icon_dir .. 'settings' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_settings_button = wibox.widget { + { + nil, + { + { + record_tbl.screen_rec_settings_imgbox, + margins = dpi(16), + widget = wibox.container.margin + }, + widget = clickable_container + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical + }, + forced_width = dpi(60), + forced_height = dpi(60), + bg = beautiful.groups_bg, + shape = gears.shape.circle, + widget = wibox.container.background +} + +record_tbl.screen_rec_back_imgbox = wibox.widget { + image = widget_icon_dir .. 'back' .. '.svg', + resize = true, + widget = wibox.widget.imagebox +} + +record_tbl.screen_rec_back_button = wibox.widget { + { + nil, + { + { + record_tbl.screen_rec_back_imgbox, + margins = dpi(16), + widget = wibox.container.margin + }, + widget = clickable_container + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical + }, + forced_width = dpi(48), + forced_height = dpi(48), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background +} + +record_tbl.screen_rec_back_txt = wibox.widget { + { + text = 'Back', + font = 'Inter Bold 16', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + margins = dpi(5), + widget = wibox.container.margin + +} + +record_tbl.screen_rec_res_txt = wibox.widget { + { + text = 'Resolution', + font = 'Inter Bold 16', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + margins = dpi(5), + widget = wibox.container.margin + +} + +record_tbl.screen_rec_res_txtbox = wibox.widget { + { + { + { + id = 'res_tbox', + markup = '' .. '1366x768' .. "", + font = 'Inter Bold 16', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + margins = dpi(5), + widget = wibox.container.margin + }, + widget = clickable_container + }, + forced_width = dpi(60), + forced_height = dpi(60), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background +} + +record_tbl.screen_rec_offset_txt = wibox.widget { + { + text = 'Offset', + font = 'Inter Bold 16', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + margins = dpi(5), + widget = wibox.container.margin +} + +record_tbl.screen_rec_offset_txtbox = wibox.widget { + { + { + { + id = 'offset_tbox', + markup = '' .. '0,0' .. "", + font = 'Inter Bold 16', + ellipsize = 'start', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + margins = dpi(5), + widget = wibox.container.margin + }, + widget = clickable_container + }, + forced_width = dpi(60), + forced_height = dpi(60), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background +} + +screen.connect_signal("request::desktop_decoration", function(s) + + s.recorder_screen = wibox + ({ + ontop = true, + screen = s, + type = 'dock', + height = s.geometry.height, + width = s.geometry.width, + x = s.geometry.x, + y = s.geometry.y, + bg = beautiful.background, + fg = beautiful.fg_normal + }) + + s.recorder_screen : setup { + layout = wibox.layout.stack, + { + id = 'recorder_panel', + visible = true, + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + record_tbl.screen_rec_countdown_txt, + { + layout = wibox.layout.align.horizontal, + record_tbl.screen_rec_settings_button, + record_tbl.screen_rec_main_button, + record_tbl.screen_rec_audio_button + }, + record_tbl.screen_rec_close_button, + }, + nil + + }, + nil + }, + { + id = 'recorder_settings', + visible = false, + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + forced_width = dpi(240), + spacing = dpi(10), + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(10), + record_tbl.screen_rec_back_button, + record_tbl.screen_rec_back_txt, + }, + record_tbl.screen_rec_res_txt, + record_tbl.screen_rec_res_txtbox, + record_tbl.screen_rec_offset_txt, + record_tbl.screen_rec_offset_txtbox + }, + nil + + }, + nil + } + } + +end) + +return record_tbl diff --git a/.config/awesome/widget/search-apps/icons/app-launcher.svg b/.config/awesome/widget/search-apps/icons/app-launcher.svg new file mode 100644 index 0000000..616879f --- /dev/null +++ b/.config/awesome/widget/search-apps/icons/app-launcher.svg @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/search-apps/init.lua b/.config/awesome/widget/search-apps/init.lua new file mode 100644 index 0000000..4839ab8 --- /dev/null +++ b/.config/awesome/widget/search-apps/init.lua @@ -0,0 +1,51 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local filesystem = gears.filesystem +local config_dir = filesystem.get_configuration_dir() +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local widget_icon_dir = config_dir .. '/widget/search-apps/icons/' +local apps = require('configuration.apps') + +local return_button = function() + + local widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'app-launcher.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local widget_button = wibox.widget { + { + widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + if screen.primary.left_panel.opened then + screen.primary.left_panel:toggle() + end + awful.spawn(apps.default.rofi_appmenu, false) + end + ) + ) + ) + + return widget_button +end + +return return_button \ No newline at end of file diff --git a/.config/awesome/widget/social-media/icons/facebook.svg b/.config/awesome/widget/social-media/icons/facebook.svg new file mode 100644 index 0000000..1052f58 --- /dev/null +++ b/.config/awesome/widget/social-media/icons/facebook.svg @@ -0,0 +1,4 @@ + + + + diff --git a/.config/awesome/widget/social-media/icons/instagram.svg b/.config/awesome/widget/social-media/icons/instagram.svg new file mode 100644 index 0000000..afda8b7 --- /dev/null +++ b/.config/awesome/widget/social-media/icons/instagram.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/.config/awesome/widget/social-media/icons/reddit.svg b/.config/awesome/widget/social-media/icons/reddit.svg new file mode 100644 index 0000000..b94ef6f --- /dev/null +++ b/.config/awesome/widget/social-media/icons/reddit.svg @@ -0,0 +1,2 @@ + + diff --git a/.config/awesome/widget/social-media/icons/twitter.svg b/.config/awesome/widget/social-media/icons/twitter.svg new file mode 100644 index 0000000..76840b2 --- /dev/null +++ b/.config/awesome/widget/social-media/icons/twitter.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/.config/awesome/widget/social-media/init.lua b/.config/awesome/widget/social-media/init.lua new file mode 100644 index 0000000..c1304dc --- /dev/null +++ b/.config/awesome/widget/social-media/init.lua @@ -0,0 +1,130 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local beautiful = require('beautiful') + +local dpi = beautiful.xresources.apply_dpi + +local clickable_container = require('widget.clickable-container') + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/social-media/icons/' + +local decorate_widget = function(widgets) + + return wibox.widget { + widgets, + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, groups_radius) + end, + widget = wibox.container.background + } + +end + +local build_social_button = function(website) + + local social_imgbox = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. website .. '.svg', + widget = wibox.widget.imagebox, + resize = true, + forced_height = dpi(35) + }, + layout = wibox.layout.align.horizontal + } + + local social_button = wibox.widget { + { + social_imgbox, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container + } + + local website_url = nil + if website == 'facebook' then + website_url = 'https://facebook.com' + + elseif website == 'reddit' then + website_url = 'https://reddit.com' + + elseif website == 'twitter' then + website_url = 'https://twitter.com' + + elseif website == 'instagram' then + website_url = 'https://instagram.com' + + end + + social_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn({'xdg-open', website_url}, false) + end + ) + ) + ) + + local social_name = website:sub(1,1):upper() .. website:sub(2) + + local social_tbox = wibox.widget { + text = social_name, + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox + } + + return wibox.widget { + layout = wibox.layout.fixed.vertical, + spacing = dpi(5), + { + layout = wibox.layout.align.horizontal, + expand = 'none', + nil, + decorate_widget(social_button), + nil + }, + social_tbox + } +end + + +local social_layout = wibox.widget { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(5), + build_social_button('reddit'), + build_social_button('facebook'), + build_social_button('twitter'), + build_social_button('instagram'), +} + +local social = wibox.widget { + { + { + expand = 'none', + layout = wibox.layout.align.horizontal, + nil, + social_layout, + nil + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + forced_height = dpi(92), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background +} + +return social diff --git a/.config/awesome/widget/tag-list/init.lua b/.config/awesome/widget/tag-list/init.lua new file mode 100644 index 0000000..df5ae64 --- /dev/null +++ b/.config/awesome/widget/tag-list/init.lua @@ -0,0 +1,168 @@ +local awful = require('awful') +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +--- Common method to create buttons. +-- @tab buttons +-- @param object +-- @return table +local function create_buttons(buttons, object) + if buttons then + local btns = {} + for _, b in ipairs(buttons) do + -- Create a proxy button object: it will receive the real + -- press and release events, and will propagate them to the + -- button object the user provided, but with the object as + -- argument. + local btn = awful.button { + modifiers = b.modifiers, + button = b.button, + on_press = function() + b:emit_signal('press', object) + end, + on_release = function() + b:emit_signal('release', object) + end + } + btns[#btns + 1] = btn + end + return btns + end +end + +local function list_update(w, buttons, label, data, objects) + -- update the widgets, creating them if needed + w:reset() + for i, o in ipairs(objects) do + local cache = data[o] + local ib, tb, bgb, tbm, ibm, l, bg_clickable + if cache then + ib = cache.ib + tb = cache.tb + bgb = cache.bgb + tbm = cache.tbm + ibm = cache.ibm + else + ib = wibox.widget.imagebox() + tb = wibox.widget.textbox() + bgb = wibox.container.background() + tbm = wibox.widget { + tb, + left = dpi(4), + right = dpi(16), + widget = wibox.container.margin + } + ibm = wibox.widget { + ib, + margins = dpi(10), + widget = wibox.container.margin + } + l = wibox.layout.fixed.horizontal() + bg_clickable = clickable_container() + + -- All of this is added in a fixed widget + l:fill_space(true) + l:add(ibm) + -- l:add(tbm) + bg_clickable:set_widget(l) + + -- And all of this gets a background + bgb:set_widget(bg_clickable) + + bgb:buttons(create_buttons(buttons, o)) + + data[o] = { + ib = ib, + tb = tb, + bgb = bgb, + tbm = tbm, + ibm = ibm + } + end + + local text, bg, bg_image, icon, args = label(o, tb) + args = args or {} + + -- The text might be invalid, so use pcall. + if text == nil or text == '' then + tbm:set_margins(0) + else + if not tb:set_markup_silently(text) then + tb:set_markup('<Invalid text>') + end + end + bgb:set_bg(bg) + if type(bg_image) == 'function' then + -- TODO: Why does this pass nil as an argument? + bg_image = bg_image(tb, o, nil, objects, i) + end + bgb:set_bgimage(bg_image) + if icon then + ib.image = icon + else + ibm:set_margins(0) + end + + bgb.shape = args.shape + bgb.shape_border_width = args.shape_border_width + bgb.shape_border_color = args.shape_border_color + + w:add(bgb) + end +end + +local tag_list = function(s) + return awful.widget.taglist( + s, + awful.widget.taglist.filter.all, + awful.util.table.join( + awful.button( + {}, + 1, + function(t) + t:view_only() + end + ), + awful.button( + {modkey}, + 1, + function(t) + if _G.client.focus then + _G.client.focus:move_to_tag(t) + t:view_only() + end + end + ), + awful.button({}, 3, awful.tag.viewtoggle), + awful.button( + {modkey}, + 3, + function(t) + if _G.client.focus then + _G.client.focus:toggle_tag(t) + end + end + ), + awful.button( + {}, + 4, + function(t) + awful.tag.viewprev(t.screen) + end + ), + awful.button( + {}, + 5, + function(t) + awful.tag.viewnext(t.screen) + end + ) + ), + {}, + list_update, + wibox.layout.fixed.vertical() + ) +end +return tag_list diff --git a/.config/awesome/widget/task-list/init.lua b/.config/awesome/widget/task-list/init.lua new file mode 100644 index 0000000..9bf921e --- /dev/null +++ b/.config/awesome/widget/task-list/init.lua @@ -0,0 +1,232 @@ +local awful = require('awful') +local wibox = require('wibox') +local dpi = require('beautiful').xresources.apply_dpi +local gears = require('gears') +local clickable_container = require('widget.clickable-container') +local icons = require('theme.icons') + +--- Common method to create buttons. +-- @tab buttons +-- @param object +-- @return table +local function create_buttons(buttons, object) + if buttons then + local btns = {} + for _, b in ipairs(buttons) do + -- Create a proxy button object: it will receive the real + -- press and release events, and will propagate them to the + -- button object the user provided, but with the object as + -- argument. + local btn = awful.button { + modifiers = b.modifiers, + button = b.button, + on_press = function() + b:emit_signal('press', object) + end, + on_release = function() + b:emit_signal('release', object) + end + } + btns[#btns + 1] = btn + end + return btns + end +end + +local function list_update(w, buttons, label, data, objects) + -- Update the widgets, creating them if needed + w:reset() + for i, o in ipairs(objects) do + local cache = data[o] + local ib, cb, tb, cbm, bgb, tbm, ibm, tt, l, ll, bg_clickable + if cache then + ib = cache.ib + tb = cache.tb + bgb = cache.bgb + tbm = cache.tbm + ibm = cache.ibm + tt = cache.tt + else + ib = wibox.widget.imagebox() + tb = wibox.widget.textbox() + cb = wibox.widget { + { + { + image = icons.close, + resize = true, + widget = wibox.widget.imagebox + }, + margins = dpi(4), + widget = wibox.container.margin + }, + widget = clickable_container + } + cb.shape = gears.shape.circle + cbm = wibox.widget { + -- 4, 8 ,12 ,12 -- close button + cb, + left = dpi(4), + right = dpi(8), + top = dpi(4), + bottom = dpi(4), + widget = wibox.container.margin + } + cbm:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + o:kill() + end + ) + ) + ) + bg_clickable = clickable_container() + bgb = wibox.container.background() + tbm = wibox.widget { + tb, + left = dpi(4), + right = dpi(4), + widget = wibox.container.margin + } + ibm = wibox.widget { + -- 12 top bottom + ib, + left = dpi(6), + right = dpi(6), + top = dpi(6), + bottom = dpi(6), + widget = wibox.container.margin + } + l = wibox.layout.fixed.horizontal() + ll = wibox.layout.fixed.horizontal() + + -- All of this is added in a fixed widget + l:fill_space(true) + l:add(ibm) + l:add(tbm) + ll:add(l) + ll:add(cbm) + + bg_clickable:set_widget(ll) + -- And all of this gets a background + bgb:set_widget(bg_clickable) + + l:buttons(create_buttons(buttons, o)) + + -- Tooltip to display whole title, if it was truncated + tt = awful.tooltip({ + objects = {tb}, + mode = 'outside', + align = 'bottom', + delay_show = 1, + }) + + data[o] = { + ib = ib, + tb = tb, + bgb = bgb, + tbm = tbm, + ibm = ibm, + tt = tt + } + end + + local text, bg, bg_image, icon, args = label(o, tb) + args = args or {} + + -- The text might be invalid, so use pcall. + if text == nil or text == '' then + tbm:set_margins(0) + else + -- Truncate when title is too long + local text_only = text:match('>(.-)<') + if (utf8.len(text_only) > 24) then + text = text:gsub('>(.-)<', '>' .. string.sub(text_only, 1, utf8.offset(text_only,22) - 1) .. '...<') + tt:set_text(text_only) + tt:add_to_object(tb) + else + tt:remove_from_object(tb) + end + if not tb:set_markup_silently(text) then + tb:set_markup('<Invalid text>') + end + end + bgb:set_bg(bg) + if type(bg_image) == 'function' then + -- TODO: Why does this pass nil as an argument? + bg_image = bg_image(tb, o, nil, objects, i) + end + bgb:set_bgimage(bg_image) + if icon then + ib.image = gears.surface(icon) + else + ibm:set_margins(0) + end + + bgb.shape = args.shape + bgb.shape_border_width = args.shape_border_width + bgb.shape_border_color = args.shape_border_color + + w:add(bgb) + end +end + +local tasklist_buttons = awful.util.table.join( + awful.button( + {}, + 1, + function(c) + if c == client.focus then + c.minimized = true + else + -- Without this, the following + -- :isvisible() makes no sense + c.minimized = false + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + -- This will also un-minimize + -- the client, if needed + c:emit_signal('request::activate') + c:raise() + end + end + ), + awful.button( + {}, + 2, + function(c) + c:kill() + end + ), + awful.button( + {}, + 4, + function() + awful.client.focus.byidx(1) + end + ), + awful.button( + {}, + 5, + function() + awful.client.focus.byidx(-1) + end + ) +) + +local task_list = function(s) + return awful.widget.tasklist( + s, + awful.widget.tasklist.filter.currenttags, + tasklist_buttons, + {}, + list_update, + wibox.layout.fixed.horizontal() + ) +end + +return task_list diff --git a/.config/awesome/widget/temperature-meter/init.lua b/.config/awesome/widget/temperature-meter/init.lua new file mode 100644 index 0000000..ca59e9b --- /dev/null +++ b/.config/awesome/widget/temperature-meter/init.lua @@ -0,0 +1,88 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local beautiful = require('beautiful') +local watch = awful.widget.watch +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') + +local slider = wibox.widget { + nil, + { + id = 'temp_status', + max_value = 100, + value = 29, + forced_height = dpi(2), + color = beautiful.fg_normal, + background_color = beautiful.groups_bg, + shape = gears.shape.rounded_rect, + widget = wibox.widget.progressbar + }, + nil, + expand = 'none', + layout = wibox.layout.align.vertical +} + +local max_temp = 80 + +awful.spawn.easy_async_with_shell( + [[ + temp_path=null + for i in /sys/class/hwmon/hwmon*/temp*_input; + do + temp_path="$(echo "$(<$(dirname $i)/name): $(cat ${i%_*}_label 2>/dev/null || + echo $(basename ${i%_*})) $(readlink -f $i)");" + + label="$(echo $temp_path | awk '{print $2}')" + + if [ "$label" = "Package" ]; + then + echo ${temp_path} | awk '{print $5}' | tr -d ';\n' + exit; + fi + done + ]], + function(stdout) + local temp_path = stdout:gsub('%\n', '') + if temp_path == '' or not temp_path then + temp_path = '/sys/class/thermal/thermal_zone0/temp' + end + + watch( + [[ + sh -c "cat ]] .. temp_path .. [[" + ]], + 10, + function(_, stdout) + local temp = stdout:match('(%d+)') + slider.temp_status:set_value((temp / 1000) / max_temp * 100) + collectgarbage('collect') + end + ) + end +) + +local temperature_meter = wibox.widget { + { + { + { + image = icons.thermometer, + resize = true, + widget = wibox.widget.imagebox + }, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return temperature_meter diff --git a/.config/awesome/widget/tray-toggle/icons/left-arrow.svg b/.config/awesome/widget/tray-toggle/icons/left-arrow.svg new file mode 100644 index 0000000..f0e76e5 --- /dev/null +++ b/.config/awesome/widget/tray-toggle/icons/left-arrow.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/tray-toggle/icons/right-arrow.svg b/.config/awesome/widget/tray-toggle/icons/right-arrow.svg new file mode 100644 index 0000000..7446424 --- /dev/null +++ b/.config/awesome/widget/tray-toggle/icons/right-arrow.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/tray-toggle/init.lua b/.config/awesome/widget/tray-toggle/init.lua new file mode 100644 index 0000000..76af98d --- /dev/null +++ b/.config/awesome/widget/tray-toggle/init.lua @@ -0,0 +1,68 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local dpi = require('beautiful').xresources.apply_dpi +local clickable_container = require('widget.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/tray-toggle/icons/' + +local widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'right-arrow' .. '.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal +} + +local widget_button = wibox.widget { + { + widget, + margins = dpi(7), + widget = wibox.container.margin + }, + widget = clickable_container +} + +widget_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awesome.emit_signal('widget::systray:toggle') + end + ) + ) +) + +-- Listen to signal +awesome.connect_signal( + 'widget::systray:toggle', + function() + if screen.primary.systray then + + if not screen.primary.systray.visible then + + widget.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'left-arrow.svg')) + else + + widget.icon:set_image(gears.surface.load_uncached(widget_icon_dir .. 'right-arrow.svg')) + end + + screen.primary.systray.visible = not screen.primary.systray.visible + end + end +) + +-- Update icon on start-up +if screen.primary.systray then + if screen.primary.systray.visible then + widget.icon:set_image(widget_icon_dir .. 'right-arrow' .. '.svg') + end +end + +-- Show only the tray button in the primary screen +return awful.widget.only_on_screen(widget_button, 'primary') diff --git a/.config/awesome/widget/user-profile/init.lua b/.config/awesome/widget/user-profile/init.lua new file mode 100644 index 0000000..6151a76 --- /dev/null +++ b/.config/awesome/widget/user-profile/init.lua @@ -0,0 +1,239 @@ +-- User profile widget +-- Optional dependency: +-- mugshot (use to update profile picture and information) + + +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') +local naughty = require('naughty') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local apps = require('configuration.apps') +local clickable_container = require('widget.clickable-container') +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'configuration/user-profile/' +local user_icon_dir = '/var/lib/AccountsService/icons/' + +title_table = { + 'Hey, I have a message for you', + 'Listen here you little shit!', + 'Le\' me tell you a secret', + 'I never lie', + 'Message received from your boss' +} + +message_table = { + 'Let me rate your face! Oops... It looks like I can\'t compute negative numbers. You\'re ugly af, sorry', + 'Lookin\' good today, now fuck off!', + 'The last thing I want to do is hurt you. But it’s still on the list.', + 'If I agreed with you we’d both be wrong.', + 'I intend to live forever. So far, so good.', + 'Jesus loves you, but everyone else thinks you’re an asshole.', + 'Your baby is so ugly, you should have thrown it away and kept the stork.', + 'If your brain was dynamite, there wouldn’t be enough to blow your hat off.', + 'You are more disappointing than an unsalted pretzel.', + 'Your kid is so ugly, he makes his Happy Meal cry.', + 'Your secrets are always safe with me. I never even listen when you tell me them.', + 'I only take you everywhere I go just so I don’t have to kiss you goodbye.', + 'You look so pretty. Not at all gross, today.', + 'It’s impossible to underestimate you.', + 'I’m not insulting you, I’m describing you.', + 'Keep rolling your eyes, you might eventually find a brain.', + 'You bring everyone so much joy, when you leave the room.', + 'I thought of you today. It reminded me to take out the trash.', + 'You are the human version of period cramps.', + 'You’re the reason God created the middle finger.' +} + +local profile_imagebox = wibox.widget { + { + id = 'icon', + forced_height = dpi(45), + forced_width = dpi(45), + image = widget_icon_dir .. 'default.svg', + widget = wibox.widget.imagebox, + resize = true, + clip_shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end + }, + layout = wibox.layout.align.horizontal +} + +profile_imagebox:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.single_instance('mugshot') + end + ), + awful.button( + {}, + 3, + nil, + function() + naughty.notification({ + app_name = 'FBI\'s ChatBot v69', + title = title_table[math.random(#title_table)], + message = message_table[math.random(#message_table)] .. + '\n\n- xXChatBOT69Xx', + urgency = 'normal' + }) + end + ) + ) +) + +local profile_name = wibox.widget { + font = 'Inter Regular 10', + markup = 'User', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local distro_name = wibox.widget { + font = 'Inter Regular 10', + markup = 'GNU/Linux', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local kernel_version = wibox.widget { + font = 'Inter Regular 10', + markup = 'Linux', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local uptime_time = wibox.widget { + font = 'Inter Regular 10', + markup = 'up 1 minute', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox +} + +local update_profile_image = function() + awful.spawn.easy_async_with_shell( + apps.utils.update_profile, + function(stdout) + stdout = stdout:gsub('%\n','') + if not stdout:match('default') then + profile_imagebox.icon:set_image(stdout) + else + profile_imagebox.icon:set_image(widget_icon_dir .. 'default.svg') + end + end + ) +end + +update_profile_image() + +awful.spawn.easy_async_with_shell( + [[ + sh -c ' + fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")" + if [ -z "$fullname" ]; + then + printf "$(whoami)@$(hostname)" + else + printf "$fullname" + fi + ' + ]], + function(stdout) + local stdout = stdout:gsub('%\n', '') + profile_name:set_markup(stdout) + end +) + +awful.spawn.easy_async_with_shell( + [[ + cat /etc/os-release | awk 'NR==1'| awk -F '"' '{print $2}' + ]], + function(stdout) + local distroname = stdout:gsub('%\n', '') + distro_name:set_markup(distroname) + end +) + +awful.spawn.easy_async_with_shell( + 'uname -r', + function(stdout) + local kname = stdout:gsub('%\n', '') + kernel_version:set_markup(kname) + end +) + +local update_uptime = function() + awful.spawn.easy_async_with_shell( + 'uptime -p', + function(stdout) + local uptime = stdout:gsub('%\n','') + uptime_time:set_markup(uptime) + end + ) +end + +local uptime_updater_timer = gears.timer{ + timeout = 60, + autostart = true, + call_now = true, + callback = function() + update_uptime() + end +} + +local user_profile = wibox.widget { + { + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(10), + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + profile_imagebox, + nil + }, + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + profile_name, + distro_name, + kernel_version, + uptime_time + }, + nil + } + }, + margins = dpi(10), + widget = wibox.container.margin + }, + forced_height = dpi(92), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, beautiful.groups_radius) + end, + widget = wibox.container.background + +} + +user_profile:connect_signal( + 'mouse::enter', + function() + update_uptime() + end +) + +return user_profile diff --git a/.config/awesome/widget/volume-slider/init.lua b/.config/awesome/widget/volume-slider/init.lua new file mode 100644 index 0000000..101772d --- /dev/null +++ b/.config/awesome/widget/volume-slider/init.lua @@ -0,0 +1,180 @@ +local wibox = require('wibox') +local gears = require('gears') +local awful = require('awful') +local beautiful = require('beautiful') +local spawn = awful.spawn +local dpi = beautiful.xresources.apply_dpi +local icons = require('theme.icons') +local clickable_container = require('widget.clickable-container') + +local icon = wibox.widget { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + image = icons.volume, + resize = true, + widget = wibox.widget.imagebox + }, + nil +} + +local action_level = wibox.widget { + { + icon, + widget = clickable_container, + }, + bg = beautiful.transparent, + shape = gears.shape.circle, + widget = wibox.container.background +} + +local slider = wibox.widget { + nil, + { + id = 'volume_slider', + bar_shape = gears.shape.rounded_rect, + bar_height = dpi(2), + bar_color = '#ffffff20', + bar_active_color = '#f2f2f2EE', + handle_color = '#ffffff', + handle_shape = gears.shape.circle, + handle_width = dpi(15), + handle_border_color = '#00000012', + handle_border_width = dpi(1), + maximum = 100, + widget = wibox.widget.slider, + }, + nil, + forced_height = dpi(24), + expand = 'none', + layout = wibox.layout.align.vertical +} + + +local volume_slider = slider.volume_slider + +volume_slider:connect_signal( + 'property::value', + function() + local volume_level = volume_slider:get_value() + + spawn('amixer -D pulse sset Master ' .. + volume_level .. '%', + false + ) + + -- Update volume osd + awesome.emit_signal( + 'module::volume_osd', + volume_level + ) + end +) + +volume_slider:buttons( + gears.table.join( + awful.button( + {}, + 4, + nil, + function() + if volume_slider:get_value() > 100 then + volume_slider:set_value(100) + return + end + volume_slider:set_value(volume_slider:get_value() + 5) + end + ), + awful.button( + {}, + 5, + nil, + function() + if volume_slider:get_value() < 0 then + volume_slider:set_value(0) + return + end + volume_slider:set_value(volume_slider:get_value() - 5) + end + ) + ) +) + + +local update_slider = function() + awful.spawn.easy_async_with_shell( + [[bash -c "amixer -D pulse sget Master"]], + function(stdout) + local volume = string.match(stdout, '(%d?%d?%d)%%') + volume_slider:set_value(tonumber(volume)) + end + ) +end + +-- Update on startup +update_slider() + +local action_jump = function() + local sli_value = volume_slider:get_value() + local new_value = 0 + + if sli_value >= 0 and sli_value < 50 then + new_value = 50 + elseif sli_value >= 50 and sli_value < 100 then + new_value = 100 + else + new_value = 0 + end + volume_slider:set_value(new_value) +end + +action_level:buttons( + awful.util.table.join( + awful.button( + {}, + 1, + nil, + function() + action_jump() + end + ) + ) +) + +-- The emit will come from the global keybind +awesome.connect_signal( + 'widget::volume', + function() + update_slider() + end +) + +-- The emit will come from the OSD +awesome.connect_signal( + 'widget::volume:update', + function(value) + volume_slider:set_value(tonumber(value)) + end +) + +local volume_setting = wibox.widget { + { + { + action_level, + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin + }, + slider, + spacing = dpi(24), + layout = wibox.layout.fixed.horizontal + + }, + left = dpi(24), + right = dpi(24), + forced_height = dpi(48), + widget = wibox.container.margin +} + +return volume_setting diff --git a/.config/awesome/widget/weather/icons/d_rain.svg b/.config/awesome/widget/weather/icons/d_rain.svg new file mode 100644 index 0000000..44cacc1 --- /dev/null +++ b/.config/awesome/widget/weather/icons/d_rain.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dbroken_clouds.svg b/.config/awesome/widget/weather/icons/dbroken_clouds.svg new file mode 100644 index 0000000..8fa8005 --- /dev/null +++ b/.config/awesome/widget/weather/icons/dbroken_clouds.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dfew_clouds.svg b/.config/awesome/widget/weather/icons/dfew_clouds.svg new file mode 100644 index 0000000..a4f1fd3 --- /dev/null +++ b/.config/awesome/widget/weather/icons/dfew_clouds.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dmist.svg b/.config/awesome/widget/weather/icons/dmist.svg new file mode 100644 index 0000000..b23f3bf --- /dev/null +++ b/.config/awesome/widget/weather/icons/dmist.svg @@ -0,0 +1,77 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dscattered_clouds.svg b/.config/awesome/widget/weather/icons/dscattered_clouds.svg new file mode 100644 index 0000000..9c0ebcb --- /dev/null +++ b/.config/awesome/widget/weather/icons/dscattered_clouds.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dshower_rain.svg b/.config/awesome/widget/weather/icons/dshower_rain.svg new file mode 100644 index 0000000..3a88004 --- /dev/null +++ b/.config/awesome/widget/weather/icons/dshower_rain.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/dthunderstorm.svg b/.config/awesome/widget/weather/icons/dthunderstorm.svg new file mode 100644 index 0000000..10375e4 --- /dev/null +++ b/.config/awesome/widget/weather/icons/dthunderstorm.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/moon_icon.svg b/.config/awesome/widget/weather/icons/moon_icon.svg new file mode 100644 index 0000000..b9e5c3a --- /dev/null +++ b/.config/awesome/widget/weather/icons/moon_icon.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/n_rain.svg b/.config/awesome/widget/weather/icons/n_rain.svg new file mode 100644 index 0000000..3ba466a --- /dev/null +++ b/.config/awesome/widget/weather/icons/n_rain.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nbroken_clouds.svg b/.config/awesome/widget/weather/icons/nbroken_clouds.svg new file mode 100644 index 0000000..d462c33 --- /dev/null +++ b/.config/awesome/widget/weather/icons/nbroken_clouds.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nfew_clouds.svg b/.config/awesome/widget/weather/icons/nfew_clouds.svg new file mode 100644 index 0000000..74575ee --- /dev/null +++ b/.config/awesome/widget/weather/icons/nfew_clouds.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nmist.svg b/.config/awesome/widget/weather/icons/nmist.svg new file mode 100644 index 0000000..34d0e41 --- /dev/null +++ b/.config/awesome/widget/weather/icons/nmist.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nscattered_clouds.svg b/.config/awesome/widget/weather/icons/nscattered_clouds.svg new file mode 100644 index 0000000..007e66b --- /dev/null +++ b/.config/awesome/widget/weather/icons/nscattered_clouds.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nshower_rain.svg b/.config/awesome/widget/weather/icons/nshower_rain.svg new file mode 100644 index 0000000..50b4ebc --- /dev/null +++ b/.config/awesome/widget/weather/icons/nshower_rain.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/nthunderstorm.svg b/.config/awesome/widget/weather/icons/nthunderstorm.svg new file mode 100644 index 0000000..73f67e5 --- /dev/null +++ b/.config/awesome/widget/weather/icons/nthunderstorm.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/refresh.svg b/.config/awesome/widget/weather/icons/refresh.svg new file mode 100644 index 0000000..0eb9ef7 --- /dev/null +++ b/.config/awesome/widget/weather/icons/refresh.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/snow.svg b/.config/awesome/widget/weather/icons/snow.svg new file mode 100644 index 0000000..f4fcc6a --- /dev/null +++ b/.config/awesome/widget/weather/icons/snow.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/sun_icon.svg b/.config/awesome/widget/weather/icons/sun_icon.svg new file mode 100644 index 0000000..24ac40d --- /dev/null +++ b/.config/awesome/widget/weather/icons/sun_icon.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/sunrise.svg b/.config/awesome/widget/weather/icons/sunrise.svg new file mode 100644 index 0000000..f0e8a47 --- /dev/null +++ b/.config/awesome/widget/weather/icons/sunrise.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/sunset.svg b/.config/awesome/widget/weather/icons/sunset.svg new file mode 100644 index 0000000..d60f574 --- /dev/null +++ b/.config/awesome/widget/weather/icons/sunset.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/icons/weather-error.svg b/.config/awesome/widget/weather/icons/weather-error.svg new file mode 100644 index 0000000..afcb331 --- /dev/null +++ b/.config/awesome/widget/weather/icons/weather-error.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/weather/init.lua b/.config/awesome/widget/weather/init.lua new file mode 100644 index 0000000..1c1a516 --- /dev/null +++ b/.config/awesome/widget/weather/init.lua @@ -0,0 +1,398 @@ +local wibox = require('wibox') +local awful = require('awful') +local gears = require('gears') +local naughty = require('naughty') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/weather/icons/' +local clickable_container = require('widget.clickable-container') +local json = require('library.json') + +local config = require('configuration.config') +local secrets = { + key = config.widget.weather.key, + city_id = config.widget.weather.city_id, + units = config.widget.weather.units, + update_interval = config.widget.weather.update_interval +} + +local weather_icon_widget = wibox.widget { + { + id = 'icon', + image = widget_icon_dir .. 'weather-error.svg', + resize = true, + forced_height = dpi(45), + forced_width = dpi(45), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local sunrise_icon_widget = wibox.widget { + { + id = 'sunrise_icon', + image = widget_icon_dir .. 'sunrise.svg', + resize = true, + forced_height = dpi(18), + forced_width = dpi(18), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local sunset_icon_widget = wibox.widget { + { + id = 'sunset_icon', + image = widget_icon_dir .. 'sunset.svg', + resize = true, + forced_height = dpi(18), + forced_width = dpi(18), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local refresh_icon_widget = wibox.widget { + { + id = 'refresh_icon', + image = widget_icon_dir .. 'refresh.svg', + resize = true, + forced_height = dpi(18), + forced_width = dpi(18), + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.horizontal +} + +local refresh_button = clickable_container(refresh_icon_widget) +refresh_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awesome.emit_signal('widget::weather_fetch') + awesome.emit_signal('widget::forecast_fetch') + end + ) + ) +) + +local refresh_widget = wibox.widget { + refresh_button, + bg = beautiful.transparent, + shape = gears.shape.circle, + widget = wibox.container.background +} + +local weather_desc_temp = wibox.widget { + { + id = 'description', + markup = 'Dust and clouds, -1000°C', + font = 'Inter Regular 10', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + id = 'scroll_container', + max_size = 345, + speed = 75, + expand = true, + direction = 'h', + step_function = wibox.container.scroll + .step_functions.waiting_nonlinear_back_and_forth, + fps = 30, + layout = wibox.container.scroll.horizontal, +} + +local weather_location = wibox.widget { + { + id = 'location', + markup = 'Earth, Milky Way', + font = 'Inter Regular 10', + align = 'left', + valign = 'center', + widget = wibox.widget.textbox + }, + id = 'scroll_container', + max_size = 345, + speed = 75, + expand = true, + direction = 'h', + step_function = wibox.container.scroll + .step_functions.waiting_nonlinear_back_and_forth, + fps = 30, + layout = wibox.container.scroll.horizontal, +} + +local weather_sunrise = wibox.widget { + markup = '00:00', + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local weather_sunset = wibox.widget { + markup = '00:00', + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local weather_data_time = wibox.widget { + markup = '00:00', + font = 'Inter Regular 10', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local weather_forecast_tooltip = awful.tooltip { + text = 'Loading...', + objects = {weather_icon_widget}, + mode = 'outside', + align = 'right', + preferred_positions = {'left', 'right', 'top', 'bottom'}, + margin_leftright = dpi(8), + margin_topbottom = dpi(8) +} + +local weather_report = wibox.widget { + { + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(10), + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + weather_icon_widget, + nil + }, + { + layout = wibox.layout.align.vertical, + expand = 'none', + nil, + { + layout = wibox.layout.fixed.vertical, + weather_location, + weather_desc_temp, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(7), + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(3), + sunrise_icon_widget, + weather_sunrise + }, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(3), + sunset_icon_widget, + weather_sunset + }, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(3), + refresh_widget, + weather_data_time + } + } + }, + nil + } + }, + margins = dpi(10), + widget = wibox.container.margin + }, + forced_height = dpi(92), + bg = beautiful.groups_bg, + shape = function(cr, width, height) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) + end, + widget = wibox.container.background +} + +-- Return weather symbol +local get_weather_symbol = function() + local symbol_tbl = { + ['metric'] = '°C', + ['imperial'] = '°F' + } + return symbol_tbl[secrets.units] +end + +-- Create openweathermap script based on pass mode +-- Mode must be `forecast` or `weather` +local create_weather_script = function(mode) + local weather_script = [[ + KEY="]] .. secrets.key .. [[" + CITY="]] .. secrets.city_id .. [[" + UNITS="]] .. secrets.units .. [[" + + weather=$(curl -sf "http://api.openweathermap.org/data/2.5/]] .. mode .. + [[?APPID="${KEY}"&id="${CITY}"&units="${UNITS}"") + + if [ ! -z "$weather" ]; then + printf "${weather}" + else + printf "error" + fi + ]] + + return weather_script +end + +awesome.connect_signal( + 'widget::forecast_fetch', + function() + awful.spawn.easy_async_with_shell( + create_weather_script('forecast'), + function(stdout) + if stdout:match('error') then + weather_forecast_tooltip:set_markup('Can\'t retrieve data!') + else + local forecast_data = json.parse(stdout) + local forecast = '' + + for i = 8, 40, 8 do + local day = os.date('%A @ %H:%M', forecast_data.list[i].dt) + local temp = math.floor(forecast_data.list[i].main.temp + 0.5) + local feels_like = math.floor(forecast_data.list[i].main.feels_like + 0.5) + local weather = forecast_data.list[i].weather[1].description + + -- Capitalize weather description + weather = weather:sub(1, 1):upper() .. weather:sub(2) + + forecast = forecast .. '' .. day .. '\n' .. + 'Weather: ' .. weather .. '\n' .. + 'Temperature: ' .. temp .. get_weather_symbol() .. '\n' .. + 'Feels like: ' .. feels_like .. get_weather_symbol() .. '\n\n' + + weather_forecast_tooltip:set_markup(forecast:sub(1, -2)) + end + end + end + ) + end +) + +awesome.connect_signal( + 'widget::weather_fetch', + function() + awful.spawn.easy_async_with_shell( + create_weather_script('weather'), + function(stdout) + if stdout:match('error') then + awesome.emit_signal( + 'widget::weather_update', + '...', + 'Dust and clouds, -1000°C', + 'Earth, Milky Way', + '00:00', + '00:00', + '00:00' + ) + else + -- Parse JSON string + local weather_data = json.parse(stdout) + + -- Process weather data + local location = weather_data.name + local country = weather_data.sys.country + local sunrise = os.date('%H:%M', weather_data.sys.sunrise) + local sunset = os.date('%H:%M', weather_data.sys.sunset) + local refresh = os.date('%H:%M', weather_data.dt) + local temperature = math.floor(weather_data.main.temp + 0.5) + local weather = weather_data.weather[1].description + local weather_icon = weather_data.weather[1].icon + + -- Capitalize weather description + local weather = weather:sub(1, 1):upper() .. weather:sub(2) + + -- Contantenate weather description and symbol + local weather_description = weather .. ', ' .. temperature .. get_weather_symbol() + + -- Contantenate city and country + local weather_location = location .. ', ' .. country + + awesome.emit_signal( + 'widget::weather_update', + weather_icon, + weather_description, + weather_location, + sunrise, + sunset, + refresh + ) + end + end + ) + end +) + +local update_widget_timer = gears.timer { + timeout = secrets.update_interval, + autostart = true, + call_now = true, + single_shot = false, + callback = function() + awesome.emit_signal('widget::weather_fetch') + awesome.emit_signal('widget::forecast_fetch') + end +} + +awesome.connect_signal( + 'system::network_connected', + function() + awesome.emit_signal('widget::weather_fetch') + awesome.emit_signal('widget::forecast_fetch') + end +) + +awesome.connect_signal( + 'widget::weather_update', + function(code, desc, location, sunrise, sunset, data_receive) + local widget_icon_name = 'weather-error' + + local icon_tbl = { + ['01d'] = 'sun_icon.svg', + ['01n'] = 'moon_icon.svg', + ['02d'] = 'dfew_clouds.svg', + ['02n'] = 'nfew_clouds.svg', + ['03d'] = 'dscattered_clouds.svg', + ['03n'] = 'nscattered_clouds.svg', + ['04d'] = 'dbroken_clouds.svg', + ['04n'] = 'nbroken_clouds.svg', + ['09d'] = 'dshower_rain.svg', + ['09n'] = 'nshower_rain.svg', + ['10d'] = 'd_rain.svg', + ['10n'] = 'n_rain.svg', + ['11d'] = 'dthunderstorm.svg', + ['11n'] = 'nthunderstorm.svg', + ['13d'] = 'snow.svg', + ['13n'] = 'snow.svg', + ['50d'] = 'dmist.svg', + ['50n'] = 'nmist.svg', + ['...'] = 'weather-error.svg' + } + + widget_icon_name = icon_tbl[code] + + weather_icon_widget.icon:set_image(widget_icon_dir .. widget_icon_name) + weather_icon_widget.icon:emit_signal('widget::redraw_needed') + + weather_desc_temp.description:set_markup(desc) + weather_location.location:set_markup(location) + weather_sunrise:set_markup(sunrise) + weather_sunset:set_markup(sunset) + weather_data_time:set_markup(data_receive) + end +) + +return weather_report diff --git a/.config/awesome/widget/xdg-folders/documents.lua b/.config/awesome/widget/xdg-folders/documents.lua new file mode 100644 index 0000000..5906a8b --- /dev/null +++ b/.config/awesome/widget/xdg-folders/documents.lua @@ -0,0 +1,59 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local docu_widget = wibox.widget { + { + image = widget_icon_dir .. 'folder-documents' .. '.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal + } + + local docu_button = wibox.widget { + { + docu_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + docu_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('xdg-open $(xdg-user-dir DOCUMENTS)') + end + ) + ) + ) + + awful.tooltip( + { + objects = {docu_button}, + mode = 'outside', + align = 'right', + text = 'Documents', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + ) + + return docu_button +end + +return create_widget diff --git a/.config/awesome/widget/xdg-folders/downloads.lua b/.config/awesome/widget/xdg-folders/downloads.lua new file mode 100644 index 0000000..02f572b --- /dev/null +++ b/.config/awesome/widget/xdg-folders/downloads.lua @@ -0,0 +1,59 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local dl_widget = wibox.widget { + { + image = widget_icon_dir .. 'folder-download.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal + } + + local downloads_button = wibox.widget { + { + dl_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + downloads_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('xdg-open $(xdg-user-dir DOWNLOAD)') + end + ) + ) + ) + + awful.tooltip( + { + objects = {downloads_button}, + mode = 'outside', + align = 'right', + text = 'Downloads', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + ) + + return downloads_button +end + +return create_widget diff --git a/.config/awesome/widget/xdg-folders/home.lua b/.config/awesome/widget/xdg-folders/home.lua new file mode 100644 index 0000000..24c3820 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/home.lua @@ -0,0 +1,59 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local home_widget = wibox.widget { + { + image = widget_icon_dir .. 'user-home.svg', + resize = true, + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.align.horizontal + } + + local home_button = wibox.widget { + { + home_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + home_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('xdg-open $(xdg-user-dir)') + end + ) + ) + ) + + awful.tooltip( + { + objects = {home_button}, + mode = 'outside', + align = 'right', + text = 'Home', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + ) + + return home_button +end + +return create_widget diff --git a/.config/awesome/widget/xdg-folders/icons/folder-documents.svg b/.config/awesome/widget/xdg-folders/icons/folder-documents.svg new file mode 100644 index 0000000..e6a53e5 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/folder-documents.svg @@ -0,0 +1,126 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/folder-download.svg b/.config/awesome/widget/xdg-folders/icons/folder-download.svg new file mode 100644 index 0000000..9b75134 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/folder-download.svg @@ -0,0 +1,134 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg b/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg new file mode 100644 index 0000000..014b5b3 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/folder-pictures.svg @@ -0,0 +1,127 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/folder-videos.svg b/.config/awesome/widget/xdg-folders/icons/folder-videos.svg new file mode 100644 index 0000000..50b53df --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/folder-videos.svg @@ -0,0 +1,126 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/no.svg b/.config/awesome/widget/xdg-folders/icons/no.svg new file mode 100644 index 0000000..0654b8a --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/no.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/open-folder.svg b/.config/awesome/widget/xdg-folders/icons/open-folder.svg new file mode 100644 index 0000000..f1f131d --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/open-folder.svg @@ -0,0 +1,110 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/user-home.svg b/.config/awesome/widget/xdg-folders/icons/user-home.svg new file mode 100644 index 0000000..b0a0839 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/user-home.svg @@ -0,0 +1,126 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg b/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg new file mode 100644 index 0000000..f4d107f --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/user-trash-empty.svg @@ -0,0 +1,160 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg b/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg new file mode 100644 index 0000000..2d75d2d --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/user-trash-full.svg @@ -0,0 +1,979 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/icons/yes.svg b/.config/awesome/widget/xdg-folders/icons/yes.svg new file mode 100644 index 0000000..2617c5d --- /dev/null +++ b/.config/awesome/widget/xdg-folders/icons/yes.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/.config/awesome/widget/xdg-folders/init.lua b/.config/awesome/widget/xdg-folders/init.lua new file mode 100644 index 0000000..f0448ff --- /dev/null +++ b/.config/awesome/widget/xdg-folders/init.lua @@ -0,0 +1,31 @@ +local awful = require('awful') +local wibox = require('wibox') +local beautiful = require('beautiful') +local dpi = beautiful.xresources.apply_dpi + +local create_xdg_widgets = function() + local separator = wibox.widget { + orientation = 'horizontal', + forced_height = dpi(1), + forced_width = dpi(1), + span_ratio = 0.55, + widget = wibox.widget.separator + } + + return wibox.widget { + layout = wibox.layout.align.vertical, + { + separator, + require('widget.xdg-folders.home')(), + require('widget.xdg-folders.documents')(), + require('widget.xdg-folders.downloads')(), + -- require('widget.xdg-folders.pictures')(), + -- require('widget.xdg-folders.videos')(), + separator, + require('widget.xdg-folders.trash')(), + layout = wibox.layout.fixed.vertical, + }, + } +end + +return create_xdg_widgets diff --git a/.config/awesome/widget/xdg-folders/pictures.lua b/.config/awesome/widget/xdg-folders/pictures.lua new file mode 100644 index 0000000..2c591c2 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/pictures.lua @@ -0,0 +1,59 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local pic_widget = wibox.widget { + { + image = widget_icon_dir .. 'folder-pictures.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal + } + + local pic_button = wibox.widget { + { + pic_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + pic_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('xdg-open $(xdg-user-dir PICTURES)') + end + ) + ) + ) + + awful.tooltip( + { + objects = {pic_button}, + mode = 'outside', + align = 'right', + text = 'Pictures', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + ) + + return pic_button +end + +return create_widget diff --git a/.config/awesome/widget/xdg-folders/trash.lua b/.config/awesome/widget/xdg-folders/trash.lua new file mode 100644 index 0000000..2625e5a --- /dev/null +++ b/.config/awesome/widget/xdg-folders/trash.lua @@ -0,0 +1,148 @@ +local wibox = require('wibox') +local awful = require('awful') +local naughty = require('naughty') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local trash_widget = wibox.widget { + { + id = 'trash_icon', + image = widget_icon_dir .. 'user-trash-empty.svg', + resize = true, + widget = wibox.widget.imagebox + }, + layout = wibox.layout.align.horizontal + } + + local trash_menu = awful.menu({ + items = { + { + 'Open trash', + function() + awful.spawn.easy_async_with_shell( + 'gio open trash:///', + function(stdout) end, + 1 + ) + end, + widget_icon_dir .. 'open-folder.svg' + }, + { + 'Delete forever', + { + { + 'Yes', + function() + awful.spawn.easy_async_with_shell( + 'gio trash --empty', + function(stdout) + end, + 1 + ) + end, + widget_icon_dir .. 'yes.svg' + }, + { + 'No', + '', + widget_icon_dir .. 'no.svg' + } + }, + widget_icon_dir .. 'user-trash-empty.svg' + }, + } + }) + + local trash_button = wibox.widget { + { + trash_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + -- Tooltip for trash_button + trash_tooltip = awful.tooltip { + objects = {trash_button}, + mode = 'outside', + align = 'right', + markup = 'Trash', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + + -- Mouse event for trash_button + trash_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn({'gio', 'open', 'trash:///'}, false) + end + ), + awful.button( + {}, + 3, + nil, + function() + trash_menu:toggle() + trash_tooltip.visible = not trash_tooltip.visible + end + ) + ) + ) + + -- Update icon on changes + local check_trash_list = function() + awful.spawn.easy_async_with_shell( + 'gio list trash:/// | wc -l', + function(stdout) + if tonumber(stdout) > 0 then + trash_widget.trash_icon:set_image(widget_icon_dir .. 'user-trash-full.svg') + + awful.spawn.easy_async_with_shell( + 'gio list trash:///', + function(stdout) + trash_tooltip.markup = 'Trash contains:\n' .. stdout:gsub('\n$', '') + end + ) + else + trash_widget.trash_icon:set_image(widget_icon_dir .. 'user-trash-empty.svg') + trash_tooltip.markup = 'Trash empty' + end + end + ) + end + + -- Check trash on awesome (re)-start + check_trash_list() + + -- Kill the old process of gio monitor trash:/// + awful.spawn.easy_async_with_shell( + 'ps x | grep \'gio monitor trash:///\' | grep -v grep | awk \'{print $1}\' | xargs kill', + function() + awful.spawn.with_line_callback( + 'gio monitor trash:///', + { + stdout = function(_) + check_trash_list() + end + } + ) + end + ) + + return trash_button +end + +return create_widget diff --git a/.config/awesome/widget/xdg-folders/videos.lua b/.config/awesome/widget/xdg-folders/videos.lua new file mode 100644 index 0000000..5c54088 --- /dev/null +++ b/.config/awesome/widget/xdg-folders/videos.lua @@ -0,0 +1,59 @@ +local awful = require('awful') +local wibox = require('wibox') +local gears = require('gears') + +local clickable_container = require('widget.clickable-container') +local dpi = require('beautiful').xresources.apply_dpi + +local config_dir = gears.filesystem.get_configuration_dir() +local widget_icon_dir = config_dir .. 'widget/xdg-folders/icons/' + +local create_widget = function() + local vid_widget = wibox.widget { + { + image = widget_icon_dir .. 'folder-videos.svg', + widget = wibox.widget.imagebox, + resize = true + }, + layout = wibox.layout.align.horizontal + } + + local videos_button = wibox.widget { + { + vid_widget, + margins = dpi(10), + widget = wibox.container.margin + }, + widget = clickable_container + } + + videos_button:buttons( + gears.table.join( + awful.button( + {}, + 1, + nil, + function() + awful.spawn.with_shell('xdg-open $(xdg-user-dir VIDEOS)') + end + ) + ) + ) + + awful.tooltip + { + objects = {videos_button}, + mode = 'outside', + align = 'right', + margin_leftright = dpi(8), + margin_topbottom = dpi(8), + timer_function = function() + return 'Videos' + end, + preferred_positions = {'top', 'bottom', 'right', 'left'} + } + + return videos_button +end + +return create_widget