moved to personal fennel config for awesome and added qutebrowser
This commit is contained in:
parent
403cb92b7d
commit
688748f8a6
502 changed files with 8576 additions and 9597 deletions
35
awes2/module/auto-start.lua
Normal file
35
awes2/module/auto-start.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
-- MODULE AUTO-START
|
||||
-- Run all the apps listed in configuration/apps.lua as run_on_start_up only once when awesome start
|
||||
|
||||
local awful = require('awful')
|
||||
local apps = require('configuration.apps')
|
||||
|
||||
local debugger_mode = false
|
||||
|
||||
local run_once = function(cmd)
|
||||
local findme = cmd
|
||||
local firstspace = cmd:find(' ')
|
||||
if firstspace then
|
||||
findme = cmd:sub(0, firstspace - 1)
|
||||
end
|
||||
awful.spawn.easy_async_with_shell(
|
||||
string.format('pgrep -u $USER -x %s > /dev/null || (%s)', findme, cmd),
|
||||
function(stdout, stderr)
|
||||
-- Debugger
|
||||
if not stderr or stderr == '' or not debugger_mode then
|
||||
return
|
||||
end
|
||||
require('naughty').notification({
|
||||
app_name = 'Start-up Applications',
|
||||
title = '<b>Oof! Error detected when starting an application!</b>',
|
||||
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
|
83
awes2/module/backdrop.lua
Normal file
83
awes2/module/backdrop.lua
Normal file
|
@ -0,0 +1,83 @@
|
|||
local wibox = require('wibox')
|
||||
local gears = require('gears')
|
||||
local awful = require('awful')
|
||||
|
||||
local function update_backdrop(w, c)
|
||||
local cairo = require('lgi').cairo
|
||||
local geo = c.screen.geometry
|
||||
|
||||
w.x = geo.x
|
||||
w.y = geo.y
|
||||
w.width = geo.width
|
||||
w.height = geo.height
|
||||
|
||||
-- Create an image surface that is as large as the wibox
|
||||
local shape = cairo.ImageSurface.create(cairo.Format.A1, geo.width, geo.height)
|
||||
local cr = cairo.Context(shape)
|
||||
|
||||
-- Fill with "completely opaque"
|
||||
cr.operator = 'SOURCE'
|
||||
cr:set_source_rgba(1, 1, 1, 1)
|
||||
cr:paint()
|
||||
|
||||
-- Remove the shape of the client
|
||||
local c_geo = c:geometry()
|
||||
local c_shape = gears.surface(c.shape_bounding)
|
||||
cr:set_source_rgba(0, 0, 0, 0)
|
||||
cr:mask_surface(c_shape, c_geo.x + c.border_width - geo.x, c_geo.y + c.border_width - geo.y)
|
||||
c_shape:finish()
|
||||
|
||||
w.shape_bounding = shape._native
|
||||
shape:finish()
|
||||
w:draw()
|
||||
end
|
||||
|
||||
local function backdrop(c)
|
||||
local function update()
|
||||
update_backdrop(c.backdrop, c)
|
||||
end
|
||||
if not c.backdrop then
|
||||
c.backdrop = wibox {ontop = true, bg = '#00000054', type = 'splash'}
|
||||
c.backdrop:buttons(
|
||||
awful.util.table.join(
|
||||
awful.button(
|
||||
{},
|
||||
1,
|
||||
function()
|
||||
c:kill()
|
||||
end
|
||||
)
|
||||
)
|
||||
)
|
||||
c:connect_signal('property::geometry', update)
|
||||
c:connect_signal(
|
||||
'property::shape_client_bounding',
|
||||
function()
|
||||
gears.timer.delayed_call(update)
|
||||
end
|
||||
)
|
||||
c:connect_signal(
|
||||
'unmanage',
|
||||
function()
|
||||
c.backdrop.visible = false
|
||||
end
|
||||
)
|
||||
c:connect_signal(
|
||||
'property::shape_bounding',
|
||||
function()
|
||||
gears.timer.delayed_call(update)
|
||||
end
|
||||
)
|
||||
end
|
||||
update()
|
||||
c.backdrop.visible = true
|
||||
end
|
||||
|
||||
client.connect_signal(
|
||||
'manage',
|
||||
function(c)
|
||||
if c.draw_backdrop == true then
|
||||
backdrop(c)
|
||||
end
|
||||
end
|
||||
)
|
157
awes2/module/battery-notifier.lua
Normal file
157
awes2/module/battery-notifier.lua
Normal file
|
@ -0,0 +1,157 @@
|
|||
-- Battery notification module
|
||||
-- Dependencies:
|
||||
-- acpid, upower, acpi_listens, acpi_call
|
||||
-- enabled acpid service
|
||||
|
||||
local awful = require('awful')
|
||||
local naughty = require('naughty')
|
||||
local icons = require('theme.icons')
|
||||
|
||||
local update_interval = 30
|
||||
|
||||
-- Periodically get battery info
|
||||
awful.widget.watch(
|
||||
[[
|
||||
sh -c "
|
||||
upower -i $(upower -e | grep BAT) | grep percentage | awk '{print $2}'
|
||||
"]],
|
||||
update_interval,
|
||||
function(widget, stdout)
|
||||
local battery = stdout:gsub("%%", "")
|
||||
awesome.emit_signal("module::battery", tonumber(battery))
|
||||
end
|
||||
)
|
||||
|
||||
local emit_charger_info = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"cat /sys/class/power_supply/*/online",
|
||||
function (stdout)
|
||||
status = tonumber(stdout)
|
||||
if status == 1 then
|
||||
awesome.emit_signal("module::charger", true)
|
||||
else
|
||||
awesome.emit_signal("module::charger", false)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
emit_charger_info()
|
||||
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"ps x | grep \"acpi_listen\" | grep -v grep | awk '{print $1}' | xargs kill",
|
||||
function ()
|
||||
awful.spawn.with_line_callback(
|
||||
[[
|
||||
sh -c '
|
||||
acpi_listen | grep --line-buffered ac_adapter
|
||||
']],
|
||||
{
|
||||
stdout = function(_)
|
||||
emit_charger_info()
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
local charger_plugged = true
|
||||
local battery_full_already_notified = true
|
||||
local battery_low_already_notified = false
|
||||
local battery_critical_already_notified = false
|
||||
|
||||
local last_notification
|
||||
|
||||
local function send_notification(title, text, icon, timeout, urgency)
|
||||
|
||||
local args = {
|
||||
title = title,
|
||||
text = text,
|
||||
icon = icon,
|
||||
timeout = timeout,
|
||||
urgency = urgency,
|
||||
app_name = 'Power Notification'
|
||||
}
|
||||
|
||||
if last_notification and not last_notification.is_expired then
|
||||
last_notification.title = args.title
|
||||
last_notification.text = args.text
|
||||
last_notification.icon = args.icon
|
||||
else
|
||||
last_notification = naughty.notification(args)
|
||||
end
|
||||
|
||||
last_notification = notification
|
||||
end
|
||||
|
||||
-- Full / Low / Critical notifications
|
||||
awesome.connect_signal("module::battery", function(battery)
|
||||
|
||||
local text
|
||||
local icon
|
||||
local timeout
|
||||
if not charger_plugged then
|
||||
|
||||
icon = icons.batt_discharging
|
||||
|
||||
if battery < 6 and not battery_critical_already_notified then
|
||||
battery_critical_already_notified = true
|
||||
text = "Battery Critical!"
|
||||
timeout = 0
|
||||
urgency = 'critical'
|
||||
elseif battery < 16 and not battery_low_already_notified then
|
||||
battery_low_already_notified = true
|
||||
text = "Battery Full!"
|
||||
timeout = 6
|
||||
urgency = 'normal'
|
||||
end
|
||||
|
||||
else
|
||||
icon = icons.batt_charging
|
||||
if battery ~= nil then
|
||||
if battery > 99 and not battery_full_already_notified then
|
||||
battery_full_already_notified = true
|
||||
text = "Battery Full!"
|
||||
timeout = 6
|
||||
urgency = 'normal'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If text has been initialized, then we need to send a
|
||||
-- notification
|
||||
if text then
|
||||
send_notification("Battery status", text, icon, timeout, urgency)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
-- Charger notifications
|
||||
local charger_first_time = true
|
||||
awesome.connect_signal("module::charger", function(plugged)
|
||||
charger_plugged = plugged
|
||||
local text
|
||||
local icon
|
||||
-- TODO if charger is plugged and battery is full, then set
|
||||
-- battery_full_already_notified to true
|
||||
if plugged then
|
||||
battery_critical_already_notified = false
|
||||
battery_low_already_notified = false
|
||||
text = "Plugged"
|
||||
icon = icons.batt_charging
|
||||
urgency = 'normal'
|
||||
else
|
||||
battery_full_already_notified = false
|
||||
text = "Unplugged"
|
||||
icon = icons.batt_discharging
|
||||
urgency = 'normal'
|
||||
end
|
||||
|
||||
-- Do not send a notification the first time (when AwesomeWM (re)starts)
|
||||
if charger_first_time then
|
||||
charger_first_time = false
|
||||
else
|
||||
send_notification("Charger Status", text, icon, 3, urgency)
|
||||
end
|
||||
end)
|
||||
|
272
awes2/module/brightness-osd.lua
Normal file
272
awes2/module/brightness-osd.lua
Normal file
|
@ -0,0 +1,272 @@
|
|||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
|
||||
local clickable_container = require('widget.clickable-container')
|
||||
local icons = require('theme.icons')
|
||||
local spawn = require('awful.spawn')
|
||||
|
||||
screen.connect_signal("request::desktop_decoration", function(s)
|
||||
|
||||
s.show_bri_osd = false
|
||||
|
||||
local osd_header = wibox.widget {
|
||||
text = 'Brightness',
|
||||
font = 'VictorMono Nerd Font 12',
|
||||
align = 'left',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local osd_value = wibox.widget {
|
||||
text = '0%',
|
||||
font = 'VictorMono Nerd Font 12',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local slider_osd = wibox.widget {
|
||||
nil,
|
||||
{
|
||||
id = 'bri_osd_slider',
|
||||
bar_shape = gears.shape.rounded_rect,
|
||||
bar_height = dpi(2),
|
||||
bar_color = '#ffffff20',
|
||||
bar_active_color = '#f2f2f2EE',
|
||||
handle_color = '#ffffff',
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_width = dpi(15),
|
||||
handle_border_color = '#00000012',
|
||||
handle_border_width = dpi(1),
|
||||
maximum = 100,
|
||||
widget = wibox.widget.slider,
|
||||
},
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
local bri_osd_slider = slider_osd.bri_osd_slider
|
||||
|
||||
-- Update brightness level using slider value
|
||||
bri_osd_slider:connect_signal(
|
||||
'property::value',
|
||||
function()
|
||||
|
||||
local brightness_level = bri_osd_slider:get_value()
|
||||
|
||||
spawn('light -S ' .. math.max(brightness_level, 5), false)
|
||||
|
||||
-- Update textbox widget text
|
||||
osd_value.text = brightness_level .. '%'
|
||||
|
||||
-- Update the brightness slider if values here change
|
||||
awesome.emit_signal('widget::brightness:update', brightness_level)
|
||||
|
||||
if s.show_bri_osd then
|
||||
awesome.emit_signal(
|
||||
'module::brightness_osd:show',
|
||||
true
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
bri_osd_slider:connect_signal(
|
||||
'button::press',
|
||||
function()
|
||||
s.show_bri_osd = true
|
||||
end
|
||||
)
|
||||
bri_osd_slider:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
s.show_bri_osd = false
|
||||
end
|
||||
)
|
||||
bri_osd_slider:connect_signal(
|
||||
'mouse::enter',
|
||||
function()
|
||||
s.show_bri_osd = true
|
||||
end
|
||||
)
|
||||
|
||||
-- The emit will come from brightness slider
|
||||
awesome.connect_signal(
|
||||
'module::brightness_osd',
|
||||
function(brightness)
|
||||
bri_osd_slider:set_value(brightness)
|
||||
end
|
||||
)
|
||||
|
||||
local icon = wibox.widget {
|
||||
{
|
||||
image = icons.brightness,
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
top = dpi(12),
|
||||
bottom = dpi(12),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local brightness_slider_osd = wibox.widget {
|
||||
icon,
|
||||
slider_osd,
|
||||
spacing = dpi(24),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
}
|
||||
|
||||
-- Create the box
|
||||
local osd_height = dpi(100)
|
||||
local osd_width = dpi(300)
|
||||
|
||||
local osd_margin = dpi(10)
|
||||
|
||||
s.brightness_osd_overlay = awful.popup {
|
||||
widget = {
|
||||
-- Removing this block will cause an error...
|
||||
},
|
||||
ontop = true,
|
||||
visible = false,
|
||||
type = 'notification',
|
||||
screen = s,
|
||||
height = osd_height,
|
||||
width = osd_width,
|
||||
maximum_height = osd_height,
|
||||
maximum_width = osd_width,
|
||||
offset = dpi(5),
|
||||
shape = gears.shape.rectangle,
|
||||
bg = beautiful.transparent,
|
||||
preferred_anchors = 'middle',
|
||||
preferred_positions = {'left', 'right', 'top', 'bottom'},
|
||||
|
||||
}
|
||||
|
||||
s.brightness_osd_overlay : setup {
|
||||
{
|
||||
{
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
forced_height = dpi(48),
|
||||
osd_header,
|
||||
nil,
|
||||
osd_value
|
||||
},
|
||||
brightness_slider_osd,
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
left = dpi(24),
|
||||
right = dpi(24),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.background,
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = wibox.container.background()
|
||||
}
|
||||
|
||||
local hide_osd = gears.timer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
awful.screen.focused().brightness_osd_overlay.visible = false
|
||||
end
|
||||
}
|
||||
|
||||
local timer_rerun = function()
|
||||
if hide_osd.started then
|
||||
hide_osd:again()
|
||||
else
|
||||
hide_osd:start()
|
||||
end
|
||||
end
|
||||
|
||||
-- Reset timer on mouse hover
|
||||
s.brightness_osd_overlay:connect_signal(
|
||||
'mouse::enter',
|
||||
function()
|
||||
s.show_bri_osd = true
|
||||
timer_rerun()
|
||||
end
|
||||
)
|
||||
s.brightness_osd_overlay:connect_signal(
|
||||
'mouse::enter',
|
||||
function()
|
||||
s.show_bri_osd = false
|
||||
timer_rerun()
|
||||
end
|
||||
)
|
||||
|
||||
local placement_placer = function()
|
||||
|
||||
local focused = awful.screen.focused()
|
||||
|
||||
local right_panel = focused.right_panel
|
||||
local left_panel = focused.left_panel
|
||||
local volume_osd = focused.brightness_osd_overlay
|
||||
|
||||
if right_panel and left_panel then
|
||||
if right_panel.visible then
|
||||
awful.placement.bottom_left(focused.brightness_osd_overlay, { margins = {
|
||||
left = osd_margin + left_panel.width,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if right_panel then
|
||||
if right_panel.visible then
|
||||
awful.placement.bottom_left(focused.brightness_osd_overlay, { margins = {
|
||||
left = osd_margin,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
awful.placement.bottom_right(focused.brightness_osd_overlay, { margins = {
|
||||
left = 0,
|
||||
right = osd_margin,
|
||||
top = 0,
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
end
|
||||
|
||||
awesome.connect_signal(
|
||||
'module::brightness_osd:show',
|
||||
function(bool)
|
||||
placement_placer()
|
||||
awful.screen.focused().brightness_osd_overlay.visible = bool
|
||||
if bool then
|
||||
timer_rerun()
|
||||
awesome.emit_signal(
|
||||
'module::volume_osd:show',
|
||||
false
|
||||
)
|
||||
else
|
||||
if hide_osd.started then
|
||||
hide_osd:stop()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
end)
|
112
awes2/module/decorate-client.lua
Normal file
112
awes2/module/decorate-client.lua
Normal file
|
@ -0,0 +1,112 @@
|
|||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
local function render_client(client, mode)
|
||||
|
||||
if client.skip_decoration or (client.rendering_mode == mode) then
|
||||
return
|
||||
end
|
||||
|
||||
client.rendering_mode = mode
|
||||
client.floating = false
|
||||
client.maximized = false
|
||||
client.above = false
|
||||
client.below = false
|
||||
client.ontop = false
|
||||
client.sticky = false
|
||||
client.maximized_horizontal = false
|
||||
client.maximized_vertical = false
|
||||
|
||||
if client.rendering_mode == 'maximized' then
|
||||
client.border_width = 0
|
||||
client.shape = function(cr, w, h)
|
||||
gears.shape.rectangle(cr, w, h)
|
||||
end
|
||||
elseif client.rendering_mode ~= 'maximized' then
|
||||
client.border_width = beautiful.border_width
|
||||
client.shape = function(cr, w, h)
|
||||
gears.shape.rounded_rect(cr, w, h, beautiful.client_radius)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local changes_on_screen_called = false
|
||||
|
||||
local function changes_on_screen(current_screen)
|
||||
|
||||
local tag_is_max = current_screen.selected_tag ~= nil and
|
||||
current_screen.selected_tag.layout == awful.layout.suit.max
|
||||
|
||||
local clients_to_manage = {}
|
||||
|
||||
for _, client in pairs(current_screen.clients) do
|
||||
if not client.skip_decoration and not client.hidden then
|
||||
table.insert(clients_to_manage, client)
|
||||
end
|
||||
end
|
||||
|
||||
if (tag_is_max or #clients_to_manage == 1) then
|
||||
current_screen.client_mode = 'maximized'
|
||||
else
|
||||
current_screen.client_mode = 'dwindle'
|
||||
end
|
||||
|
||||
for _, client in pairs(clients_to_manage) do
|
||||
render_client(client, current_screen.client_mode)
|
||||
end
|
||||
changes_on_screen_called = false
|
||||
end
|
||||
|
||||
|
||||
function client_callback(client)
|
||||
if not changes_on_screen_called then
|
||||
if not client.skip_decoration and client.screen then
|
||||
changes_on_screen_called = true
|
||||
local screen = client.screen
|
||||
gears.timer.delayed_call(
|
||||
function()
|
||||
changes_on_screen(screen)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tag_callback(tag)
|
||||
if not changes_on_screen_called then
|
||||
if tag.screen then
|
||||
changes_on_screen_called = true
|
||||
local screen = tag.screen
|
||||
gears.timer.delayed_call(
|
||||
function()
|
||||
changes_on_screen(screen)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
client.connect_signal('manage', client_callback)
|
||||
|
||||
client.connect_signal('unmanage', client_callback)
|
||||
|
||||
client.connect_signal('property::hidden', client_callback)
|
||||
|
||||
client.connect_signal('property::minimized', client_callback)
|
||||
|
||||
client.connect_signal(
|
||||
'property::fullscreen',
|
||||
function(c)
|
||||
if c.fullscreen then
|
||||
render_client(c, 'maximized')
|
||||
else
|
||||
client_callback(c)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
tag.connect_signal('property::selected', tag_callback)
|
||||
|
||||
tag.connect_signal('property::layout', tag_callback)
|
225
awes2/module/dynamic-wallpaper.lua
Executable file
225
awes2/module/dynamic-wallpaper.lua
Executable file
|
@ -0,0 +1,225 @@
|
|||
----------------------------------------------------------------------------
|
||||
--- Wallpaper changer module
|
||||
--
|
||||
-- @author Gerome Matilla <gerome.matilla07@gmail.com>
|
||||
-- @copyright 2019 Gerome Matilla
|
||||
-- @module wallchange
|
||||
--
|
||||
--- Nevermind this. Do what you want.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
-- This module changes wallpaper based on declared time
|
||||
-- It checks the difference between the current time and the next scheduled time
|
||||
-- Then convert it to seconds to set it as a timeout value
|
||||
|
||||
-- Limitations:
|
||||
-- Timeout paused when laptop/pc is suspended or in sleep mode, and there's probably some bugs too so whatever
|
||||
|
||||
local awful = require('awful')
|
||||
local filesystem = require('gears.filesystem')
|
||||
local gears = require('gears')
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
|
||||
-- ========================================
|
||||
-- Configuration
|
||||
-- Change your preference here
|
||||
-- ========================================
|
||||
|
||||
-- Wallpaper directory. The default is:
|
||||
local wall_dir = filesystem.get_configuration_dir() .. 'theme/wallpapers/'
|
||||
-- local wall_dir = os.getenv('HOME') .. 'Pictures/Wallpapers/'
|
||||
|
||||
|
||||
-- Wallpapers filename
|
||||
-- Note:
|
||||
-- Default image format is jpg
|
||||
wallpaper_morning = 'morning-wallpaper.jpg'
|
||||
wallpaper_noon = 'noon-wallpaper.jpg'
|
||||
wallpaper_night = 'night-wallpaper.jpg'
|
||||
wallpaper_midnight = 'midnight-wallpaper.jpg'
|
||||
|
||||
|
||||
-- Change the wallpaper on scheduled time
|
||||
morning_schedule = '06:22:00'
|
||||
noon_schedule = '12:00:00'
|
||||
night_schedule = '17:58:00'
|
||||
midnight_schedule = '24:00:00'
|
||||
|
||||
|
||||
-- Update lockscreen background
|
||||
local update_ls_bg = false
|
||||
|
||||
-- Update lockscreen background command
|
||||
local update_ls_cmd = 'mantablockscreen --image'
|
||||
|
||||
|
||||
|
||||
-- ========================================
|
||||
-- Processes
|
||||
-- Don't touch it if it's working
|
||||
-- ========================================
|
||||
|
||||
|
||||
-- Get current time
|
||||
local current_time = function()
|
||||
return os.date("%H:%M:%S")
|
||||
end
|
||||
|
||||
|
||||
-- Countdown variable
|
||||
-- In seconds
|
||||
the_countdown = nil
|
||||
|
||||
|
||||
-- We will use an array for hour change and wallpaper string
|
||||
-- Element 0 errm 1 will store the incoming/next scheduled time
|
||||
-- Geez why the f is lua's array starts with `1`? lol
|
||||
-- Element 2 will have the wallpaper file name
|
||||
local wall_data = {}
|
||||
-- > Why array, you say?
|
||||
-- Because why not? I'm new to lua and I'm experimenting with it
|
||||
|
||||
|
||||
-- Parse HH:MM:SS to seconds
|
||||
local parse_to_seconds = function(time)
|
||||
|
||||
-- Convert HH in HH:MM:SS
|
||||
hour_sec = tonumber(string.sub(time, 1, 2)) * 3600
|
||||
|
||||
-- Convert MM in HH:MM:SS
|
||||
min_sec = tonumber(string.sub(time, 4, 5)) * 60
|
||||
|
||||
-- Get SS in HH:MM:SS
|
||||
get_sec = tonumber(string.sub(time, 7, 8))
|
||||
|
||||
-- Return computed seconds
|
||||
return (hour_sec + min_sec + get_sec)
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Get time difference
|
||||
local time_diff = function(current, schedule)
|
||||
local diff = parse_to_seconds(current) - parse_to_seconds(schedule)
|
||||
return diff
|
||||
end
|
||||
|
||||
|
||||
-- Update wallpaper (used by the manage_timer function)
|
||||
-- I think the gears.wallpaper.maximized is too fast or being ran asynchronously
|
||||
-- So the wallpaper is not being updated on awesome (re)start without this timer
|
||||
-- We need some delay.
|
||||
-- Hey it's working, so whatever
|
||||
local update_wallpaper = function(wall_name)
|
||||
gears.timer.start_new(0, function()
|
||||
|
||||
local wall_dir = wall_dir .. wall_name
|
||||
|
||||
gears.wallpaper.maximized (wall_dir, s)
|
||||
|
||||
-- Overwrite the default wallpaper
|
||||
-- This is important in case we add an extra monitor
|
||||
beautiful.wallpaper = wall_dir
|
||||
|
||||
if update_ls_bg then
|
||||
awful.spawn.easy_async_with_shell(update_ls_cmd .. ' ' .. wall_dir, function()
|
||||
--
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Updates variables
|
||||
local manage_timer = function()
|
||||
|
||||
-- Get current time
|
||||
local time_now = parse_to_seconds(current_time())
|
||||
|
||||
-- Parse the schedules to seconds
|
||||
local parsed_morning = parse_to_seconds(morning_schedule)
|
||||
local parsed_noon = parse_to_seconds(noon_schedule)
|
||||
local parsed_night = parse_to_seconds(night_schedule)
|
||||
local parsed_midnight = parse_to_seconds('00:00:00')
|
||||
|
||||
-- Note that we will use '00:00:00' instead of '24:00:00' as midnight
|
||||
-- As the latter causes an error. The time_diff() returns a negative value
|
||||
|
||||
if time_now >= parsed_midnight and time_now < parsed_morning then
|
||||
-- Midnight time
|
||||
|
||||
-- Update Wallpaper
|
||||
update_wallpaper(wallpaper_midnight)
|
||||
|
||||
-- Set the data for the next scheduled time
|
||||
wall_data = {morning_schedule, wallpaper_morning}
|
||||
|
||||
elseif time_now >= parsed_morning and time_now < parsed_noon then
|
||||
-- Morning time
|
||||
|
||||
-- Update Wallpaper
|
||||
update_wallpaper(wallpaper_morning)
|
||||
|
||||
-- Set the data for the next scheduled time
|
||||
wall_data = {noon_schedule, wallpaper_noon}
|
||||
|
||||
elseif time_now >= parsed_noon and time_now < parsed_night then
|
||||
-- Noon time
|
||||
|
||||
-- Update Wallpaper
|
||||
update_wallpaper(wallpaper_noon)
|
||||
|
||||
-- Set the data for the next scheduled time
|
||||
wall_data = {night_schedule, wallpaper_night}
|
||||
|
||||
else
|
||||
-- Night time
|
||||
|
||||
-- Update Wallpaper
|
||||
update_wallpaper(wallpaper_night)
|
||||
|
||||
-- Set the data for the next scheduled time
|
||||
wall_data = {midnight_schedule, wallpaper_midnight}
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Get the time difference to set as timeout for the wall_updater timer below
|
||||
the_countdown = time_diff(wall_data[1], current_time())
|
||||
|
||||
end
|
||||
|
||||
-- Update values at startup
|
||||
manage_timer()
|
||||
|
||||
|
||||
|
||||
local wall_updater = gears.timer {
|
||||
-- The timeout is the difference of current time and the scheduled time we set above.
|
||||
timeout = the_countdown,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
|
||||
-- Emit signal to update wallpaper
|
||||
awesome.emit_signal("module::change_wallpaper")
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
-- Update wallpaper here and update the timeout for the next schedule
|
||||
awesome.connect_signal("module::change_wallpaper", function()
|
||||
|
||||
-- Update wallpaper based on the data in the array
|
||||
gears.wallpaper.maximized (wall_dir .. wall_data[2], s)
|
||||
|
||||
-- Update values for the next specified schedule
|
||||
manage_timer()
|
||||
|
||||
-- Update timer timeout for the next specified schedule
|
||||
wall_updater.timeout = the_countdown
|
||||
|
||||
-- Restart timer
|
||||
wall_updater:again()
|
||||
|
||||
end)
|
351
awes2/module/exit-screen.lua
Normal file
351
awes2/module/exit-screen.lua
Normal file
|
@ -0,0 +1,351 @@
|
|||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local wibox = require('wibox')
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
local icons = require('theme.icons')
|
||||
local apps = require('configuration.apps')
|
||||
local clickable_container = require('widget.clickable-container')
|
||||
|
||||
local filesystem = gears.filesystem
|
||||
local config_dir = filesystem.get_configuration_dir()
|
||||
local widget_icon_dir = config_dir .. 'configuration/user-profile/'
|
||||
|
||||
|
||||
local greeter_message = wibox.widget {
|
||||
markup = 'Choose wisely!',
|
||||
font = 'SF Pro Text UltraLight 48',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local profile_name = wibox.widget {
|
||||
markup = 'user@hostname',
|
||||
font = 'SF Pro Text Regular 12',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local profile_imagebox = wibox.widget {
|
||||
image = widget_icon_dir .. 'default.svg',
|
||||
resize = true,
|
||||
forced_height = dpi(110),
|
||||
clip_shape = gears.shape.circle,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
local profile_imagebox_bg = wibox.widget {
|
||||
bg = beautiful.groups_bg,
|
||||
forced_width = dpi(120),
|
||||
forced_height = dpi(120),
|
||||
shape = gears.shape.circle,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local update_profile_pic = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
apps.bins.update_profile,
|
||||
function(stdout)
|
||||
stdout = stdout:gsub('%\n','')
|
||||
if not stdout:match("default") then
|
||||
profile_imagebox:set_image(stdout)
|
||||
else
|
||||
profile_imagebox:set_image(widget_icon_dir .. 'default.svg')
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_profile_pic()
|
||||
|
||||
local update_user_name = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"printf \"$(whoami)@$(hostname)\"",
|
||||
function(stdout)
|
||||
local stdout = stdout:gsub('%\n','')
|
||||
local username = stdout:match("(.*)@")
|
||||
username = username:sub(1, 1):upper() .. username:sub(2)
|
||||
greeter_message:set_markup('Choose wisely, ' .. username .. '!')
|
||||
profile_name:set_markup(stdout)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
update_user_name()
|
||||
|
||||
local build_button = function(icon, name)
|
||||
|
||||
local button_text = wibox.widget {
|
||||
text = name,
|
||||
font = beautiful.font,
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local a_button = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
image = icon,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
margins = dpi(16),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.groups_bg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
shape = gears.shape.rounded_rect,
|
||||
forced_width = dpi(90),
|
||||
forced_height = dpi(90),
|
||||
widget = clickable_container
|
||||
},
|
||||
left = dpi(24),
|
||||
right = dpi(24),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local build_a_button = wibox.widget {
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(5),
|
||||
a_button,
|
||||
button_text
|
||||
}
|
||||
|
||||
return build_a_button
|
||||
end
|
||||
|
||||
local suspend_command = function()
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
awful.spawn.with_shell(apps.default.lock .. ' & systemctl suspend')
|
||||
end
|
||||
|
||||
local exit_command = function()
|
||||
awesome.quit()
|
||||
end
|
||||
|
||||
local lock_command = function()
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
awful.spawn.with_shell('sleep 1 && ' .. apps.default.lock)
|
||||
end
|
||||
|
||||
local poweroff_command = function()
|
||||
awful.spawn.with_shell('poweroff')
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
end
|
||||
|
||||
local reboot_command = function()
|
||||
awful.spawn.with_shell('reboot')
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
end
|
||||
|
||||
local poweroff = build_button(icons.power, 'Shutdown')
|
||||
poweroff:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
poweroff_command()
|
||||
end
|
||||
)
|
||||
|
||||
local reboot = build_button(icons.restart, 'Restart')
|
||||
reboot:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
reboot_command()
|
||||
end
|
||||
)
|
||||
|
||||
local suspend = build_button(icons.sleep, 'Sleep')
|
||||
suspend:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
suspend_command()
|
||||
end
|
||||
)
|
||||
|
||||
local exit = build_button(icons.logout, 'Logout')
|
||||
exit:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
exit_command()
|
||||
end
|
||||
)
|
||||
|
||||
local lock = build_button(icons.lock, 'Lock')
|
||||
lock:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
lock_command()
|
||||
end
|
||||
)
|
||||
|
||||
screen.connect_signal(
|
||||
"request::desktop_decoration",
|
||||
function(s)
|
||||
|
||||
s.exit_screen = wibox
|
||||
{
|
||||
screen = s,
|
||||
type = 'splash',
|
||||
visible = false,
|
||||
ontop = true,
|
||||
bg = beautiful.background,
|
||||
fg = beautiful.fg_normal,
|
||||
height = s.geometry.height,
|
||||
width = s.geometry.width,
|
||||
x = s.geometry.x,
|
||||
y = s.geometry.y
|
||||
}
|
||||
|
||||
local exit_screen_hide = function()
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
|
||||
end
|
||||
|
||||
|
||||
local exit_screen_grabber = awful.keygrabber {
|
||||
|
||||
auto_start = true,
|
||||
stop_event = 'release',
|
||||
keypressed_callback = function(self, mod, key, command)
|
||||
|
||||
if key == 's' then
|
||||
suspend_command()
|
||||
|
||||
elseif key == 'e' then
|
||||
exit_command()
|
||||
|
||||
elseif key == 'l' then
|
||||
lock_command()
|
||||
|
||||
elseif key == 'p' then
|
||||
poweroff_command()
|
||||
|
||||
elseif key == 'r' then
|
||||
reboot_command()
|
||||
|
||||
elseif key == 'Escape' or key == 'q' or key == 'x' then
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
awesome.connect_signal(
|
||||
"module::exit_screen_show",
|
||||
function()
|
||||
for s in screen do
|
||||
s.exit_screen.visible = false
|
||||
end
|
||||
awful.screen.focused().exit_screen.visible = true
|
||||
exit_screen_grabber:start()
|
||||
end
|
||||
)
|
||||
|
||||
awesome.connect_signal(
|
||||
"module::exit_screen_hide",
|
||||
function()
|
||||
exit_screen_grabber:stop()
|
||||
for s in screen do
|
||||
s.exit_screen.visible = false
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
s.exit_screen : buttons(
|
||||
gears.table.join(
|
||||
awful.button(
|
||||
{},
|
||||
2,
|
||||
function()
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
end
|
||||
),
|
||||
awful.button(
|
||||
{},
|
||||
3,
|
||||
function()
|
||||
awesome.emit_signal("module::exit_screen_hide")
|
||||
end
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
s.exit_screen : setup {
|
||||
nil,
|
||||
{
|
||||
nil,
|
||||
{
|
||||
{
|
||||
nil,
|
||||
{
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(5),
|
||||
{
|
||||
profile_imagebox_bg,
|
||||
{
|
||||
layout = wibox.layout.align.vertical,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
profile_imagebox,
|
||||
nil
|
||||
},
|
||||
nil
|
||||
},
|
||||
layout = wibox.layout.stack
|
||||
},
|
||||
profile_name
|
||||
},
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
{
|
||||
greeter_message,
|
||||
{
|
||||
poweroff,
|
||||
reboot,
|
||||
suspend,
|
||||
exit,
|
||||
lock,
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
spacing = dpi(30),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
spacing = dpi(40),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
nil
|
||||
},
|
||||
spacing = dpi(40),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
end
|
||||
)
|
896
awes2/module/lockscreen.lua
Executable file
896
awes2/module/lockscreen.lua
Executable file
|
@ -0,0 +1,896 @@
|
|||
local wibox = require('wibox')
|
||||
local gears = require('gears')
|
||||
local awful = require('awful')
|
||||
local naughty = require('naughty')
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
local filesystem = require('gears.filesystem')
|
||||
local config_dir = filesystem.get_configuration_dir()
|
||||
|
||||
local apps = require('configuration.apps')
|
||||
|
||||
local widget_icon_dir = config_dir .. 'configuration/user-profile/'
|
||||
|
||||
package.cpath = package.cpath .. ";" .. config_dir .. "/library/?.so;"
|
||||
local pam = require('liblua_pam')
|
||||
|
||||
-- General Configuration
|
||||
local capture_intruder = true -- Capture a picture using webcam
|
||||
local face_capture_dir = '$(xdg-user-dir PICTURES)/Intruders/' -- Save location, auto creates
|
||||
|
||||
-- Background Mode Configuration
|
||||
local background_mode = 'blur' -- Available background mode: `image`, `blur`, `root`, `bg_color`
|
||||
local wall_dir = config_dir .. 'theme/wallpapers/' -- Wallpaper directory
|
||||
local default_wall_name = 'morning-wallpaper.jpg' -- Default wallpaper
|
||||
local tmp_wall_dir = '/tmp/awesomewm/' .. os.getenv('USER') .. '/' -- /tmp directory
|
||||
|
||||
|
||||
-- Useful variables (DO NOT TOUCH)
|
||||
local input_password = nil
|
||||
local lock_again = nil
|
||||
local type_again = true
|
||||
local capture_now = capture_intruder
|
||||
local locked_tag = nil
|
||||
|
||||
-- Processes
|
||||
local locker = function(s)
|
||||
|
||||
local lockscreen = wibox {
|
||||
screen = s,
|
||||
visible = false,
|
||||
ontop = true,
|
||||
type = "splash",
|
||||
width = s.geometry.width,
|
||||
height = s.geometry.height,
|
||||
bg = beautiful.background,
|
||||
fg = beautiful.fg_normal
|
||||
}
|
||||
|
||||
local uname_text = wibox.widget {
|
||||
id = 'uname_text',
|
||||
markup = '$USER',
|
||||
font = 'SF Pro Display Bold 17',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local uname_text_shadow = wibox.widget {
|
||||
id = 'uname_text_shadow',
|
||||
markup = '<span foreground="#00000066">' .. '$USER' .. "</span>",
|
||||
font = 'SF Pro Display Bold 17',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local caps_text = wibox.widget {
|
||||
id = 'uname_text',
|
||||
markup = 'Caps Lock is on',
|
||||
font = 'SF Pro Display Italic 10',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
opacity = 0.0,
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
local caps_text_shadow = wibox.widget {
|
||||
id = 'uname_text',
|
||||
markup = '<span foreground="#00000066">' .. 'Caps Lock is on' .. "</span>",
|
||||
font = 'SF Pro Display Italic 10',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
opacity = 0.0,
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
-- Update username textbox
|
||||
awful.spawn.easy_async_with_shell('whoami | tr -d "\\n"', function(stdout)
|
||||
uname_text.markup = stdout
|
||||
uname_text_shadow.markup = '<span foreground="#00000066">' .. stdout .. "</span>"
|
||||
end)
|
||||
|
||||
|
||||
local profile_imagebox = wibox.widget {
|
||||
id = 'user_icon',
|
||||
image = widget_icon_dir .. 'default' .. '.svg',
|
||||
resize = true,
|
||||
forced_height = dpi(100),
|
||||
forced_width = dpi(100),
|
||||
clip_shape = gears.shape.circle,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
local update_profile_pic = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
apps.bins.update_profile,
|
||||
function(stdout)
|
||||
stdout = stdout:gsub('%\n','')
|
||||
if not stdout:match("default") then
|
||||
profile_imagebox:set_image(stdout)
|
||||
else
|
||||
profile_imagebox:set_image(widget_icon_dir .. 'default.svg')
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Update image
|
||||
gears.timer.start_new(
|
||||
2,
|
||||
function()
|
||||
update_profile_pic()
|
||||
end
|
||||
)
|
||||
|
||||
local time = wibox.widget.textclock(
|
||||
'<span font="SF Pro Display Bold 56">%H:%M</span>',
|
||||
1
|
||||
)
|
||||
|
||||
local time_shadow = wibox.widget.textclock(
|
||||
'<span foreground="#00000066" font="SF Pro Display Bold 56">%H:%M</span>',
|
||||
1
|
||||
)
|
||||
|
||||
local wanted_text = wibox.widget {
|
||||
markup = 'INTRUDER ALERT!',
|
||||
font = 'SFNS Pro Text Bold 12',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local msg_table = {
|
||||
'We are watching you.',
|
||||
'We know where you live.',
|
||||
'This incident will be reported.',
|
||||
'RUN!',
|
||||
'Yamete, Oniichan~ uwu',
|
||||
'This will self-destruct in 5 seconds!',
|
||||
'Image successfully sent!',
|
||||
'You\'re doomed!'
|
||||
}
|
||||
|
||||
local wanted_msg = wibox.widget {
|
||||
markup = 'This incident will be reported!',
|
||||
font = 'SFNS Pro Text Regular 10',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local wanted_image = wibox.widget {
|
||||
image = widget_icon_dir .. 'default.svg',
|
||||
resize = true,
|
||||
forced_height = dpi(100),
|
||||
clip_shape = gears.shape.rounded_rect,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
local wanted_poster = awful.popup {
|
||||
|
||||
widget = {
|
||||
{
|
||||
{
|
||||
wanted_text,
|
||||
{
|
||||
nil,
|
||||
wanted_image,
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
wanted_msg,
|
||||
spacing = dpi(10),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
margins = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.background,
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
bg = beautiful.transparent,
|
||||
type = 'utility',
|
||||
ontop = true,
|
||||
shape = gears.shape.rectangle,
|
||||
maximum_width = dpi(250),
|
||||
maximum_height = dpi(200),
|
||||
hide_on_right_click = false,
|
||||
preferred_anchors = {'middle'},
|
||||
visible = false
|
||||
|
||||
}
|
||||
|
||||
awful.placement.bottom(wanted_poster,
|
||||
{
|
||||
margins =
|
||||
{
|
||||
bottom = dpi(10),
|
||||
},
|
||||
parent = screen.primary
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
local date_value = function()
|
||||
local date_val = {}
|
||||
local ordinal = nil
|
||||
|
||||
local day = os.date('%d')
|
||||
local month = os.date('%B')
|
||||
|
||||
local first_digit = string.sub(day, 0, 1)
|
||||
local last_digit = string.sub(day, -1)
|
||||
|
||||
if first_digit == '0' then
|
||||
day = last_digit
|
||||
end
|
||||
|
||||
if last_digit == '1' and day ~= '11' then
|
||||
ordinal = 'st'
|
||||
elseif last_digit == '2' and day ~= '12' then
|
||||
ordinal = 'nd'
|
||||
elseif last_digit == '3' and day ~= '13' then
|
||||
ordinal = 'rd'
|
||||
else
|
||||
ordinal = 'th'
|
||||
end
|
||||
|
||||
date_val.day = day
|
||||
date_val.month = month
|
||||
date_val.ordinal= ordinal
|
||||
|
||||
return date_val
|
||||
end
|
||||
|
||||
local date = wibox.widget {
|
||||
markup = date_value().day .. date_value().ordinal .. ' of ' .. date_value().month,
|
||||
font = 'SF Pro Display Bold 20',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local date_shadow = wibox.widget {
|
||||
markup = "<span foreground='#00000066'>" .. date_value().day .. date_value().ordinal .. " of " ..
|
||||
date_value().month .. "</span>",
|
||||
font = 'SF Pro Display Bold 20',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local circle_container = wibox.widget {
|
||||
bg = '#f2f2f233',
|
||||
forced_width = dpi(110),
|
||||
forced_height = dpi(110),
|
||||
shape = gears.shape.circle,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local locker_arc = wibox.widget {
|
||||
bg = beautiful.transparent,
|
||||
forced_width = dpi(110),
|
||||
forced_height = dpi(110),
|
||||
shape = function(cr, width, height)
|
||||
gears.shape.arc(cr, width, height, dpi(5), 0, math.pi/2, true, true)
|
||||
end,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
-- Check Capslock state
|
||||
local check_caps = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
'xset q | grep Caps | cut -d: -f3 | cut -d0 -f1 | tr -d " "',
|
||||
function(stdout)
|
||||
status = stdout
|
||||
|
||||
if status:match('on') then
|
||||
caps_text.opacity = 1.0
|
||||
caps_text_shadow.opacity = 1.0
|
||||
else
|
||||
caps_text.opacity = 0.0
|
||||
caps_text_shadow.opacity = 0.0
|
||||
end
|
||||
caps_text:emit_signal('widget::redraw_needed')
|
||||
caps_text_shadow:emit_signal('widget::redraw_needed')
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local rotate_container = wibox.container.rotate()
|
||||
|
||||
local locker_widget = wibox.widget {
|
||||
{
|
||||
locker_arc,
|
||||
widget = rotate_container
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
|
||||
-- Rotation direction table
|
||||
local rotation_direction = {"north", "west", "south", "east"}
|
||||
|
||||
-- Red, Green, Yellow, Blue
|
||||
local red = beautiful.system_red_dark
|
||||
local green = beautiful.system_green_dark
|
||||
local yellow = beautiful.system_yellow_dark
|
||||
local blue = beautiful.system_blue_dark
|
||||
|
||||
-- Color table
|
||||
local arc_color = {red, green, yellow, blue}
|
||||
|
||||
|
||||
local locker_widget_rotate = function()
|
||||
|
||||
local direction = rotation_direction[math.random(#rotation_direction)]
|
||||
local color = arc_color[math.random(#arc_color)]
|
||||
|
||||
rotate_container.direction = direction
|
||||
|
||||
locker_arc.bg = color
|
||||
|
||||
rotate_container:emit_signal("widget:redraw_needed")
|
||||
locker_arc:emit_signal("widget::redraw_needed")
|
||||
locker_widget:emit_signal("widget::redraw_needed")
|
||||
|
||||
end
|
||||
|
||||
local check_webcam = function()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
[[
|
||||
ls -l /dev/video* | grep /dev/video0
|
||||
]],
|
||||
function(stdout)
|
||||
if not capture_intruder then
|
||||
capture_now = false
|
||||
return
|
||||
end
|
||||
|
||||
if not stdout:match('/dev/video0') then
|
||||
capture_now = false
|
||||
else
|
||||
capture_now = true
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
check_webcam()
|
||||
|
||||
local intruder_capture = function()
|
||||
local capture_image = [[
|
||||
|
||||
save_dir=]] .. face_capture_dir .. [[
|
||||
date=$(date +%Y%m%d_%H%M%S)
|
||||
file_loc=${save_dir}SUSPECT-${date}.png
|
||||
|
||||
if [ ! -d $save_dir ]; then
|
||||
mkdir -p $save_dir;
|
||||
fi
|
||||
|
||||
ffmpeg -f video4linux2 -s 800x600 -i /dev/video0 -ss 0:0:2 -frames 1 ${file_loc}
|
||||
|
||||
canberra-gtk-play -i camera-shutter &
|
||||
echo ${file_loc}
|
||||
|
||||
]]
|
||||
|
||||
-- Capture the filthy intruder face
|
||||
awful.spawn.easy_async_with_shell(
|
||||
capture_image,
|
||||
function(stdout)
|
||||
circle_container.bg = beautiful.groups_title_bg
|
||||
|
||||
-- Humiliate the intruder by showing his/her hideous face
|
||||
wanted_image:set_image(stdout:gsub('%\n',''))
|
||||
wanted_poster.visible= true
|
||||
wanted_msg:set_markup(msg_table[math.random(#msg_table)])
|
||||
|
||||
awful.placement.bottom(wanted_poster,
|
||||
{
|
||||
margins =
|
||||
{
|
||||
bottom = dpi(10),
|
||||
},
|
||||
parent = screen.primary
|
||||
}
|
||||
)
|
||||
wanted_image:emit_signal('widget::redraw_needed')
|
||||
|
||||
type_again = true
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local stoprightthereyoucriminalscum = function()
|
||||
|
||||
circle_container.bg = red .. 'AA'
|
||||
|
||||
if capture_now then
|
||||
intruder_capture()
|
||||
else
|
||||
gears.timer.start_new(
|
||||
1,
|
||||
function()
|
||||
circle_container.bg = beautiful.groups_title_bg
|
||||
type_again = true
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local generalkenobi_ohhellothere = function()
|
||||
|
||||
circle_container.bg = green .. 'AA'
|
||||
|
||||
-- Add a little delay before unlocking completely
|
||||
gears.timer.start_new(
|
||||
1,
|
||||
function()
|
||||
if capture_now then
|
||||
-- Hide wanted poster
|
||||
wanted_poster.visible = false
|
||||
end
|
||||
|
||||
-- Hide all the lockscreen on all screen
|
||||
for s in screen do
|
||||
if s.index == 1 then
|
||||
s.lockscreen.visible = false
|
||||
else
|
||||
s.lockscreen_extended.visible = false
|
||||
end
|
||||
end
|
||||
|
||||
circle_container.bg = beautiful.groups_title_bg
|
||||
|
||||
-- Enable locking again
|
||||
lock_again = true
|
||||
|
||||
-- Enable validation again
|
||||
type_again = true
|
||||
|
||||
-- Select old tag
|
||||
-- And restore minimized focused client if there's any
|
||||
if locked_tag then
|
||||
locked_tag.selected = true
|
||||
locked_tag = nil
|
||||
end
|
||||
local c = awful.client.restore()
|
||||
if c then
|
||||
client.focus = c
|
||||
c:raise()
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- A backdoor
|
||||
local back_door = function()
|
||||
generalkenobi_ohhellothere()
|
||||
end
|
||||
|
||||
local password_grabber = awful.keygrabber {
|
||||
auto_start = true,
|
||||
stop_event = 'release',
|
||||
mask_event_callback = true,
|
||||
keybindings = {
|
||||
awful.key {
|
||||
modifiers = {'Control'},
|
||||
key = 'u',
|
||||
on_press = function()
|
||||
input_password = nil
|
||||
|
||||
end
|
||||
},
|
||||
awful.key {
|
||||
modifiers = {'Mod1', 'Mod4', 'Shift', 'Control'},
|
||||
key = 'Return',
|
||||
on_press = function(self)
|
||||
if not type_again then
|
||||
return
|
||||
end
|
||||
self:stop()
|
||||
back_door()
|
||||
end
|
||||
}
|
||||
},
|
||||
keypressed_callback = function(self, mod, key, command)
|
||||
|
||||
if not type_again then
|
||||
return
|
||||
end
|
||||
|
||||
-- Clear input string
|
||||
if key == 'Escape' then
|
||||
-- Clear input threshold
|
||||
input_password = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Accept only the single charactered key
|
||||
-- Ignore 'Shift', 'Control', 'Return', 'F1', 'F2', etc., etc.
|
||||
if #key == 1 then
|
||||
locker_widget_rotate()
|
||||
|
||||
if input_password == nil then
|
||||
input_password = key
|
||||
return
|
||||
end
|
||||
|
||||
input_password = input_password .. key
|
||||
end
|
||||
|
||||
end,
|
||||
keyreleased_callback = function(self, mod, key, command)
|
||||
locker_arc.bg = beautiful.transparent
|
||||
locker_arc:emit_signal('widget::redraw_needed')
|
||||
|
||||
if key == 'Caps_Lock' then
|
||||
check_caps()
|
||||
return
|
||||
end
|
||||
|
||||
if not type_again then
|
||||
return
|
||||
end
|
||||
|
||||
-- Validation
|
||||
if key == 'Return' then
|
||||
|
||||
-- Validate password
|
||||
local pam_auth = false
|
||||
if input_password ~= nil then
|
||||
pam_auth = pam:auth_current_user(input_password)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if pam_auth then
|
||||
-- Come in!
|
||||
self:stop()
|
||||
generalkenobi_ohhellothere()
|
||||
else
|
||||
-- F*ck off, you [REDACTED]!
|
||||
stoprightthereyoucriminalscum()
|
||||
end
|
||||
|
||||
type_again = false
|
||||
|
||||
input_password = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
lockscreen : setup {
|
||||
layout = wibox.layout.align.vertical,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
expand = 'none',
|
||||
spacing = dpi(20),
|
||||
{
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
time_shadow,
|
||||
time,
|
||||
vertical_offset = dpi(-1),
|
||||
widget = wibox.layout.stack
|
||||
},
|
||||
nil
|
||||
|
||||
},
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
date_shadow,
|
||||
date,
|
||||
vertical_offset = dpi(-1),
|
||||
widget = wibox.layout.stack
|
||||
},
|
||||
nil
|
||||
|
||||
},
|
||||
expand = 'none',
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
{
|
||||
circle_container,
|
||||
locker_widget,
|
||||
{
|
||||
layout = wibox.layout.align.vertical,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = 'none',
|
||||
nil,
|
||||
profile_imagebox,
|
||||
nil
|
||||
},
|
||||
nil,
|
||||
},
|
||||
layout = wibox.layout.stack
|
||||
},
|
||||
{
|
||||
uname_text_shadow,
|
||||
uname_text,
|
||||
vertical_offset = dpi(-1),
|
||||
widget = wibox.layout.stack
|
||||
},
|
||||
{
|
||||
caps_text_shadow,
|
||||
caps_text,
|
||||
vertical_offset = dpi(-1),
|
||||
widget = wibox.layout.stack
|
||||
}
|
||||
},
|
||||
},
|
||||
nil
|
||||
},
|
||||
nil
|
||||
}
|
||||
|
||||
local show_lockscreen = function()
|
||||
|
||||
-- Unselect all tags and minimize the focused client
|
||||
-- Will also fix the problem with virtualbox or any other program that has keygrabbing enabled
|
||||
if client.focus then
|
||||
client.focus.minimized = true
|
||||
end
|
||||
for _, t in ipairs(mouse.screen.selected_tags) do
|
||||
locked_tag = t
|
||||
t.selected = false
|
||||
end
|
||||
|
||||
-- Why is there a lock_again variable?
|
||||
-- Well, it fixes a bug.
|
||||
-- What is the bug?
|
||||
-- It's a secret.
|
||||
|
||||
if lock_again == true or lock_again == nil then
|
||||
|
||||
-- Check capslock status
|
||||
check_caps()
|
||||
|
||||
-- Check webcam status
|
||||
check_webcam()
|
||||
|
||||
-- Show all the lockscreen on each screen
|
||||
for s in screen do
|
||||
if s.index == 1 then
|
||||
s.lockscreen.visible = true
|
||||
else
|
||||
s.lockscreen_extended.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Start key grabbing for password
|
||||
password_grabber:start()
|
||||
|
||||
-- Dont lock again
|
||||
lock_again = false
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
awesome.connect_signal(
|
||||
"module::lockscreen_show",
|
||||
function()
|
||||
if lock_again == true or lock_again == nil then
|
||||
show_lockscreen()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return lockscreen
|
||||
|
||||
end
|
||||
|
||||
-- This lockscreen is for the extra/multi monitor
|
||||
local locker_ext = function(s)
|
||||
local extended_lockscreen = wibox {
|
||||
screen = s,
|
||||
visible = false,
|
||||
ontop = true,
|
||||
ontype = 'true',
|
||||
x = s.geometry.x,
|
||||
y = s.geometry.y,
|
||||
width = s.geometry.width,
|
||||
height = s.geometry.height,
|
||||
bg = beautiful.background,
|
||||
fg = beautiful.fg_normal
|
||||
}
|
||||
|
||||
return extended_lockscreen
|
||||
end
|
||||
|
||||
local cycle_through_screens = function(s)
|
||||
if s.index == 1 then
|
||||
s.lockscreen = locker(s)
|
||||
else
|
||||
s.lockscreen_extended = locker_ext(s)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create a lockscreen for each screen
|
||||
screen.connect_signal(
|
||||
"request::desktop_decoration",
|
||||
function(s)
|
||||
cycle_through_screens(s)
|
||||
end
|
||||
)
|
||||
|
||||
-- Regenerate lockscreens if a screen was added to avoid errors
|
||||
screen.connect_signal(
|
||||
'added',
|
||||
function(s)
|
||||
cycle_through_screens(s)
|
||||
end
|
||||
|
||||
)
|
||||
|
||||
-- Regenerate lockscreens if a screen was removed to avoid errors
|
||||
screen.connect_signal(
|
||||
"removed",
|
||||
function(s)
|
||||
cycle_through_screens(s)
|
||||
end
|
||||
)
|
||||
|
||||
-- Dont show notification popups if the screen is locked
|
||||
local check_lockscreen_visibility = function()
|
||||
focused = awful.screen.focused()
|
||||
if focused.lockscreen and focused.lockscreen.visible then
|
||||
return true
|
||||
end
|
||||
if focused.lockscreen_extended and focused.lockscreen_extended.visible then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
naughty.connect_signal(
|
||||
"request::display",
|
||||
function(_)
|
||||
if check_lockscreen_visibility() then
|
||||
naughty.destroy_all_notifications(nil, 1)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Background Mode Processes
|
||||
local blur_resize_image = function(wall_name, index, ap, width, height)
|
||||
local magic = [[
|
||||
if [ ! -d ]] .. tmp_wall_dir ..[[ ]; then mkdir -p ]] .. tmp_wall_dir .. [[; fi
|
||||
|
||||
convert -quality 100 -filter Gaussian -blur 0x10 ]] .. wall_dir .. wall_name ..
|
||||
[[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height ..
|
||||
[[! ]] .. tmp_wall_dir .. index .. wall_name .. [[
|
||||
]]
|
||||
return magic
|
||||
end
|
||||
|
||||
local resize_image = function(wall_name, index, ap, width, height)
|
||||
local magic = [[
|
||||
if [ ! -d ]] .. tmp_wall_dir ..[[ ]; then mkdir -p ]] .. tmp_wall_dir .. [[; fi
|
||||
|
||||
convert -quality 100 ]] .. wall_dir .. wall_name ..
|
||||
[[ -gravity center -crop ]] .. ap .. [[:1 +repage -resize ]] .. width .. 'x' .. height ..
|
||||
[[! ]] .. tmp_wall_dir .. index .. wall_name .. [[
|
||||
]]
|
||||
return magic
|
||||
end
|
||||
|
||||
local apply_ls_bg_image = function(wall_name)
|
||||
for s in screen do
|
||||
local index = s.index .. '-'
|
||||
|
||||
local screen_width = s.geometry.width
|
||||
local screen_height = s.geometry.height
|
||||
|
||||
local aspect_ratio = screen_width / screen_height
|
||||
|
||||
aspect_ratio = math.floor(aspect_ratio * 100) / 100
|
||||
|
||||
local cmd = nil
|
||||
if background_mode == 'blur' then
|
||||
cmd = blur_resize_image(wall_name, index, aspect_ratio, screen_width, screen_height)
|
||||
else
|
||||
cmd = resize_image(wall_name, index, aspect_ratio, screen_width, screen_height)
|
||||
end
|
||||
|
||||
if s.index == 1 then
|
||||
awful.spawn.easy_async_with_shell(
|
||||
cmd,
|
||||
function(stdout, stderr)
|
||||
s.lockscreen.bgimage = tmp_wall_dir .. index .. wall_name
|
||||
end
|
||||
)
|
||||
else
|
||||
awful.spawn.easy_async_with_shell(
|
||||
cmd,
|
||||
function()
|
||||
s.lockscreen_extended.bgimage = tmp_wall_dir .. index .. wall_name
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local check_background_mode = function()
|
||||
|
||||
if background_mode == 'root' then
|
||||
|
||||
for s in screen do
|
||||
if s.index == 1 then
|
||||
s.lockscreen.bgimage = root.wallpaper()
|
||||
else
|
||||
s.lockscreen_extended.bgimage = root.wallpaper()
|
||||
end
|
||||
end
|
||||
|
||||
elseif background_mode == 'bg_color' then
|
||||
for s in screen do
|
||||
if s.index == 1 then
|
||||
s.lockscreen.bg = beautiful.background
|
||||
else
|
||||
s.lockscreen_extended.bg = beautiful.background
|
||||
end
|
||||
end
|
||||
|
||||
elseif background_mode == 'blur' or background_mode == 'image' then
|
||||
apply_ls_bg_image(default_wall_name)
|
||||
|
||||
else
|
||||
for s in screen do
|
||||
if s.index == 1 then
|
||||
s.lockscreen.bgimage = root.wallpaper()
|
||||
else
|
||||
s.lockscreen_extended.bgimage = root.wallpaper()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
check_background_mode()
|
||||
|
||||
-- Regenerate lockscreen's background if a screen was added
|
||||
screen.connect_signal(
|
||||
'added',
|
||||
function()
|
||||
check_background_mode()
|
||||
end
|
||||
|
||||
)
|
||||
|
||||
-- Regenerate lockscreen's background if a screen was removed
|
||||
screen.connect_signal(
|
||||
"removed",
|
||||
function()
|
||||
check_background_mode()
|
||||
end
|
||||
)
|
206
awes2/module/menu.lua
Normal file
206
awes2/module/menu.lua
Normal file
|
@ -0,0 +1,206 @@
|
|||
-- An applications menu
|
||||
-- Required depends: awesome-freedesktop
|
||||
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
local apps = require('configuration.apps')
|
||||
local menubar = require("menubar")
|
||||
|
||||
local hotkeys_popup = require('awful.hotkeys_popup').widget
|
||||
|
||||
local terminal = apps.default.terminal
|
||||
local web_browser = apps.default.web_browser
|
||||
local file_manager = apps.default.file_manager
|
||||
local text_editor = apps.default.text_editor
|
||||
local editor_cmd = terminal .. " -e " .. (os.getenv("EDITOR") or "nano")
|
||||
|
||||
local function is_module_available(name)
|
||||
if package.loaded[name] then
|
||||
return true
|
||||
else
|
||||
for _, searcher in ipairs(package.searchers or package.loaders) do
|
||||
local loader = searcher(name)
|
||||
if type(loader) == 'function' then
|
||||
package.preload[name] = loader
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Create a launcher widget and a main menu
|
||||
awesome_menu = {
|
||||
{
|
||||
"Hotkeys",
|
||||
function()
|
||||
hotkeys_popup.show_help(nil, awful.screen.focused())
|
||||
end,
|
||||
menubar.utils.lookup_icon("keyboard")
|
||||
},
|
||||
{
|
||||
"Edit config",
|
||||
editor_cmd .. " " .. awesome.conffile,
|
||||
menubar.utils.lookup_icon("accessories-text-editor")
|
||||
},
|
||||
{
|
||||
"Restart",
|
||||
awesome.restart,
|
||||
menubar.utils.lookup_icon("system-restart")
|
||||
},
|
||||
{
|
||||
"Quit",
|
||||
function() awesome.quit() end,
|
||||
menubar.utils.lookup_icon("system-log-out")
|
||||
}
|
||||
}
|
||||
|
||||
local default_app_menu = {
|
||||
{
|
||||
"Terminal",
|
||||
terminal,
|
||||
menubar.utils.lookup_icon("utilities-terminal")
|
||||
},
|
||||
{
|
||||
"Web browser",
|
||||
web_browser,
|
||||
menubar.utils.lookup_icon("webbrowser-app")
|
||||
},
|
||||
{
|
||||
"File Manager",
|
||||
file_manager,
|
||||
menubar.utils.lookup_icon("system-file-manager")
|
||||
},
|
||||
{
|
||||
"Text Editor",
|
||||
text_editor,
|
||||
menubar.utils.lookup_icon("accessories-text-editor")
|
||||
}
|
||||
}
|
||||
|
||||
-- Screenshot menu
|
||||
local screenshot_menu = {
|
||||
{
|
||||
"Full",
|
||||
function()
|
||||
gears.timer.start_new(
|
||||
0.1,
|
||||
function()
|
||||
awful.spawn.easy_async_with_shell(apps.bins.full_screenshot)
|
||||
end
|
||||
)
|
||||
end,
|
||||
menubar.utils.lookup_icon("accessories-screenshot")
|
||||
},
|
||||
{
|
||||
"Area",
|
||||
function()
|
||||
gears.timer.start_new(
|
||||
0.1,
|
||||
function()
|
||||
awful.spawn.easy_async_with_shell(apps.bins.area_screenshot)
|
||||
end,
|
||||
menubar.utils.lookup_icon("accessories-screenshot")
|
||||
)
|
||||
end,
|
||||
menubar.utils.lookup_icon("accessories-screenshot")
|
||||
}
|
||||
}
|
||||
|
||||
local tools_menu = {
|
||||
{
|
||||
"Awesome",
|
||||
awesome_menu,
|
||||
beautiful.awesome_icon
|
||||
},
|
||||
{
|
||||
"Take a Screenshot",
|
||||
screenshot_menu,
|
||||
menubar.utils.lookup_icon("accessories-screenshot")
|
||||
},
|
||||
{
|
||||
"End Session",
|
||||
function()
|
||||
awesome.emit_signal("module::exit_screen_show")
|
||||
end,
|
||||
menubar.utils.lookup_icon("system-shutdown")
|
||||
}
|
||||
}
|
||||
|
||||
-- A menu generated by awesome-freedesktop
|
||||
-- https://github.com/lcpz/awesome-freedesktop
|
||||
|
||||
if is_module_available("freedesktop") then
|
||||
|
||||
local freedesktop = require("freedesktop")
|
||||
|
||||
mymainmenu = freedesktop.menu.build({
|
||||
-- Not actually the size, but the quality of the icon
|
||||
icon_size = 48,
|
||||
|
||||
before = default_app_menu,
|
||||
after = tools_menu
|
||||
})
|
||||
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menu = mymainmenu })
|
||||
else
|
||||
|
||||
mymainmenu = awful.menu({
|
||||
|
||||
items = {
|
||||
{
|
||||
"Instructions",
|
||||
function()
|
||||
local naughty = require('naughty')
|
||||
|
||||
local open_github = naughty.action {
|
||||
name = 'Open Github Page',
|
||||
icon_only = false,
|
||||
}
|
||||
|
||||
open_github:connect_signal('invoked', function()
|
||||
awful.spawn.easy_async_with_shell("xdg-open https://github.com/lcpz/awesome-freedesktop")
|
||||
end)
|
||||
|
||||
local open_aur = naughty.action {
|
||||
name = 'Open AUR Page',
|
||||
icon_only = false,
|
||||
}
|
||||
|
||||
open_aur:connect_signal('invoked', function()
|
||||
awful.spawn.easy_async_with_shell("xdg-open https://aur.archlinux.org/packages/awesome-freedesktop-git/")
|
||||
end)
|
||||
|
||||
naughty.notification({
|
||||
title = 'A dependency is missing!',
|
||||
message = "You need to install <b>awesome-freedesktop.</b> " ..
|
||||
"This will populate the menu with your installed applications automatically. " ..
|
||||
"It is also available in AUR, it is called <b>awesome-freedesktop-git</b>.",
|
||||
app_name = 'System Notification',
|
||||
timeout = 0,
|
||||
urgency = 'normal',
|
||||
actions = { open_github, open_aur }
|
||||
})
|
||||
end,
|
||||
menubar.utils.lookup_icon("accessories-text-editor")
|
||||
},
|
||||
{
|
||||
"Awesome",
|
||||
awesome_menu,
|
||||
beautiful.awesome_icon
|
||||
},
|
||||
{
|
||||
"Take a Screenshot",
|
||||
screenshot_menu,
|
||||
menubar.utils.lookup_icon("accessories-screenshot")
|
||||
},
|
||||
{
|
||||
"End Session",
|
||||
function()
|
||||
awesome.emit_signal("module::exit_screen_show")
|
||||
end,
|
||||
menubar.utils.lookup_icon("system-shutdown")
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
264
awes2/module/notifications.lua
Normal file
264
awes2/module/notifications.lua
Normal file
|
@ -0,0 +1,264 @@
|
|||
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(100)
|
||||
naughty.config.defaults.border_width = 0
|
||||
naughty.config.defaults.position = 'top_right'
|
||||
naughty.config.defaults.screen = 1
|
||||
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(20)
|
||||
naughty.config.spacing = dpi(20)
|
||||
naughty.config.icon_dirs = {
|
||||
"/usr/share/icons/Papirus/",
|
||||
"/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 = 'VictorMono Nerd Font 10',
|
||||
bg = '#ff0000',
|
||||
fg = '#ffffff',
|
||||
margin = dpi(16),
|
||||
position = 'top_right',
|
||||
implicit_timeout = 15
|
||||
}
|
||||
}
|
||||
|
||||
-- Normal notifs
|
||||
ruled.notification.append_rule {
|
||||
rule = { urgency = 'normal' },
|
||||
properties = {
|
||||
font = 'VictorMono Nerd Font 10',
|
||||
bg = beautiful.transparent,
|
||||
fg = beautiful.fg_normal,
|
||||
margin = dpi(16),
|
||||
position = 'top_right',
|
||||
implicit_timeout = 8
|
||||
}
|
||||
}
|
||||
|
||||
-- Low notifs
|
||||
ruled.notification.append_rule {
|
||||
rule = { urgency = 'low' },
|
||||
properties = {
|
||||
font = 'VictorMono Nerd Font 10',
|
||||
bg = beautiful.transparent,
|
||||
fg = beautiful.fg_normal,
|
||||
margin = dpi(16),
|
||||
position = 'top_right',
|
||||
implicit_timeout = 5
|
||||
}
|
||||
}
|
||||
end)
|
||||
|
||||
|
||||
-- Error handling
|
||||
naughty.connect_signal(
|
||||
"request::display_error",
|
||||
function(message, startup)
|
||||
naughty.notification {
|
||||
urgency = "critical",
|
||||
title = "Oops, an error happened"..(startup and " during startup!" or "!"),
|
||||
message = message,
|
||||
app_name = 'System Notification',
|
||||
icon = beautiful.awesome_icon
|
||||
}
|
||||
end
|
||||
)
|
||||
|
||||
-- XDG icon lookup
|
||||
naughty.connect_signal(
|
||||
"request::icon",
|
||||
function(n, context, hints)
|
||||
if context ~= "app_icon" then return end
|
||||
|
||||
local path = menubar.utils.lookup_icon(hints.app_icon) or
|
||||
menubar.utils.lookup_icon(hints.app_icon:lower())
|
||||
|
||||
if path then
|
||||
n.icon = path
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Naughty template
|
||||
naughty.connect_signal("request::display", function(n)
|
||||
|
||||
-- naughty.actions template
|
||||
local actions_template = wibox.widget {
|
||||
notification = n,
|
||||
base_layout = wibox.widget {
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.flex.horizontal
|
||||
},
|
||||
widget_template = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'text_role',
|
||||
font = 'VictorMono Nerd Font 10',
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
widget = wibox.container.place
|
||||
},
|
||||
widget = clickable_container
|
||||
},
|
||||
bg = beautiful.groups_bg,
|
||||
shape = gears.shape.rounded_rect,
|
||||
forced_height = dpi(35),
|
||||
widget = wibox.container.background
|
||||
},
|
||||
margins = dpi(8),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
style = { underline_normal = false, underline_selected = true },
|
||||
widget = naughty.list.actions
|
||||
}
|
||||
-- Custom notification layout
|
||||
naughty.layout.box {
|
||||
notification = n,
|
||||
type = "notification",
|
||||
screen = awful.screen.preferred(),
|
||||
shape = gears.shape.rounded_rectangle,
|
||||
widget_template = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = n.app_name or 'System Notification',
|
||||
font = 'VictorMono Nerd Font 10',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
margins = beautiful.notification_margin,
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = '#000000'.. '44',
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
resize_strategy = 'center',
|
||||
widget = naughty.widget.icon,
|
||||
},
|
||||
margins = beautiful.notification_margin,
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
layout = wibox.layout.align.vertical,
|
||||
expand = 'none',
|
||||
nil,
|
||||
{
|
||||
{
|
||||
align = 'center',
|
||||
widget = naughty.widget.title
|
||||
},
|
||||
{
|
||||
align = "center",
|
||||
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.bg_normal,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
-- Notification action list
|
||||
-- naughty.list.actions,
|
||||
actions_template,
|
||||
spacing = dpi(4),
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
bg = beautiful.bg_normal,
|
||||
id = "background_role",
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = naughty.container.background,
|
||||
},
|
||||
strategy = "min",
|
||||
width = dpi(160),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
strategy = "max",
|
||||
width = beautiful.notification_max_width or dpi(500),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
-- Anti-aliasing container
|
||||
-- Real BG
|
||||
bg = beautiful.bg_normal,
|
||||
-- This will be the anti-aliased shape of the notification
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
-- Margin of the fake BG to have a space between notification and the screen edge
|
||||
-- margins = dpi(15),--beautiful.notification_margin,
|
||||
right = dpi(20),
|
||||
left = dpi(0),
|
||||
bottom = dpi(0),
|
||||
top = dpi(20),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.transparent,
|
||||
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)
|
73
awes2/module/quake-terminal.lua
Normal file
73
awes2/module/quake-terminal.lua
Normal file
|
@ -0,0 +1,73 @@
|
|||
local gears = require('gears')
|
||||
local spawn = require('awful.spawn')
|
||||
local app = require('configuration.apps').default.quake
|
||||
-- local awful = require('awful')
|
||||
|
||||
local quake_id = 'notnil'
|
||||
local quake_client
|
||||
local opened = false
|
||||
function create_shell()
|
||||
quake_id =
|
||||
spawn(
|
||||
app,
|
||||
{
|
||||
skip_decoration = true
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function open_quake()
|
||||
quake_client.hidden = false
|
||||
quake_client:emit_signal('request::activate')
|
||||
end
|
||||
|
||||
function close_quake()
|
||||
quake_client.hidden = true
|
||||
end
|
||||
|
||||
toggle_quake = function()
|
||||
opened = not opened
|
||||
if not quake_client then
|
||||
create_shell()
|
||||
else
|
||||
if opened then
|
||||
open_quake()
|
||||
else
|
||||
close_quake()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
client.connect_signal(
|
||||
'manage',
|
||||
function(c)
|
||||
if c.pid == quake_id then
|
||||
quake_client = c
|
||||
c.opacity = 0.95
|
||||
c.floating = true
|
||||
c.skip_taskbar = true
|
||||
c.ontop = true
|
||||
c.above = true
|
||||
c.sticky = true
|
||||
c.hidden = not opened
|
||||
c.maximized_horizontal = true
|
||||
c.hide_titlebars = true
|
||||
c.skip_center = true
|
||||
c.round_corners = false
|
||||
c.shape = function(cr, w, h)
|
||||
gears.shape.rectangle(cr, w, h)
|
||||
end
|
||||
-- awful.placement.top(c)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
client.connect_signal(
|
||||
'unmanage',
|
||||
function(c)
|
||||
if c.pid == quake_id then
|
||||
opened = false
|
||||
quake_client = nil
|
||||
end
|
||||
end
|
||||
)
|
30
awes2/module/test.lua
Normal file
30
awes2/module/test.lua
Normal file
|
@ -0,0 +1,30 @@
|
|||
-- Load these libraries (if you haven't already)
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
|
||||
-- Create the box
|
||||
local anti_aliased_wibox = wibox({visible = true, ontop = true, type = "normal", height = 100, width = 100})
|
||||
|
||||
-- Place it at the center of the screen
|
||||
awful.placement.centered(anti_aliased_wibox)
|
||||
|
||||
-- Set transparent bg
|
||||
anti_aliased_wibox.bg = beautiful.transparent
|
||||
|
||||
-- Put its items in a shaped container
|
||||
anti_aliased_wibox:setup {
|
||||
-- Container
|
||||
{
|
||||
-- Items go here
|
||||
--wibox.widget.textbox("Hello!"),
|
||||
awful.spawn('urxvt'),
|
||||
-- ...
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
-- The real background color
|
||||
bg = "#111111",
|
||||
-- The real, anti-aliased shape
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = wibox.container.background()
|
||||
}
|
282
awes2/module/titlebar.lua
Normal file
282
awes2/module/titlebar.lua
Normal file
|
@ -0,0 +1,282 @@
|
|||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
awful.titlebar.enable_tooltip = false
|
||||
awful.titlebar.fallback_name = 'Client\'s name'
|
||||
|
||||
|
||||
local titlebar_size = beautiful.titlebar_size
|
||||
|
||||
|
||||
-- ▄▄▄▄▄▄▄ ▀ ▄ ▀▀█ █
|
||||
-- █ ▄▄▄ ▄▄█▄▄ █ ▄▄▄ █▄▄▄ ▄▄▄ ▄ ▄▄
|
||||
-- █ █ █ █ █▀ █ █▀ ▀█ ▀ █ █▀ ▀
|
||||
-- █ █ █ █ █▀▀▀▀ █ █ ▄▀▀▀█ █
|
||||
-- █ ▄▄█▄▄ ▀▄▄ ▀▄▄ ▀█▄▄▀ ██▄█▀ ▀▄▄▀█ █
|
||||
|
||||
|
||||
|
||||
function double_click_event_handler(double_click_event)
|
||||
if double_click_timer then
|
||||
double_click_timer:stop()
|
||||
double_click_timer = nil
|
||||
|
||||
double_click_event()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
double_click_timer = gears.timer.start_new(0.20, function()
|
||||
double_click_timer = nil
|
||||
return false
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
|
||||
client.connect_signal("request::titlebars", function(c)
|
||||
|
||||
-- Buttons for moving/resizing functionality
|
||||
local buttons = gears.table.join(
|
||||
awful.button(
|
||||
{},
|
||||
1,
|
||||
function()
|
||||
double_click_event_handler(function()
|
||||
if c.floating then
|
||||
c.floating = false
|
||||
return
|
||||
end
|
||||
|
||||
c.maximized = not c.maximized
|
||||
c:raise()
|
||||
return
|
||||
end)
|
||||
|
||||
c:activate {context = "titlebar", action = "mouse_move"}
|
||||
end
|
||||
),
|
||||
awful.button(
|
||||
{},
|
||||
3,
|
||||
function()
|
||||
c:activate {context = "titlebar", action = "mouse_resize"}
|
||||
end
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
local decorate_titlebar = function(c, pos, bg, size)
|
||||
|
||||
c.titlebar_position = pos
|
||||
|
||||
if pos == 'left' or pos == 'right' then
|
||||
|
||||
-- Creates left or right titlebars
|
||||
awful.titlebar(c, {position = pos, bg = bg, size = size or titlebar_size}) : setup {
|
||||
{
|
||||
{
|
||||
awful.titlebar.widget.closebutton(c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.minimizebutton (c),
|
||||
spacing = dpi(7),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
{
|
||||
awful.titlebar.widget.floatingbutton (c),
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.align.vertical
|
||||
|
||||
}
|
||||
|
||||
elseif pos == 'top' or pos == 'bottom' then
|
||||
|
||||
-- Creates top or bottom titlebars
|
||||
awful.titlebar(c, {position = pos, bg = bg, size = size or titlebar_size}) : setup {
|
||||
{
|
||||
{
|
||||
awful.titlebar.widget.closebutton(c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.minimizebutton (c),
|
||||
spacing = dpi(7),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.flex.horizontal
|
||||
},
|
||||
{
|
||||
awful.titlebar.widget.floatingbutton (c),
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
-- Create a left titlebar (default in this setup)
|
||||
awful.titlebar(c, {position = 'left', size = titlebar_size}) : setup {
|
||||
{
|
||||
{
|
||||
awful.titlebar.widget.closebutton(c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.minimizebutton (c),
|
||||
spacing = dpi(7),
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.flex.vertical
|
||||
},
|
||||
{
|
||||
awful.titlebar.widget.floatingbutton (c),
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- ▄▄▄ ▄ ▀
|
||||
-- ▄▀ ▀ ▄ ▄ ▄▄▄ ▄▄█▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄
|
||||
-- █ █ █ █ ▀ █ █▀ ▀█ █ █ █ █ ▄▀ █▀ █
|
||||
-- █ █ █ ▀▀▀▄ █ █ █ █ █ █ █ ▄▀ █▀▀▀▀
|
||||
-- ▀▄▄▄▀ ▀▄▄▀█ ▀▄▄▄▀ ▀▄▄ ▀█▄█▀ █ █ █ ▄▄█▄▄ █▄▄▄▄ ▀█▄▄▀
|
||||
|
||||
-- Generate a custom titlabar for each class, roles, type, etc., etc.
|
||||
-- The titlebar's position can now be set differently
|
||||
|
||||
if c.class == 'dolphin' or c.class == 'firefox' or c.class == 'pavucontrol-qt' or
|
||||
c.instance == 'transmission-qt' or c.class == 'ark' or c.class == 'polkit-kde-authentication-agent-1' or
|
||||
c.class == 'partitionmanager' or c.class == 'discord' or c.class == 'kdesu' then
|
||||
|
||||
if c.type == 'dialog' or c.type == 'modal' then
|
||||
decorate_titlebar(c, 'top', beautiful.background, titlebar_size)
|
||||
else
|
||||
decorate_titlebar(c, 'left', beautiful.background, titlebar_size)
|
||||
end
|
||||
|
||||
elseif c.role == "GtkFileChooserDialog" or c.type == 'dialog' or c.type == 'modal' then
|
||||
|
||||
-- Let's use the gtk theme's bg_color as titlebar's bg then add some transparency
|
||||
-- Let's set the titlebar's position to top
|
||||
-- Isn't it neat? lol
|
||||
decorate_titlebar(c, 'top', beautiful.gtk.get_theme_variables().bg_color:sub(1,7) .. '66', titlebar_size)
|
||||
|
||||
elseif c.class == "kitty" then
|
||||
|
||||
decorate_titlebar(c, 'left', '#000000AA', titlebar_size)
|
||||
|
||||
elseif c.class == 'XTerm' or c.class == 'UXTerm' then
|
||||
|
||||
-- Let's use the xresources' background color as the titlebar color for xterm
|
||||
-- awesome is the shit boi!
|
||||
decorate_titlebar(c, 'top', beautiful.xresources.get_current_theme().background, titlebar_size)
|
||||
|
||||
elseif c.class == 'Nemo' then
|
||||
|
||||
decorate_titlebar(c, 'left', beautiful.xresources.get_current_theme().background, titlebar_size)
|
||||
|
||||
else
|
||||
|
||||
-- Default titlebar
|
||||
decorate_titlebar(c, 'left', beautiful.background, titlebar_size)
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
|
||||
-- ▄▄▄▄ ▀ ▀▀█
|
||||
-- █▀ ▀ ▄▄▄ ▄▄▄▄ ▄ ▄▄ ▄▄▄ █ ▄▄▄
|
||||
-- ▀█▄▄▄ █ █▀ ▀█ █▀ █ ▀ █ █ █ ▀
|
||||
-- ▀█ █ █ █ █ █ ▄▀▀▀█ █ ▀▀▀▄
|
||||
-- ▀▄▄▄█▀ ▄▄█▄▄ ▀█▄▀█ █ █ ▀▄▄▀█ ▀▄▄ ▀▄▄▄▀
|
||||
-- ▄ █
|
||||
-- ▀▀
|
||||
|
||||
|
||||
client.connect_signal(
|
||||
"manage",
|
||||
function(c)
|
||||
|
||||
if not c.max and not c.hide_titlebars then
|
||||
awful.titlebar.show(c, c.titlebar_position or 'left')
|
||||
else
|
||||
awful.titlebar.hide(c, c.titlebar_position or 'left')
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
-- Catch the signal when a client's layout is changed
|
||||
screen.connect_signal(
|
||||
"arrange",
|
||||
function(s)
|
||||
for _, c in pairs(s.clients) do
|
||||
|
||||
if (#s.tiled_clients > 1 or c.floating) and c.first_tag.layout.name ~= 'max' then
|
||||
|
||||
if not c.hide_titlebars then
|
||||
awful.titlebar.show(c, c.titlebar_position or 'left')
|
||||
else
|
||||
awful.titlebar.hide(c, c.titlebar_position or 'left')
|
||||
end
|
||||
|
||||
if c.maximized or not c.round_corners or c.fullscreen then
|
||||
c.shape = function(cr, w, h)
|
||||
gears.shape.rectangle(cr, w, h)
|
||||
end
|
||||
else
|
||||
c.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
|
||||
end
|
||||
end
|
||||
|
||||
elseif (#s.tiled_clients == 1 or c.first_tag.layout.name == 'max') and not c.fullscreen then
|
||||
|
||||
awful.titlebar.hide(c, c.titlebar_position or 'left')
|
||||
|
||||
c.shape = function(cr, w, h)
|
||||
gears.shape.rectangle(cr, w, h)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
client.connect_signal("property::maximized", function(c)
|
||||
c.shape = gears.shape.rectangle
|
||||
|
||||
if not c.maximized then
|
||||
c.shape = function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, beautiful.client_radius)
|
||||
end
|
||||
end
|
||||
end)
|
271
awes2/module/volume-osd.lua
Normal file
271
awes2/module/volume-osd.lua
Normal file
|
@ -0,0 +1,271 @@
|
|||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local beautiful = require('beautiful')
|
||||
|
||||
local dpi = require('beautiful').xresources.apply_dpi
|
||||
|
||||
local clickable_container = require('widget.clickable-container')
|
||||
local icons = require('theme.icons')
|
||||
local spawn = require('awful.spawn')
|
||||
|
||||
screen.connect_signal("request::desktop_decoration", function(s)
|
||||
|
||||
s.show_vol_osd = true
|
||||
|
||||
local osd_header = wibox.widget {
|
||||
text = 'Volume',
|
||||
font = 'VictorMono Nerd Font 12',
|
||||
align = 'left',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local osd_value = wibox.widget {
|
||||
text = '0%',
|
||||
font = 'VictorMono Nerd Font 11',
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local slider_osd = wibox.widget {
|
||||
nil,
|
||||
{
|
||||
id = 'vol_osd_slider',
|
||||
bar_shape = gears.shape.rounded_rect,
|
||||
bar_height = dpi(2),
|
||||
bar_color = '#ffffff20',
|
||||
bar_active_color = '#f2f2f2EE',
|
||||
handle_color = '#ffffff',
|
||||
handle_shape = gears.shape.circle,
|
||||
handle_width = dpi(15),
|
||||
handle_border_color = '#00000012',
|
||||
handle_border_width = dpi(1),
|
||||
maximum = 100,
|
||||
widget = wibox.widget.slider,
|
||||
},
|
||||
nil,
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.vertical
|
||||
}
|
||||
|
||||
local vol_osd_slider = slider_osd.vol_osd_slider
|
||||
|
||||
-- Update volume level using slider value
|
||||
vol_osd_slider:connect_signal(
|
||||
'property::value',
|
||||
function()
|
||||
|
||||
local volume_level = vol_osd_slider:get_value()
|
||||
|
||||
spawn('amixer set Master ' .. volume_level .. '%', false)
|
||||
|
||||
-- Update textbox widget text
|
||||
osd_value.text = volume_level .. '%'
|
||||
|
||||
-- Update the volume slider if values here change
|
||||
awesome.emit_signal('widget::volume:update', volume_level)
|
||||
|
||||
if s.show_vol_osd then
|
||||
awesome.emit_signal(
|
||||
'module::volume_osd:show',
|
||||
true
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
vol_osd_slider:connect_signal(
|
||||
'button::press',
|
||||
function()
|
||||
s.show_vol_osd = true
|
||||
end
|
||||
)
|
||||
vol_osd_slider:connect_signal(
|
||||
'button::release',
|
||||
function()
|
||||
s.show_vol_osd = false
|
||||
end
|
||||
)
|
||||
vol_osd_slider:connect_signal(
|
||||
'mouse::enter',
|
||||
function()
|
||||
s.show_vol_osd = true
|
||||
end
|
||||
)
|
||||
|
||||
-- The emit will come from the volume-slider
|
||||
awesome.connect_signal(
|
||||
'module::volume_osd',
|
||||
function(volume)
|
||||
vol_osd_slider:set_value(volume)
|
||||
end
|
||||
)
|
||||
|
||||
local icon = wibox.widget {
|
||||
{
|
||||
image = icons.volume,
|
||||
resize = true,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
top = dpi(12),
|
||||
bottom = dpi(12),
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local volume_slider_osd = wibox.widget {
|
||||
icon,
|
||||
slider_osd,
|
||||
spacing = dpi(24),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
}
|
||||
|
||||
-- Create the box
|
||||
local osd_height = dpi(100)
|
||||
local osd_width = dpi(300)
|
||||
|
||||
local osd_margin = dpi(10)
|
||||
|
||||
s.volume_osd_overlay = awful.popup {
|
||||
widget = {
|
||||
-- Removing this block will cause an error...
|
||||
},
|
||||
ontop = true,
|
||||
visible = false,
|
||||
type = 'notification',
|
||||
screen = s,
|
||||
height = osd_height,
|
||||
width = osd_width,
|
||||
maximum_height = osd_height,
|
||||
maximum_width = osd_width,
|
||||
offset = dpi(5),
|
||||
shape = gears.shape.rounded_rect,
|
||||
bg = "#282a36",
|
||||
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
|
||||
|
||||
},
|
||||
shape = gears.shape.rounded_rect,
|
||||
widget = wibox.container.background()
|
||||
}
|
||||
|
||||
|
||||
local hide_osd = gears.timer {
|
||||
timeout = 2,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
awful.screen.focused().volume_osd_overlay.visible = false
|
||||
end
|
||||
}
|
||||
|
||||
local timer_rerun = function()
|
||||
if hide_osd.started then
|
||||
hide_osd:again()
|
||||
else
|
||||
hide_osd:start()
|
||||
end
|
||||
end
|
||||
|
||||
-- Reset timer on mouse hover
|
||||
s.volume_osd_overlay:connect_signal(
|
||||
'mouse::enter',
|
||||
function()
|
||||
s.show_vol_osd = true
|
||||
timer_rerun()
|
||||
end
|
||||
)
|
||||
s.volume_osd_overlay:connect_signal(
|
||||
'mouse::leave',
|
||||
function()
|
||||
s.show_vol_osd = false
|
||||
end
|
||||
)
|
||||
|
||||
local placement_placer = function()
|
||||
|
||||
local focused = awful.screen.focused()
|
||||
|
||||
local right_panel = focused.right_panel
|
||||
local left_panel = focused.left_panel
|
||||
local volume_osd = focused.volume_osd_overlay
|
||||
|
||||
if right_panel and left_panel then
|
||||
if right_panel.visible then
|
||||
awful.placement.bottom_left(focused.volume_osd_overlay, { margins = {
|
||||
left = osd_margin + left_panel.width,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if right_panel then
|
||||
if right_panel.visible then
|
||||
awful.placement.bottom_left(focused.volume_osd_overlay, { margins = {
|
||||
left = osd_margin,
|
||||
right = 0,
|
||||
top = 0,
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
awful.placement.centered(focused.volume_osd_overlay, { margins = {
|
||||
left = 0,
|
||||
right = osd_margin,
|
||||
top = dpi(800),
|
||||
bottom = osd_margin,
|
||||
},
|
||||
parent = focused }
|
||||
)
|
||||
end
|
||||
|
||||
awesome.connect_signal(
|
||||
'module::volume_osd:show',
|
||||
function(bool)
|
||||
placement_placer()
|
||||
awful.screen.focused().volume_osd_overlay.visible = bool
|
||||
if bool then
|
||||
timer_rerun()
|
||||
awesome.emit_signal(
|
||||
'module::brightness_osd:show',
|
||||
false
|
||||
)
|
||||
else
|
||||
if hide_osd.started then
|
||||
hide_osd:stop()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue