feat: Migrate to Chezmoi

This commit is contained in:
punkfairie 2024-04-14 18:41:15 -07:00
commit 18373323b0
No known key found for this signature in database
GPG key ID: 284B78B49C058673
289 changed files with 17267 additions and 0 deletions

View file

@ -0,0 +1,19 @@
[".config/awesome/lib/bling"]
type = "git-repo"
url = "https://github.com/BlingCorp/bling.git"
refreshPeriod = "672h"
[".config/awesome/lib/catppuccin"]
type = "git-repo"
url = "https://github.com/catppuccin/lua.git"
refreshPeriod = "672h"
[".config/awesome/lib/layout-machi"]
type = "git-repo"
url = "https://github.com/xinhaoyuan/layout-machi.git"
refreshPeriod = "672h"
[".config/awesome/lib/rubato"]
type = "git-repo"
url = "https://github.com/andOrlando/rubato.git"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".config/bat/themes/Catppuccin-latte.tmTheme"]
type = "file"
url = "https://github.com/catppuccin/bat/raw/main/themes/Catppuccin%20Latte.tmTheme"
refreshPeriod = "672h"
[".config/bat/themes/Catppuccin-frappe.tmTheme"]
type = "file"
url = "https://github.com/catppuccin/bat/raw/main/themes/Catppuccin%20Frappe.tmTheme"
refreshPeriod = "672h"
[".config/bat/themes/Catppuccin-macchiato.tmTheme"]
type = "file"
url = "https://github.com/catppuccin/bat/raw/main/themes/Catppuccin%20Macchiato.tmTheme"
refreshPeriod = "672h"
[".config/bat/themes/Catppuccin-mocha.tmTheme"]
type = "file"
url = "https://github.com/catppuccin/bat/raw/main/themes/Catppuccin%20Mocha.tmTheme"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".config/btop/themes/catppuccin_frappe.theme"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/btop/main/themes/catppuccin_frappe.theme"
refreshPeriod = "672h"
[".config/btop/themes/catppuccin_latte.theme"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/btop/main/themes/catppuccin_latte.theme"
refreshPeriod = "672h"
[".config/btop/themes/catppuccin_macchiato.theme"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/btop/main/themes/catppuccin_macchiato.theme"
refreshPeriod = "672h"
[".config/btop/themes/catppuccin_mocha.theme"]
type = "file"
url = "https://github.com/catppuccin/btop/blob/main/themes/catppuccin_mocha.theme"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".config/glow/catppuccin/frappe.json"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/glamour/main/themes/catppuccin-frappe.json"
refreshPeriod = "672h"
[".config/glow/catppuccin/latte.json"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/glamour/main/themes/catppuccin-latte.json"
refreshPeriod = "672h"
[".config/glow/catppuccin/macchiato.json"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/glamour/main/themes/catppuccin-macchiato.json"
refreshPeriod = "672h"
[".config/glow/catppuccin/mocha.json"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/glamour/main/themes/catppuccin-mocha.json"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".config/lazygit/catppuccin/frappe.yml"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/lazygit/main/themes-mergable/frappe/pink.yml"
refreshPeriod = "672h"
[".config/lazygit/catppuccin/latte.yml"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/lazygit/main/themes-mergable/latte/pink.yml"
refreshPeriod = "672h"
[".config/lazygit/catppuccin/macchiato.yml"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/lazygit/main/themes-mergable/macchiato/pink.yml"
refreshPeriod = "672h"
[".config/lazygit/catppuccin/mocha.yml"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/lazygit/main/themes-mergable/mocha/pink.yml"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".local/share/rofi/themes/catppuccin-frappe.rasi"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/rofi/main/basic/.local/share/rofi/themes/catppuccin-frappe.rasi"
refreshPeriod = "672h"
[".local/share/rofi/themes/catppuccin-latte.rasi"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/rofi/main/basic/.local/share/rofi/themes/catppuccin-latte.rasi"
refreshPeriod = "672h"
[".local/share/rofi/themes/catppuccin-macchiato.rasi"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/rofi/main/basic/.local/share/rofi/themes/catppuccin-macchiato.rasi"
refreshPeriod = "672h"
[".local/share/rofi/themes/catppuccin-mocha.rasi"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/rofi/main/basic/.local/share/rofi/themes/catppuccin-mocha.rasi"
refreshPeriod = "672h"

View file

@ -0,0 +1,19 @@
[".config/zathura/catppuccin-frappe"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-frappe"
refreshPeriod = "672h"
[".config/zathura/catppuccin-latte"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-latte"
refreshPeriod = "672h"
[".config/zathura/catppuccin-macchiato"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-macchiato"
refreshPeriod = "672h"
[".config/zathura/catppuccin-mocha"]
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-mocha"
refreshPeriod = "672h"

38
dot_Xresources Normal file
View file

@ -0,0 +1,38 @@
*background: #24273A
*foreground: #CAD3F5
! black
*color0: #494D64
*color8: #5B6078
! red
*color1: #ED8796
*color9: #ED8796
! green
*color2: #A6DA95
*color10: #A6DA95
! yellow
*color3: #EED49F
*color11: #EED49F
! blue
*color4: #8AADF4
*color12: #8AADF4
! magenta
*color5: #F5BDE6
*color13: #F5BDE6
! cyan
*color6: #8BD5CA
*color14: #8BD5CA
! white
*color7: #B8C0E0
*color15: #A5ADCB
! Make Rofi use fish shell
rofi.run-command: fish -c '{cmd}'
rofi.run-list-command: 'fish -c functions'

3
dot_bash_logout Normal file
View file

@ -0,0 +1,3 @@
#
# ~/.bash_logout
#

5
dot_bash_profile Normal file
View file

@ -0,0 +1,5 @@
#
# ~/.bash_profile
#
[[ -f ~/.bashrc ]] && . ~/.bashrc

13
dot_bashrc Normal file
View file

@ -0,0 +1,13 @@
#
# ~/.bashrc
#
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
alias ls='ls --color=auto'
alias grep='grep --color=auto'
PS1='[\u@\h \W]\$ '
export EDITOR='nvim'
export VISUAL="$EDITOR"

View file

@ -0,0 +1,102 @@
local config_dir = require("gears.filesystem").get_configuration_dir()
local M = {}
M.keys = {
mod = "Mod4",
alt = "Mod1",
}
M.apps = {
terminal = "wezterm",
launcher = "rofi -show drun",
browser = "firefox",
file_manager = "thunar",
editor = os.getenv("EDITOR") or "nvim",
}
M.apps.start_editor = M.apps.terminal .. "-e" .. M.apps.editor
M.apps.music_player = M.apps.terminal .. "--class music -e ncmpcpp"
M.theme = {
flavor = "macchiato",
accent1 = "pink",
accent2 = "rosewater",
-- wallpaper = config_dir .. "themes/catppuccin/buttons.png",
wallpaper = "~/data/photos/wallpaper/city.png",
pfp = config_dir .. "themes/catppuccin/assets/pfp.jpg",
icon_theme = "Papirus",
font = {
family = "FairiesevkaSans Nerd Font Propo",
size = "10",
},
}
M.icons = {
menu = "󰜬",
power = "",
restart = "",
sleep = "",
exit = "󰗼",
lock = "",
music = {
next = "󰒭",
prev = "󰒮",
pause = "󰏤",
play = "󰐊",
},
tags = {
general = "",
files = "",
media = "",
terminal = "",
coding = "",
misc = "󰍹 ",
},
cal = "",
clock = "",
arr = {
r = "»",
l = "«",
},
vol = {
on = "󰕾",
off = "󰖁",
low = "󰕿",
med = "󰖀",
high = "󰕾",
},
mem = "󰍛",
cpu = "",
disk = "",
}
M.widget = {}
M.widget.clock = {
format = "%I:%M %p",
}
M.widget.date = {
format = "%a %b %d",
}
M.widget.weather = {
api_key = "e894c3e6c1a9d2217eee94791e845c96",
coordinates = { lat = "47.773140", lon = "-122.303660" },
units = "imperial",
}
M.widget.github = {
username = "punkfairie",
}
M.widget.mic = {
name = "",
}
M.widget.disk = {
name = "/dev/sdb3",
}
return M

View file

@ -0,0 +1,3 @@
return {
ui = require("helpers.ui"),
}

View file

@ -0,0 +1,188 @@
local awful = require("awful")
local wibox = require("wibox")
local gshape = require("gears.shape")
local gmatrix = require("gears.matrix")
local beautiful = require("beautiful")
local capi = { mouse = mouse }
local theme = beautiful.get()
local ui = {}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
---Set text color
---@param text string
---@param color string
---@return string
function ui.colorize_text(text, color)
return "<span foreground='" .. color .. "'>" .. text .. "</span>"
end
---Change a font attribute
---@param attr string attribute(s) to add, e.g. "Bold 16"
---@param font? string base font to use, for use in the theme file itself
---@return string
function ui.set_font(attr, font)
font = font or theme.font
return beautiful.get_merged_font(font, attr):to_string()
end
---Create an icon widget
---@param i string the icon
---@param c string the icon's color
---@return table widget the widget
function ui.create_icon(i, c)
local widget = {
{
font = ui.set_font("12.5"),
text = " " .. i,
widget = wibox.widget.textbox,
},
fg = c,
widget = wibox.container.background,
}
return widget
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
---Change cursor on hovering
---@param w any widget to change cursor on
---@param hover_cursor string cursor to change to
function ui.add_hover_cursor(w, hover_cursor)
local original_cursor = "left_ptr"
w:connect_signal("mouse::enter", function()
local widget = capi.mouse.current_wibox
if widget then
widget.cursor = hover_cursor
end
end)
w:connect_signal("mouse::leave", function()
local widget = capi.mouse.current_wibox
if widget then
widget.cursor = original_cursor
end
end)
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.vertical_pad(height)
return wibox.widget({
forced_height = height,
layout = wibox.layout.fixed.vertical,
})
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.horizontal_pad(width)
return wibox.widget({
forced_width = width,
layout = wibox.layout.fixed.horizontal,
})
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.rrect(radius)
return function(cr, width, height)
gshape.rounded_rect(cr, width, height, radius)
end
end
function ui.pie(width, height, start_angle, end_angle, radius)
return function(cr)
gshape.pie(cr, width, height, start_angle, end_angle, radius)
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.prgram(height, base)
return function(cr, width)
gshape.parallelogram(cr, width, height, base)
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.prrect(radius, tl, tr, br, bl)
return function(cr, width, height)
gshape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius)
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.custom_shape(cr, width, height)
cr:move_to(0, height / 25)
cr:line_to(height / 25, 0)
cr:line_to(width, 0)
cr:line_to(width, height - height / 25)
cr:line_to(width - height / 25, height)
cr:line_to(0, height)
cr:close_path()
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
local function _get_widget_geometry(_hierarchy, widget)
local width, height = _hierarchy:get_size()
if _hierarchy:get_widget() == widget then
-- Get the extents of this widget in the device space
local x, y, w, h = gmatrix.transform_rectangle(_hierarchy:get_matrix_to_device(), 0, 0, width, height)
return { x = x, y = y, width = w, height = h, hierarchy = _hierarchy }
end
for _, child in ipairs(_hierarchy:get_children()) do
local ret = _get_widget_geometry(child, widget)
if ret then
return ret
end
end
end
function ui.get_widget_geometry(_wibox, widget)
return _get_widget_geometry(_wibox._drawable._widget_hierarchy, widget)
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.screen_mask(s, bg)
local mask = wibox({
visible = false,
ontop = true,
type = "splash",
screen = s,
})
awful.placement.maximize(mask)
mask.bg = bg
return mask
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function ui.grouping_widget(w1, w2, dpi1)
local container = wibox.widget({
w1,
{
nil,
w2,
expand = "none",
layout = wibox.layout.flex.vertical,
},
spacing = dpi1,
layout = wibox.layout.fixed.horizontal,
})
return container
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
return ui

View file

@ -0,0 +1,225 @@
-------------------------------------------
-- @author https://github.com/Kasper24
-- @copyright 2021-2022 Kasper24
-------------------------------------------
local GLib = require("lgi").GLib
local gobject = require("gears.object")
local gtable = require("gears.table")
local subscribable = require("lib.animation.subscribable")
local tween = require("lib.animation.tween")
local ipairs = ipairs
local table = table
local pairs = pairs
local animation_manager = {}
animation_manager.easing = {
linear = "linear",
inQuad = "inQuad",
outQuad = "outQuad",
inOutQuad = "inOutQuad",
outInQuad = "outInQuad",
inCubic = "inCubic",
outCubic = "outCubic",
inOutCubic = "inOutCubic",
outInCubic = "outInCubic",
inQuart = "inQuart",
outQuart = "outQuart",
inOutQuart = "inOutQuart",
outInQuart = "outInQuart",
inQuint = "inQuint",
outQuint = "outQuint",
inOutQuint = "inOutQuint",
outInQuint = "outInQuint",
inSine = "inSine",
outSine = "outSine",
inOutSine = "inOutSine",
outInSine = "outInSine",
inExpo = "inExpo",
outExpo = "outExpo",
inOutExpo = "inOutExpo",
outInExpo = "outInExpo",
inCirc = "inCirc",
outCirc = "outCirc",
inOutCirc = "inOutCirc",
outInCirc = "outInCirc",
inElastic = "inElastic",
outElastic = "outElastic",
inOutElastic = "inOutElastic",
outInElastic = "outInElastic",
inBack = "inBack",
outBack = "outBack",
inOutBack = "inOutBack",
outInBack = "outInBack",
inBounce = "inBounce",
outBounce = "outBounce",
inOutBounce = "inOutBounce",
outInBounce = "outInBounce",
}
local animation = {}
local instance = nil
local ANIMATION_FRAME_DELAY = 5
local function second_to_micro(sec)
return sec * 1000000
end
function animation:start(args)
args = args or {}
-- Awestoer/Rubbto compatibility
-- I'd rather this always be a table, but Awestoer/Rubbto
-- except the :set() method to have 1 number value parameter
-- used to set the target
local is_table = type(args) == "table"
local initial = is_table and (args.pos or self.pos) or self.pos
local subject = is_table and (args.subject or self.subject) or self.subject
local target = is_table and (args.target or self.target) or args
local duration = is_table and (args.duration or self.duration) or self.duration
local easing = is_table and (args.easing or self.easing) or self.easing
duration = self._private.anim_manager._private.instant == true and 0.01 or duration
if self.tween == nil or self.reset_on_stop == true then
self.tween = tween.new({
initial = initial,
subject = subject,
target = target,
duration = second_to_micro(duration),
easing = easing,
})
end
if self._private.anim_manager._private.animations[self.index] == nil then
table.insert(self._private.anim_manager._private.animations, self)
end
self.state = true
self.last_elapsed = GLib.get_monotonic_time()
self.started:fire()
self:emit_signal("started")
end
function animation:set(args)
self:start(args)
self:emit_signal("set")
end
function animation:stop()
self.state = false
self:emit_signal("stopped")
end
function animation:abort()
animation:stop()
self:emit_signal("aborted")
end
function animation:initial()
return self._private.initial
end
function animation_manager:set_instant(value)
self._private.instant = value
end
function animation_manager:new(args)
args = args or {}
args.pos = args.pos or 0
args.subject = args.subject or nil
args.target = args.target or nil
args.duration = args.duration or 0
args.easing = args.easing or nil
args.loop = args.loop or false
args.signals = args.signals or {}
args.update = args.update or nil
args.reset_on_stop = args.reset_on_stop == nil and true or args.reset_on_stop
-- Awestoer/Rubbto compatibility
args.subscribed = args.subscribed or nil
local ret = subscribable()
ret.started = subscribable()
ret.ended = subscribable()
if args.subscribed ~= nil then
ret:subscribe(args.subscribed)
end
for sig, sigfun in pairs(args.signals) do
ret:connect_signal(sig, sigfun)
end
if args.update ~= nil then
ret:connect_signal("update", args.update)
end
gtable.crush(ret, args, true)
gtable.crush(ret, animation, true)
ret._private = {}
ret._private.anim_manager = self
ret._private.initial = args.pos
return ret
end
local function new()
local ret = gobject({})
gtable.crush(ret, animation_manager, true)
ret._private = {}
ret._private.animations = {}
ret._private.instant = false
GLib.timeout_add(GLib.PRIORITY_DEFAULT, ANIMATION_FRAME_DELAY, function()
---@diagnostic disable-next-line: redefined-local
for index, animation in ipairs(ret._private.animations) do
if animation.state == true then
-- compute delta time
local time = GLib.get_monotonic_time()
local delta = time - animation.last_elapsed
animation.last_elapsed = time
-- If pos is true, the animation has ended
local pos = animation.tween:update(delta)
if pos == true then
-- Loop the animation, don't end it.
-- Useful for widgets like the spinning cicle
if animation.loop == true then
animation.tween:reset()
else
-- Snap to end
animation.pos = animation.tween.target
animation:fire(animation.pos)
animation:emit_signal("update", animation.pos)
animation.state = false
animation.ended:fire(pos)
table.remove(ret._private.animations, index)
animation:emit_signal("ended", animation.pos)
end
-- Animation in process, keep updating
else
animation.pos = pos
animation:fire(animation.pos)
animation:emit_signal("update", animation.pos)
end
else
table.remove(ret._private.animations, index)
end
end
-- call again the function after cooldown
return true
end)
return ret
end
if not instance then
instance = new()
end
return instance

View file

@ -0,0 +1,47 @@
-------------------------------------------
-- @author https://github.com/Kasper24
-- @copyright 2021-2022 Kasper24
-------------------------------------------
local gobject = require("gears.object")
-- Kidna copying awesotre's stores on a surface level for added compatibility
local function subscribable()
local ret = gobject({})
local subscribed = {}
-- Subscrubes a function to the object so that it's called when `fire` is
-- Calls subscribe_callback if it exists as well
function ret:subscribe(func)
local id = tostring(func):gsub("function: ", "")
subscribed[id] = func
if self.subscribe_callback then
self.subscribe_callback(func)
end
end
-- Unsubscribes a function and calls unsubscribe_callback if it exists
function ret:unsubscribe(func)
if not func then
subscribed = {}
else
local id = tostring(func):gsub("function: ", "")
subscribed[id] = nil
end
if self.unsubscribe_callback then
self.unsubscribe_callback(func)
end
end
function ret:fire(...)
for _, func in pairs(subscribed) do
func(...)
end
end
return ret
end
return subscribable

View file

@ -0,0 +1,533 @@
-------------------------------------------
-- @author https://github.com/Kasper24
-- @copyright 2021-2022 Kasper24
-------------------------------------------
-- easing
-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.
-- For all easing functions:
-- t = time == how much time has to pass for the tweening to complete
-- b = begin == starting property value
-- c = change == ending - beginning
-- d = duration == running time. How much time has passed *right now*
local gobject = require("gears.object")
local gtable = require("gears.table")
local tween = {
_VERSION = "tween 2.1.1",
_DESCRIPTION = "tweening for lua",
_URL = "https://github.com/kikito/tween.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga
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 SOFTWARE.
]],
}
local sin, cos, pi, sqrt, abs, asin = math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin
-- linear
local function linear(t, b, c, d)
return c * t / d + b
end
-- quad
local function inQuad(t, b, c, d)
return c * ((t / d) ^ 2) + b
end
local function outQuad(t, b, c, d)
t = t / d
return -c * t * (t - 2) + b
end
local function inOutQuad(t, b, c, d)
t = t / d * 2
if t < 1 then
return c / 2 * (t ^ 2) + b
end
return -c / 2 * ((t - 1) * (t - 3) - 1) + b
end
local function outInQuad(t, b, c, d)
if t < d / 2 then
return outQuad(t * 2, b, c / 2, d)
end
return inQuad((t * 2) - d, b + c / 2, c / 2, d)
end
-- cubic
local function inCubic(t, b, c, d)
return c * ((t / d) ^ 3) + b
end
local function outCubic(t, b, c, d)
return c * (((t / d - 1) ^ 3) + 1) + b
end
local function inOutCubic(t, b, c, d)
t = t / d * 2
if t < 1 then
return c / 2 * t * t * t + b
end
t = t - 2
return c / 2 * (t * t * t + 2) + b
end
local function outInCubic(t, b, c, d)
if t < d / 2 then
return outCubic(t * 2, b, c / 2, d)
end
return inCubic((t * 2) - d, b + c / 2, c / 2, d)
end
-- quart
local function inQuart(t, b, c, d)
return c * ((t / d) ^ 4) + b
end
local function outQuart(t, b, c, d)
return -c * (((t / d - 1) ^ 4) - 1) + b
end
local function inOutQuart(t, b, c, d)
t = t / d * 2
if t < 1 then
return c / 2 * (t ^ 4) + b
end
return -c / 2 * (((t - 2) ^ 4) - 2) + b
end
local function outInQuart(t, b, c, d)
if t < d / 2 then
return outQuart(t * 2, b, c / 2, d)
end
return inQuart((t * 2) - d, b + c / 2, c / 2, d)
end
-- quint
local function inQuint(t, b, c, d)
return c * ((t / d) ^ 5) + b
end
local function outQuint(t, b, c, d)
return c * (((t / d - 1) ^ 5) + 1) + b
end
local function inOutQuint(t, b, c, d)
t = t / d * 2
if t < 1 then
return c / 2 * (t ^ 5) + b
end
return c / 2 * (((t - 2) ^ 5) + 2) + b
end
local function outInQuint(t, b, c, d)
if t < d / 2 then
return outQuint(t * 2, b, c / 2, d)
end
return inQuint((t * 2) - d, b + c / 2, c / 2, d)
end
-- sine
local function inSine(t, b, c, d)
return -c * cos(t / d * (pi / 2)) + c + b
end
local function outSine(t, b, c, d)
return c * sin(t / d * (pi / 2)) + b
end
local function inOutSine(t, b, c, d)
return -c / 2 * (cos(pi * t / d) - 1) + b
end
local function outInSine(t, b, c, d)
if t < d / 2 then
return outSine(t * 2, b, c / 2, d)
end
return inSine((t * 2) - d, b + c / 2, c / 2, d)
end
-- expo
local function inExpo(t, b, c, d)
if t == 0 then
return b
end
return c * (2 ^ (10 * (t / d - 1))) + b - c * 0.001
end
local function outExpo(t, b, c, d)
if t == d then
return b + c
end
return c * 1.001 * (-(2 ^ (-10 * t / d)) + 1) + b
end
local function inOutExpo(t, b, c, d)
if t == 0 then
return b
end
if t == d then
return b + c
end
t = t / d * 2
if t < 1 then
return c / 2 * (2 ^ (10 * (t - 1))) + b - c * 0.0005
end
return c / 2 * 1.0005 * (-(2 ^ (-10 * (t - 1))) + 2) + b
end
local function outInExpo(t, b, c, d)
if t < d / 2 then
return outExpo(t * 2, b, c / 2, d)
end
return inExpo((t * 2) - d, b + c / 2, c / 2, d)
end
-- circ
local function inCirc(t, b, c, d)
return (-c * (sqrt(1 - ((t / d) ^ 2)) - 1) + b)
end
local function outCirc(t, b, c, d)
return (c * sqrt(1 - ((t / d - 1) ^ 2)) + b)
end
local function inOutCirc(t, b, c, d)
t = t / d * 2
if t < 1 then
return -c / 2 * (sqrt(1 - t * t) - 1) + b
end
t = t - 2
return c / 2 * (sqrt(1 - t * t) + 1) + b
end
local function outInCirc(t, b, c, d)
if t < d / 2 then
return outCirc(t * 2, b, c / 2, d)
end
return inCirc((t * 2) - d, b + c / 2, c / 2, d)
end
-- elastic
local function calculatePAS(p, a, c, d)
p, a = p or d * 0.3, a or 0
if a < abs(c) then
return p, c, p / 4
end -- p, a, s
return p, a, p / (2 * pi) * asin(c / a) -- p,a,s
end
local function inElastic(t, b, c, d, a, p)
local s
if t == 0 then
return b
end
t = t / d
if t == 1 then
return b + c
end
p, a, s = calculatePAS(p, a, c, d)
t = t - 1
return -(a * (2 ^ (10 * t)) * sin((t * d - s) * (2 * pi) / p)) + b
end
local function outElastic(t, b, c, d, a, p)
local s
if t == 0 then
return b
end
t = t / d
if t == 1 then
return b + c
end
p, a, s = calculatePAS(p, a, c, d)
return a * (2 ^ (-10 * t)) * sin((t * d - s) * (2 * pi) / p) + c + b
end
local function inOutElastic(t, b, c, d, a, p)
local s
if t == 0 then
return b
end
t = t / d * 2
if t == 2 then
return b + c
end
p, a, s = calculatePAS(p, a, c, d)
t = t - 1
if t < 0 then
return -0.5 * (a * (2 ^ (10 * t)) * sin((t * d - s) * (2 * pi) / p)) + b
end
return a * (2 ^ (-10 * t)) * sin((t * d - s) * (2 * pi) / p) * 0.5 + c + b
end
local function outInElastic(t, b, c, d, a, p)
if t < d / 2 then
return outElastic(t * 2, b, c / 2, d, a, p)
end
return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
end
-- back
local function inBack(t, b, c, d, s)
s = s or 1.70158
t = t / d
return c * t * t * ((s + 1) * t - s) + b
end
local function outBack(t, b, c, d, s)
s = s or 1.70158
t = t / d - 1
return c * (t * t * ((s + 1) * t + s) + 1) + b
end
local function inOutBack(t, b, c, d, s)
s = (s or 1.70158) * 1.525
t = t / d * 2
if t < 1 then
return c / 2 * (t * t * ((s + 1) * t - s)) + b
end
t = t - 2
return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
end
local function outInBack(t, b, c, d, s)
if t < d / 2 then
return outBack(t * 2, b, c / 2, d, s)
end
return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
end
-- bounce
local function outBounce(t, b, c, d)
t = t / d
if t < 1 / 2.75 then
return c * (7.5625 * t * t) + b
end
if t < 2 / 2.75 then
t = t - (1.5 / 2.75)
return c * (7.5625 * t * t + 0.75) + b
elseif t < 2.5 / 2.75 then
t = t - (2.25 / 2.75)
return c * (7.5625 * t * t + 0.9375) + b
end
t = t - (2.625 / 2.75)
return c * (7.5625 * t * t + 0.984375) + b
end
local function inBounce(t, b, c, d)
return c - outBounce(d - t, 0, c, d) + b
end
local function inOutBounce(t, b, c, d)
if t < d / 2 then
return inBounce(t * 2, 0, c, d) * 0.5 + b
end
return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b
end
local function outInBounce(t, b, c, d)
if t < d / 2 then
return outBounce(t * 2, b, c / 2, d)
end
return inBounce((t * 2) - d, b + c / 2, c / 2, d)
end
tween.easing = {
linear = linear,
inQuad = inQuad,
outQuad = outQuad,
inOutQuad = inOutQuad,
outInQuad = outInQuad,
inCubic = inCubic,
outCubic = outCubic,
inOutCubic = inOutCubic,
outInCubic = outInCubic,
inQuart = inQuart,
outQuart = outQuart,
inOutQuart = inOutQuart,
outInQuart = outInQuart,
inQuint = inQuint,
outQuint = outQuint,
inOutQuint = inOutQuint,
outInQuint = outInQuint,
inSine = inSine,
outSine = outSine,
inOutSine = inOutSine,
outInSine = outInSine,
inExpo = inExpo,
outExpo = outExpo,
inOutExpo = inOutExpo,
outInExpo = outInExpo,
inCirc = inCirc,
outCirc = outCirc,
inOutCirc = inOutCirc,
outInCirc = outInCirc,
inElastic = inElastic,
outElastic = outElastic,
inOutElastic = inOutElastic,
outInElastic = outInElastic,
inBack = inBack,
outBack = outBack,
inOutBack = inOutBack,
outInBack = outInBack,
inBounce = inBounce,
outBounce = outBounce,
inOutBounce = inOutBounce,
outInBounce = outInBounce,
}
-- Private interface
local function copyTables(destination, keysTable, valuesTable)
valuesTable = valuesTable or keysTable
local mt = getmetatable(keysTable)
if mt and getmetatable(destination) == nil then
setmetatable(destination, mt)
end
for k, v in pairs(keysTable) do
if type(v) == "table" then
destination[k] = copyTables({}, v, valuesTable[k])
else
destination[k] = valuesTable[k]
end
end
return destination
end
local function checkSubjectAndTargetRecursively(subject, target, path)
path = path or {}
local targetType, newPath
for k, targetValue in pairs(target) do
targetType, newPath = type(targetValue), copyTables({}, path)
table.insert(newPath, tostring(k))
if targetType == "number" then
assert(
type(subject[k]) == "number",
"Parameter '" .. table.concat(newPath, "/") .. "' is missing from subject or isn't a number"
)
elseif targetType == "table" then
checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
else
assert(
targetType == "number",
"Parameter '" .. table.concat(newPath, "/") .. "' must be a number or table of numbers"
)
end
end
end
local function checkNewParams(_, _, subject, target, easing)
-- assert(type(initial) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration))
-- assert(type(duration) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration))
assert(type(easing) == "function", "easing must be a function. Was " .. tostring(easing))
if subject and target then
local tsubject = type(subject)
assert(
tsubject == "table" or tsubject == "userdata",
"subject must be a table or userdata. Was " .. tostring(subject)
)
assert(type(target) == "table", "target must be a table. Was " .. tostring(target))
checkSubjectAndTargetRecursively(subject, target)
end
end
local function getEasingFunction(easing)
easing = easing or "linear"
if type(easing) == "string" then
local name = easing
easing = tween.easing[name]
if type(easing) ~= "function" then
error("The easing function name '" .. name .. "' is invalid")
end
end
return easing
end
local function performEasingOnSubject(subject, target, initial, clock, duration, easing)
local t, b, c, d
for k, v in pairs(target) do
if type(v) == "table" then
performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing)
else
t, b, c, d = clock, initial[k], v - initial[k], duration
subject[k] = easing(t, b, c, d)
end
end
end
local function performEasing(table, initial, target, clock, duration, easing)
if type(target) == "table" then
local t, b, c, d
for k, v in pairs(target) do
if type(v) == "table" then
table[k] = {}
performEasing(table[k], initial[k], v, clock, duration, easing)
else
t, b, c, d = clock, initial[k], v - initial[k], duration
table[k] = easing(t, b, c, d)
end
end
return table
else
local t, b, c, d = clock, initial, target - initial, duration
return easing(t, b, c, d)
end
end
-- Public interface
local Tween = {}
function Tween:set(clock)
assert(type(clock) == "number", "clock must be a positive number or 0")
if self.subject and self.initial == 0 then
self.initial = copyTables({}, self.target, self.subject)
end
self.clock = clock
if self.clock <= 0 then
self.clock = 0
if self.subject then
copyTables(self.subject, self.initial)
end
elseif self.clock >= self.duration then -- the tween has expired
self.clock = self.duration
if self.subject then
copyTables(self.subject, self.target)
end
else
if self.subject then
performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing)
else
local pos = {}
return performEasing(pos, self.initial, self.target, self.clock, self.duration, self.easing)
end
end
return self.clock >= self.duration
end
function Tween:update(dt)
assert(type(dt) == "number", "dt must be a number")
return self:set(self.clock + dt)
end
function Tween:reset()
return self:set(0)
end
function tween.new(args)
args = args or {}
args.initial = args.initial or 0
args.subject = args.subject or nil
args.target = args.target or nil
args.duration = args.duration or 0
args.easing = args.easing or nil
args.easing = getEasingFunction(args.easing)
checkNewParams(args.initial, args.duration, args.subject, args.target, args.easing)
local ret = gobject({})
ret.clock = 0
gtable.crush(ret, args, true)
gtable.crush(ret, Tween, true)
return ret
end
return tween

View file

@ -0,0 +1,138 @@
local capi = {
client = client,
mouse = mouse,
screen = screen,
mousegrabber = mousegrabber,
}
local awful = require("awful")
local function mouse_resize_handler(m, c)
awful.client.incwfact(0, c) -- needed to fix normalization at start
local start = m(capi.mouse.coords())
local x, y = start.x, start.y
local wa = m(c.screen.workarea)
local idx = awful.client.idx(c)
local c_above
local idx_above, idx_below
local wfact_above, wfact_below
local jump_to = { x = x, y = y }
local move_mwfact = false
do
local g = m(c:geometry())
local v_border = 0.2 * g.height
if idx and idx.idx > 1 and y >= g.y and y <= g.y + v_border then
-- we are near the top edge of the window
c_above = awful.client.next(-1, c)
C_BELOW = c
jump_to.y = g.y
idx_above = idx.idx - 1
idx_below = idx.idx
elseif idx and idx.idx < idx.num and y >= g.y + g.height - v_border then
-- we are near the bottom edge of the window
c_above = c
C_BELOW = awful.client.next(1, c)
idx_above = idx.idx
idx_below = idx.idx + 1
jump_to.y = g.y + g.height
end
local mw_split = wa.x + wa.width * c.screen.selected_tag.master_width_factor
if math.abs(mw_split - x) > wa.width / 6 then
move_mwfact = false
else
move_mwfact = true
jump_to.x = mw_split
end
end
if idx and idx_above then
local t = c.screen.selected_tag
local data = t.windowfact or {}
local colfact = data[idx.col] or {}
wfact_above = colfact[idx_above] or 1
wfact_below = colfact[idx_below] or 1
end
if idx_above and move_mwfact then
CURSOR = "cross"
elseif idx_above then
CURSOR = m({ y = "sb_v_double_arrow", x = "sb_h_double_arrow" }).y
elseif move_mwfact then
CURSOR = m({ y = "sb_v_double_arrow", x = "sb_h_double_arrow" }).x
else
return false
end
capi.mouse.coords(m(jump_to))
capi.mousegrabber.run(function(_mouse)
if not c.valid then
return false
end
local pressed = false
for _, v in ipairs(_mouse.buttons) do
if v then
pressed = true
break
end
end
_mouse = m(_mouse)
if pressed then
if move_mwfact then
c.screen.selected_tag.master_width_factor = math.min(math.max((_mouse.x - wa.x) / wa.width, 0.01), 0.99)
end
if idx and idx_above then
local factor_delta = (_mouse.y - jump_to.y) / wa.height
if factor_delta < 0 then
factor_delta = math.max(factor_delta, -(wfact_above - 0.05))
else
factor_delta = math.min(factor_delta, wfact_below - 0.05)
end
local t = c.screen.selected_tag
local data = t.windowfact or {}
local colfact = data[idx.col] or {}
colfact[idx_above] = wfact_above + factor_delta
colfact[idx_below] = wfact_below - factor_delta
awful.client.incwfact(0, c_above) -- just in case
end
return true
else
return false
end
end, CURSOR)
return true
end
awful.layout.suit.tile.mouse_resize_handler = function(c)
return mouse_resize_handler(function(x)
return x
end, c)
end
---@diagnostic disable-next-line: duplicate-set-field
awful.layout.suit.tile.bottom.mouse_resize_handler = function(c)
return mouse_resize_handler(function(q)
return { x = q.y, y = q.x, width = q.height, height = q.width }
end, c)
end
-- local old_coords = mouse.coords
-- mouse.coords = function(...)
-- if select(1, ...) and not(select(1, ...).blah) then
-- print("set mouse!!!")
-- print(debug.traceback())
-- end
-- return old_coords(...)
-- end

View file

@ -0,0 +1,186 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local config = require("config")
local dpi = beautiful.xresources.apply_dpi
local theme = beautiful.get()
--- Minimalist Exit Screen
--- ~~~~~~~~~~~~~~~~~~~~~~
--- Icons
local icon_font = helpers.ui.set_font("bold 45")
local poweroff_text_icon = config.icons.power
local reboot_text_icon = config.icons.restart
local suspend_text_icon = config.icons.sleep
local exit_text_icon = config.icons.exit
local lock_text_icon = config.icons.lock
local button_bg = theme.color.base
local button_size = dpi(120)
--- Commands
local poweroff_command = function()
awful.spawn.with_shell("systemctl poweroff")
awesome.emit_signal("module::exit_screen:hide")
end
local reboot_command = function()
awful.spawn.with_shell("systemctl reboot")
awesome.emit_signal("module::exit_screen:hide")
end
local suspend_command = function()
awesome.emit_signal("module::exit_screen:hide")
awful.spawn.with_shell("systemctl suspend")
end
local exit_command = function()
awesome.quit()
end
local lock_command = function()
awesome.emit_signal("module::exit_screen:hide")
end
local create_button = function(symbol, hover_color, _, command)
local icon = wibox.widget({
forced_height = button_size,
forced_width = button_size,
halign = "center",
valign = "center",
font = icon_font,
markup = helpers.ui.colorize_text(symbol, theme.color.surface0),
widget = wibox.widget.textbox(),
})
local button = wibox.widget({
{
nil,
icon,
expand = "none",
layout = wibox.layout.align.horizontal,
},
forced_height = button_size,
forced_width = button_size,
border_width = dpi(8),
border_color = theme.color.surface0,
shape = helpers.ui.rrect(theme.border_width * 2),
bg = button_bg,
widget = wibox.container.background,
})
button:buttons(gears.table.join(awful.button({}, 1, function()
command()
end)))
button:connect_signal("mouse::enter", function()
icon.markup = helpers.ui.colorize_text(icon.text, hover_color)
button.border_color = hover_color
end)
button:connect_signal("mouse::leave", function()
icon.markup = helpers.ui.colorize_text(icon.text, theme.color.surface0)
button.border_color = theme.color.surface0
end)
helpers.ui.add_hover_cursor(button, "hand1")
return button
end
--- Create the buttons
local poweroff = create_button(poweroff_text_icon, theme.color.red, "Poweroff", poweroff_command)
local reboot = create_button(reboot_text_icon, theme.color.green, "Reboot", reboot_command)
local suspend = create_button(suspend_text_icon, theme.color.peach, "Suspend", suspend_command)
local exit = create_button(exit_text_icon, theme.color.blue, "Exit", exit_command)
local lock = create_button(lock_text_icon, theme.color.pink, "Lock", lock_command)
local create_exit_screen = function(s)
s.exit_screen = wibox({
screen = s,
type = "splash",
visible = false,
ontop = true,
bg = theme.color.transparent,
fg = theme.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({
nil,
{
nil,
{
poweroff,
reboot,
suspend,
exit,
lock,
spacing = dpi(50),
layout = wibox.layout.fixed.horizontal,
},
expand = "none",
layout = wibox.layout.align.horizontal,
},
expand = "none",
layout = wibox.layout.align.vertical,
})
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(_, _, key, _)
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)

View file

@ -0,0 +1,9 @@
local req = {
"better-resize",
"savefloats",
"exit-screen",
}
for _, x in pairs(req) do
require(... .. "." .. x)
end

View file

@ -0,0 +1,372 @@
--
-- json.lua
--
-- Copyright (c) 2020 rxi
--
-- 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
-- SOFTWARE.
--
local json = { _version = "0.1.2" }
-------------------------------------------------------------------------------
-- Encode
-------------------------------------------------------------------------------
local encode
local escape_char_map = {
["\\"] = "\\",
['"'] = '"',
["\b"] = "b",
["\f"] = "f",
["\n"] = "n",
["\r"] = "r",
["\t"] = "t",
}
local escape_char_map_inv = { ["/"] = "/" }
for k, v in pairs(escape_char_map) do
escape_char_map_inv[v] = k
end
local function escape_char(c)
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
end
local function encode_nil(_)
return "null"
end
local function encode_table(val, stack)
local res = {}
stack = stack or {}
-- Circular reference?
if stack[val] then
error("circular reference")
end
stack[val] = true
if rawget(val, 1) ~= nil or next(val) == nil then
-- Treat as array -- check keys are valid and it is not sparse
local n = 0
for k in pairs(val) do
if type(k) ~= "number" then
error("invalid table: mixed or invalid key types")
end
n = n + 1
end
if n ~= #val then
error("invalid table: sparse array")
end
-- Encode
for _, v in ipairs(val) do
table.insert(res, encode(v, stack))
end
stack[val] = nil
return "[" .. table.concat(res, ",") .. "]"
else
-- Treat as an object
for k, v in pairs(val) do
if type(k) ~= "string" then
error("invalid table: mixed or invalid key types")
end
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
end
stack[val] = nil
return "{" .. table.concat(res, ",") .. "}"
end
end
local function encode_string(val)
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
end
local function encode_number(val)
-- Check for NaN, -inf and inf
if val ~= val or val <= -math.huge or val >= math.huge then
error("unexpected number value '" .. tostring(val) .. "'")
end
return string.format("%.14g", val)
end
local type_func_map = {
["nil"] = encode_nil,
["table"] = encode_table,
["string"] = encode_string,
["number"] = encode_number,
["boolean"] = tostring,
}
encode = function(val, stack)
local t = type(val)
local f = type_func_map[t]
if f then
return f(val, stack)
end
error("unexpected type '" .. t .. "'")
end
function json.encode(val)
return (encode(val))
end
-------------------------------------------------------------------------------
-- Decode
-------------------------------------------------------------------------------
local parse
local function create_set(...)
local res = {}
for i = 1, select("#", ...) do
res[select(i, ...)] = true
end
return res
end
local space_chars = create_set(" ", "\t", "\r", "\n")
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
local literals = create_set("true", "false", "null")
local literal_map = {
["true"] = true,
["false"] = false,
["null"] = nil,
}
local function next_char(str, idx, set, negate)
for i = idx, #str do
if set[str:sub(i, i)] ~= negate then
return i
end
end
return #str + 1
end
local function decode_error(str, idx, msg)
local line_count = 1
local col_count = 1
for i = 1, idx - 1 do
col_count = col_count + 1
if str:sub(i, i) == "\n" then
line_count = line_count + 1
col_count = 1
end
end
error(string.format("%s at line %d col %d", msg, line_count, col_count))
end
local function codepoint_to_utf8(n)
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
local f = math.floor
if n <= 0x7f then
return string.char(n)
elseif n <= 0x7ff then
return string.char(f(n / 64) + 192, n % 64 + 128)
elseif n <= 0xffff then
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
elseif n <= 0x10ffff then
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, f(n % 4096 / 64) + 128, n % 64 + 128)
end
error(string.format("invalid unicode codepoint '%x'", n))
end
local function parse_unicode_escape(s)
local n1 = tonumber(s:sub(1, 4), 16)
local n2 = tonumber(s:sub(7, 10), 16)
-- Surrogate pair?
if n2 then
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
else
return codepoint_to_utf8(n1)
end
end
local function parse_string(str, i)
local res = ""
local j = i + 1
local k = j
while j <= #str do
local x = str:byte(j)
if x < 32 then
decode_error(str, j, "control character in string")
elseif x == 92 then -- `\`: Escape
res = res .. str:sub(k, j - 1)
j = j + 1
local c = str:sub(j, j)
if c == "u" then
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1)
or str:match("^%x%x%x%x", j + 1)
or decode_error(str, j - 1, "invalid unicode escape in string")
res = res .. parse_unicode_escape(hex)
j = j + #hex
else
if not escape_chars[c] then
decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string")
end
res = res .. escape_char_map_inv[c]
end
k = j + 1
elseif x == 34 then -- `"`: End of string
res = res .. str:sub(k, j - 1)
return res, j + 1
end
j = j + 1
end
decode_error(str, i, "expected closing quote for string")
end
local function parse_number(str, i)
local x = next_char(str, i, delim_chars)
local s = str:sub(i, x - 1)
local n = tonumber(s)
if not n then
decode_error(str, i, "invalid number '" .. s .. "'")
end
return n, x
end
local function parse_literal(str, i)
local x = next_char(str, i, delim_chars)
local word = str:sub(i, x - 1)
if not literals[word] then
decode_error(str, i, "invalid literal '" .. word .. "'")
end
return literal_map[word], x
end
local function parse_array(str, i)
local res = {}
local n = 1
i = i + 1
while 1 do
local x
i = next_char(str, i, space_chars, true)
-- Empty / end of array?
if str:sub(i, i) == "]" then
i = i + 1
break
end
-- Read token
x, i = parse(str, i)
res[n] = x
n = n + 1
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "]" then
break
end
if chr ~= "," then
decode_error(str, i, "expected ']' or ','")
end
end
return res, i
end
local function parse_object(str, i)
local res = {}
i = i + 1
while 1 do
local key, val
i = next_char(str, i, space_chars, true)
-- Empty / end of object?
if str:sub(i, i) == "}" then
i = i + 1
break
end
-- Read key
if str:sub(i, i) ~= '"' then
decode_error(str, i, "expected string for key")
end
key, i = parse(str, i)
-- Read ':' delimiter
i = next_char(str, i, space_chars, true)
if str:sub(i, i) ~= ":" then
decode_error(str, i, "expected ':' after key")
end
i = next_char(str, i + 1, space_chars, true)
-- Read value
val, i = parse(str, i)
-- Set
res[key] = val
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "}" then
break
end
if chr ~= "," then
decode_error(str, i, "expected '}' or ','")
end
end
return res, i
end
local char_func_map = {
['"'] = parse_string,
["0"] = parse_number,
["1"] = parse_number,
["2"] = parse_number,
["3"] = parse_number,
["4"] = parse_number,
["5"] = parse_number,
["6"] = parse_number,
["7"] = parse_number,
["8"] = parse_number,
["9"] = parse_number,
["-"] = parse_number,
["t"] = parse_literal,
["f"] = parse_literal,
["n"] = parse_literal,
["["] = parse_array,
["{"] = parse_object,
}
parse = function(str, idx)
local chr = str:sub(idx, idx)
local f = char_func_map[chr]
if f then
return f(str, idx)
end
decode_error(str, idx, "unexpected character '" .. chr .. "'")
end
function json.decode(str)
if type(str) ~= "string" then
error("expected argument of type string, got " .. type(str))
end
local res, idx = parse(str, next_char(str, 1, space_chars, true))
idx = next_char(str, idx, space_chars, true)
if idx <= #str then
decode_error(str, idx, "trailing garbage")
end
return res
end
return json

View file

@ -0,0 +1,58 @@
local awful = require("awful")
local function rel(screen, win)
return {
x = (win.x - screen.x) / screen.width,
y = (win.y - screen.y) / screen.height,
width = win.width / screen.width,
aspect = win.height / win.width,
}
end
local function unrel(s, _rel)
return _rel
and {
x = s.x + s.width * _rel.x,
y = s.y + s.height * _rel.y,
width = s.width * _rel.width,
height = _rel.aspect * s.width * _rel.width,
}
end
local stored = {}
local function forget(c)
stored[c] = nil
end
local floating = awful.layout.suit.floating
function Remember(c)
if floating == awful.layout.get(c.screen) or c.floating then
stored[c.window] = rel(c.screen.geometry, c:geometry())
end
end
function Restore(c)
local s = stored[c.window]
if s then
c:geometry(unrel(c.screen.geometry, stored[c.window]))
return true
else
return false
end
end
client.connect_signal("manage", Remember)
client.connect_signal("property::geometry", Remember)
client.connect_signal("unmanage", forget)
tag.connect_signal("property::layout", function(t)
if floating == awful.layout.get(t.screen) then
for _, c in ipairs(t:clients()) do
c:geometry(unrel(t.screen.geometry, stored[c.window]))
end
end
end)
return Restore

View file

@ -0,0 +1,286 @@
local awful = require("awful")
local hotkeys_popup = require("awful.hotkeys_popup")
local menubar = require("menubar")
local machi = require("lib.layout-machi")
local menu = require("main.menu")
local config = require("config")
local apps = config.apps
local keys = config.keys
-- General awesome keybindings
awful.keyboard.append_global_keybindings({
awful.key({ keys.mod, "Control" }, "r", awesome.restart, { description = "reload awesome", group = "awesome" }),
awful.key({ keys.mod, "Shift" }, "q", awesome.quit, { description = "quit awesome", group = "awesome" }),
awful.key({ keys.mod, "Control", "Shift" }, "x", function()
awful.prompt.run({
prompt = "Run Lua code: ",
textbox = awful.screen.focused().promptbox.widget,
exe_callback = awful.util.eval,
history_path = awful.util.get_cache_dir() .. "/history_eval",
})
end, { description = "lua execute prompt", group = "awesome" }),
awful.key({ keys.mod }, "Return", function()
awful.spawn(apps.terminal)
end, { description = "open a terminal", group = "launcher" }),
awful.key({ keys.mod, "Shift" }, "c", function()
menu.mainmenu:show()
end, { description = "show main menu", group = "awesome" }),
awful.key({ keys.mod }, "p", function()
menubar.show()
end, { description = "show the menubar", group = "launcher" }),
})
-- Tag bindings
awful.keyboard.append_global_keybindings({
awful.key({ keys.mod, "Control" }, "s", hotkeys_popup.show_help, { description = "show help", group = "awesome" }),
awful.key({ keys.mod }, "Left", awful.tag.viewprev, { description = "view previous", group = "tag" }),
awful.key({ keys.mod }, "Right", awful.tag.viewnext, { description = "view next", group = "tag" }),
awful.key({ keys.mod }, "Tab", awful.tag.history.restore, { description = "go back", group = "tag" }),
})
awful.keyboard.append_global_keybindings({
awful.key({
modifiers = { keys.mod },
keygroup = "numrow",
description = "only view tag",
group = "tag",
on_press = function(index)
local screen = awful.screen.focused()
local tag = screen.tags[index]
if tag then
tag:view_only()
end
end,
}),
awful.key({
modifiers = { keys.mod, "Control" },
keygroup = "numrow",
description = "toggle tag",
group = "tag",
on_press = function(index)
local screen = awful.screen.focused()
local tag = screen.tags[index]
if tag then
awful.tag.viewtoggle(tag)
end
end,
}),
awful.key({
modifiers = { keys.mod, "Shift" },
keygroup = "numrow",
description = "move focused client to tag",
group = "tag",
on_press = function(index)
if client.focus then
local tag = client.focus.screen.tags[index]
if tag then
client.focus:move_to_tag(tag)
end
end
end,
}),
awful.key({
modifiers = { keys.mod, "Control", "Shift" },
keygroup = "numrow",
description = "toggle focused client on tag",
group = "tag",
on_press = function(index)
if client.focus then
local tag = client.focus.screen.tags[index]
if tag then
client.focus:toggle_tag(tag)
end
end
end,
}),
awful.key({
modifiers = { keys.mod },
keygroup = "numpad",
description = "select layout directly",
group = "layout",
on_press = function(index)
local t = awful.screen.focused().selected_tag
if t then
t.layout = t.layouts[index] or t.layout
end
end,
}),
})
-- Focus bindings
awful.keyboard.append_global_keybindings({
awful.key({ keys.mod }, "c", function()
awful.client.focus.byidx(1)
end, { description = "focus next by index", group = "client" }),
awful.key({ keys.mod }, "x", function()
awful.client.focus.byidx(-1)
end, { description = "focus previous by index", group = "client" }),
awful.key({ keys.mod }, "Escape", function()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end, { description = "go back", group = "client" }),
awful.key({ keys.mod, "Control" }, "j", function()
awful.screen.focus_relative(1)
end, { description = "focus the next screen", group = "screen" }),
awful.key({ keys.mod, "Control" }, "k", function()
awful.screen.focus_relative(-1)
end, { description = "focus the previous screen", group = "screen" }),
awful.key({ keys.mod, "Control" }, "n", function()
local c = awful.client.restore()
-- Focus restored client
if c then
c:activate({ raise = true, context = "key.unminimize" })
end
end, { description = "restore minimized", group = "client" }),
})
-- Layout bindings
awful.keyboard.append_global_keybindings({
awful.key({ keys.mod, "Shift" }, "j", function()
awful.client.swap.byidx(1)
end, { description = "swap with next client by index", group = "client" }),
awful.key({ keys.mod, "Shift" }, "k", function()
awful.client.swap.byidx(-1)
end, { description = "swap with previous client by index", group = "client" }),
awful.key(
{ keys.mod },
"u",
awful.client.urgent.jumpto,
{ description = "jump to urgent client", group = "client" }
),
awful.key({ keys.mod }, "l", function()
awful.tag.incmwfact(0.05)
end, { description = "increase master width factor", group = "layout" }),
awful.key({ keys.mod }, "h", function()
awful.tag.incmwfact(-0.05)
end, { description = "decrease master width factor", group = "layout" }),
awful.key({ keys.mod, "Shift" }, "h", function()
awful.tag.incnmaster(1, nil, true)
end, { description = "increase the number of master clients", group = "layout" }),
awful.key({ keys.mod, "Shift" }, "l", function()
awful.tag.incnmaster(-1, nil, true)
end, { description = "decrease the number of master clients", group = "layout" }),
awful.key({ keys.mod, "Control" }, "h", function()
awful.tag.incncol(1, nil, true)
end, { description = "increase the number of columns", group = "layout" }),
awful.key({ keys.mod, "Control" }, "l", function()
awful.tag.incncol(-1, nil, true)
end, { description = "decrease the number of columns", group = "layout" }),
awful.key({ keys.mod }, "-", function()
machi.default_editor.start_interactive()
end, { description = "edit the current layout if it is a machi layout", group = "layout" }),
awful.key({ keys.mod }, ".", function()
machi.switcher.start(client.focus)
end, { description = "switch between windows for a machi layout", group = "layout" }),
})
-- Client bindings
client.connect_signal("request::default_keybindings", function()
awful.keyboard.append_client_keybindings({
awful.key({ keys.mod }, "f", function(c)
c.fullscreen = not c.fullscreen
c:raise()
end, { description = "toggle fullscreen", group = "client" }),
awful.key({ keys.mod }, "w", function(c)
c:kill()
end, { description = "close", group = "client" }),
awful.key(
{ keys.mod, "Control" },
"space",
awful.client.floating.toggle,
{ description = "toggle floating", group = "client" }
),
awful.key({ keys.mod, "Control" }, "Return", function(c)
c:swap(awful.client.getmaster())
end, { description = "move to master", group = "client" }),
awful.key({ keys.mod }, "o", function(c)
c:move_to_screen()
end, { description = "move to screen", group = "client" }),
awful.key({ keys.mod }, "t", function(c)
c.ontop = not c.ontop
end, { description = "toggle keep on top", group = "client" }),
awful.key({ keys.mod }, "n", function(c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end, { description = "minimize", group = "client" }),
awful.key({ keys.mod }, "m", function(c)
c.maximized = not c.maximized
c:raise()
end, { description = "(un)maximize", group = "client" }),
awful.key({ keys.mod, "Control" }, "m", function(c)
c.maximized_vertical = not c.maximized_vertical
c:raise()
end, { description = "(un)maximize vertically", group = "client" }),
awful.key({ keys.mod, "Shift" }, "m", function(c)
c.maximized_horizontal = not c.maximized_horizontal
c:raise()
end, { description = "(un)maximize horizontally", group = "client" }),
})
end)
-- Mouse bindings
awful.mouse.append_global_mousebindings({
awful.button({}, 3, function()
menu.mainmenu:toggle()
end),
awful.button({}, 4, awful.tag.viewprev),
awful.button({}, 5, awful.tag.viewnext),
})
client.connect_signal("request::default_mousebindings", function()
awful.mouse.append_client_mousebindings({
awful.button({}, 1, function(c)
c:activate({ context = "mouse_click" })
end),
awful.button({ keys.mod }, 1, function(c)
c:activate({ context = "mouse_click", action = "mouse_move" })
end),
awful.button({ keys.mod }, 3, function(c)
c:activate({ context = "mouse_click", action = "mouse_resize" })
end),
})
end)

View file

@ -0,0 +1,63 @@
local awful = require("awful")
local volume = require("ui.popups.volume")
local filesystem = require("gears.filesystem")
local config = require("config")
local keys = config.keys
local config_dir = filesystem.get_configuration_dir()
local utils_dir = config_dir .. "utilities/"
local screenshot_area = utils_dir .. "screensht area"
local screenshot_full = utils_dir .. "screensht full"
awful.keyboard.append_global_keybindings({
awful.key({ keys.mod }, "r", function()
awful.spawn(config.apps.launcher)
end, { description = "show rofi", group = "launcher" }),
awful.key({ keys.mod }, "Print", function()
awful.spawn.easy_async_with_shell(screenshot_area, function() end)
end, { description = "take a area screenshot", group = "Utils" }),
awful.key({}, "Print", function()
awful.spawn.easy_async_with_shell(screenshot_full, function() end)
end, { description = "take a full screenshot", group = "Utils" }),
awful.key({ keys.mod }, "q", function()
awesome.emit_signal("module::exit_screen:show")
end, { description = "show Exit Screen", group = "Utils" }),
awful.key({ keys.mod }, "s", function()
awesome.emit_signal("scratchpad::toggle")
end, { description = "show Scratchpad", group = "Utils" }),
awful.key({ keys.mod }, "b", function()
awful.spawn.easy_async_with_shell("headsetcontrol -l 0", function() end)
end, { description = "headsetcontrol", group = "Utils" }),
awful.key({ keys.mod }, "t", function()
awful.titlebar.toggle(client.focus)
end, { description = "toggle titlebar for active client", group = "Utils" }), -- Toggle titlebar
})
-- Volume
awful.keyboard.append_global_keybindings({
awful.key({}, "XF86AudioRaiseVolume", function()
volume.increase()
awesome.emit_signal("widget::update_vol")
awesome.emit_signal("module::volume_osd:show", true)
end),
awful.key({}, "XF86AudioLowerVolume", function()
volume.decrease()
awesome.emit_signal("widget::update_vol")
awesome.emit_signal("module::volume_osd:show", true)
end),
awful.key({}, "XF86AudioMute", function()
volume.mute()
awesome.emit_signal("widget::update_vol")
awesome.emit_signal("module::volume_osd:show", true)
end),
})

View file

@ -0,0 +1,31 @@
local naughty = require("naughty")
-- Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
naughty.notify({
preset = naughty.config.presets.critical,
title = "Oops, there were errors during startup!",
text = awesome.startup_errors,
})
end
-- Handle runtime errors after startup
do
local in_error = false
awesome.connect_signal("debug::error", function(err)
-- Make sure we don't go into an endless error loop
if in_error then
return
end
in_error = true
naughty.notify({
preset = naughty.config.presets.critical,
title = "Oops, an error happened!",
text = tostring(err),
})
in_error = false
end)
end

View file

@ -0,0 +1,14 @@
local req = {
"error_handling",
"layout",
"menu",
"wallpaper",
"bindings",
"custom_bindings",
"rules",
"tags",
}
for _, x in pairs(req) do
require(... .. "." .. x)
end

View file

@ -0,0 +1,36 @@
local awful = require("awful")
local bling = require("lib.bling")
local machi = require("lib.layout-machi")
-- Custom Layouts
local mstab = bling.layout.mstab
local centered = bling.layout.centered
local equal = bling.layout.equalarea
local deck = bling.layout.deck
machi.editor.nested_layouts = {
["0"] = deck,
["1"] = mstab,
["2"] = awful.layout.suit.spiral,
["3"] = awful.layout.suit.fair,
["4"] = awful.layout.suit.fair.horizontal,
}
-- Table of layouts to cover with awful.layout.inc, order matters.
awful.layout.append_default_layouts({
awful.layout.suit.tile,
awful.layout.suit.spiral.dwindle,
awful.layout.suit.floating,
awful.layout.suit.max,
centered,
mstab,
equal,
machi.default_layout,
})
client.connect_signal("manage", function(c)
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
end)

View file

@ -0,0 +1,107 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local helpers = require("helpers")
local hotkeys_popup = require("awful.hotkeys_popup")
local theme = require("beautiful").get()
local apps = require("config").apps
local menu = {}
local rofi = {}
rofi.timer = gears.timer({
autostart = false,
timeout = 0.1,
single_shot = true,
callback = function()
awful.spawn(apps.launcher)
end,
})
menu.awesome = {
{
"Hotkeys",
function()
hotkeys_popup.show_help(nil, awful.screen.focused())
end,
},
{ "Manual", apps.terminal .. " -e man awesome" },
{ "Edit Config", apps.start_editor .. " " .. awesome.conffile },
{ "Restart", awesome.restart },
{
"Quit",
function()
awesome.quit()
end,
},
}
menu.mainmenu = awful.menu({
items = {
{
"Applications",
function()
menu.mainmenu:hide()
rofi.timer:start()
end,
},
{ "Terminal", apps.terminal },
{ "Web Browser", apps.browser },
{ "File Manager", apps.file_manager },
{ "Text Editor", apps.code_editor },
{ "Music Player", apps.music_player },
{
"Info Panel",
function()
awesome.emit_signal("sidebar::toggle")
end,
},
{
"Notifications",
function()
awesome.emit_signal("action::toggle")
end,
},
{
"Exit",
function()
awesome.emit_signal("module::exit_screen:show")
end,
},
{ "AwesomeWM", menu.awesome },
},
})
-- apply rounded corners to menus when picom isn't available, thanks to u/signalsourcesexy
-- also applies antialiasing! - By me.
menu.mainmenu.wibox.shape = helpers.ui.rrect(10)
menu.mainmenu.wibox.bg = theme.bg_normal .. "00"
menu.mainmenu.wibox:set_widget(wibox.widget({
menu.mainmenu.wibox.widget,
bg = theme.bg_normal,
shape = helpers.ui.rrect(0),
widget = wibox.container.background,
}))
-- apply rounded corners to submenus, thanks to u/signalsourcesexy
-- also applies antialiasing! - By me.
awful.menu.original_new = awful.menu.new
---@diagnostic disable-next-line: duplicate-set-field
function awful.menu.new(...)
local ret = awful.menu.original_new(...)
ret.wibox.shape = helpers.ui.rrect(10)
ret.wibox.bg = theme.bg_normal .. "00"
ret.wibox:set_widget(wibox.widget({
ret.wibox.widget,
widget = wibox.container.background,
bg = theme.color.base,
shape = helpers.ui.rrect(0),
}))
return ret
end
return menu

View file

@ -0,0 +1,78 @@
local awful = require("awful")
local ruled = require("ruled")
local dpi = require("beautiful.xresources").apply_dpi
local helpers = require("helpers")
local config = require("config")
ruled.client.connect_signal("request::rules", function()
ruled.client.append_rule({
id = "global",
rule = {},
properties = {
focus = awful.client.focus.filter,
raise = true,
screen = awful.screen.preferred,
placement = awful.placement.no_overlap + awful.placement.no_offscreen,
},
})
ruled.client.append_rule({
id = "titlebars",
rule_any = {
type = { "normal", "dialog" },
},
properties = {
titlebars_enabled = false,
},
})
ruled.client.append_rule({
rule = { class = config.apps.launcher },
properties = {
titlebars_enabled = false,
},
})
ruled.client.append_rule({
rule = { instance = "origin.exe" },
properties = {
floating = true,
titlebars_enabled = false,
shape = helpers.ui.rrect(0),
border_width = dpi(0),
},
})
ruled.client.append_rule({
rule = { instance = "bf1.exe" },
properties = { shape = helpers.ui.rrect(0), fullscreen = true, tag = "󰍹", switchtotag = true },
})
ruled.client.append_rule({
rule = { instance = "wine" },
properties = { shape = helpers.ui.rrect(0), titlebars_enabled = false },
})
ruled.client.append_rule({
rule_any = {
floating = true,
},
properties = {
placement = awful.placement.centered,
ontop = true,
},
})
ruled.client.append_rule({
rule_any = {
class = {
"xfce",
},
instance = {
"xfce",
},
},
properties = {
floating = true,
},
})
end)

View file

@ -0,0 +1,10 @@
local awful = require("awful")
local icons = require("config").icons.tags
screen.connect_signal("request::desktop_decoration", function(s)
awful.tag(
{ icons.general, icons.files, icons.media, icons.terminal, icons.coding, icons.misc },
s,
awful.layout.layouts[1]
)
end)

View file

@ -0,0 +1,26 @@
local awful = require("awful")
local wibox = require("wibox")
local image = require("config").theme.wallpaper
local function set_wall(s)
awful.wallpaper({
screen = s,
widget = {
{
image = image,
upscale = true,
downscale = true,
widget = wibox.widget.imagebox,
},
valign = "center",
halign = "center",
tiled = true,
widget = wibox.container.tile,
},
})
end
screen.connect_signal("request::wallpaper", function(s)
set_wall(s)
end)

26
dot_config/awesome/rc.lua Normal file
View file

@ -0,0 +1,26 @@
pcall(require, "luarocks.loader")
local gears = require("gears")
local beautiful = require("beautiful")
local awful = require("awful")
require("awful.autofocus")
-- Theme --
beautiful.init(gears.filesystem.get_configuration_dir() .. "themes/catppuccin/theme.lua")
-- Main/Configuration --
require("main")
-- Libraries/Modules --
require("lib")
-- Signals/Monitoring --
require("signals")
-- Ui/Panels --
require("ui")
-- Autostart --
awful.spawn.with_shell("picom")
awful.spawn.with_shell("~/.config/.fehbg")

View file

@ -0,0 +1,20 @@
local awful = require("awful")
local gears = require("gears")
local function get_cpu()
local script = "echo $[100-$(vmstat 1 2|tail -1|awk '{print $15}')]"
awful.spawn.easy_async_with_shell(script, function(cpu_perc)
cpu_perc = cpu_perc:match("%d+")
awesome.emit_signal("signal::cpu", cpu_perc)
end)
end
gears.timer({
timeout = 1,
call_now = true,
autostart = true,
callback = function()
get_cpu()
end,
})

View file

@ -0,0 +1,23 @@
local awful = require("awful")
local gears = require("gears")
local config = require("config")
local disk = config.widget.disk.name
local function get_disk()
local script = "df -kH -B 1MB" .. disk .. "| tail -1 | awk '{printf $5}'"
awful.spawn.easy_async_with_shell(script, function(disk_perc)
disk_perc = disk_perc:match("%d+")
awesome.emit_signal("signal::disk", disk_perc)
end)
end
gears.timer({
timeout = 2000,
call_now = true,
autostart = true,
callback = function()
get_disk()
end,
})

View file

@ -0,0 +1,14 @@
local req = {
"volume",
"mic",
"cpu",
"mem",
"player",
"disk",
"uptime",
"playerctl",
}
for _, x in pairs(req) do
require("signals." .. x)
end

View file

@ -0,0 +1,22 @@
local awful = require("awful")
local gears = require("gears")
local function get_mem()
local script = [[
free | grep Mem | awk '{print $3/$2 * 100.0}' | cut -f 1 -d "."
]]
awful.spawn.easy_async_with_shell(script, function(mem_perc)
mem_perc = mem_perc:match("%d+")
awesome.emit_signal("signal::mem", mem_perc)
end)
end
gears.timer({
timeout = 4,
call_now = true,
autostart = true,
callback = function()
get_mem()
end,
})

View file

@ -0,0 +1,29 @@
local awful = require("awful")
local config = require("config")
local microphone = config.widget.mic.name
local vol_sc = "pamixer --source " .. microphone .. " --get-volume"
local mute_sc = "pamixer --source " .. microphone .. " --get-mute"
local function get_vol()
awful.spawn.easy_async_with_shell(vol_sc, function(vol)
awful.spawn.easy_async_with_shell(mute_sc, function(mute)
local muted
if mute:match("false") then
muted = false
else
muted = true
end
awesome.emit_signal("signal::mic", vol, muted)
end)
end)
end
awesome.connect_signal("widget::update_mic", function() -- Needs to be Updated if muted! For Mute in Sidebar Widget
get_vol()
end)
get_vol()

View file

@ -0,0 +1,31 @@
local awful = require("awful")
-- Script
local title_sc = "mpc -f %title% | head -1"
local artist_sc = "mpc -f %artist% | head -1"
local length_sc = "mpc | awk '{print $3}' | awk 'NR==2'"
local status_sc = "mpc | awk '{print $1}' | awk 'NR==2' | sed 's/[[]*//g' | sed 's/[]]*//g'"
-- function
local function get_player()
awful.spawn.easy_async_with_shell(title_sc, function(title)
awful.spawn.easy_async_with_shell(artist_sc, function(artist)
awful.spawn.easy_async_with_shell(length_sc, function(length)
awful.spawn.easy_async_with_shell(status_sc, function(status)
title = string.gsub(title, "\n", "")
artist = string.gsub(artist, "\n", "")
length = string.gsub(length, "\n", "")
status = string.gsub(status, "\n", "")
awesome.emit_signal("signal::player", title, artist, length, status)
end)
end)
end)
end)
end
awesome.connect_signal("widget::update_player", function()
get_player()
end)
get_player()

View file

@ -0,0 +1,17 @@
local bling = require("lib.bling")
local instance = nil
local function new()
return bling.signal.playerctl.lib({
update_on_activity = true,
player = { "mopidy", "spotify", "%any" },
debounce_delay = 1,
})
end
if not instance then
instance = new()
end
return instance

View file

@ -0,0 +1,16 @@
local awful = require("awful")
local function get_uptime()
local script = [[
uptime -p | sed 's/up\s*//g' | sed 's/\s*days*/d/g' | sed 's/\s*hours*/h/g' | sed 's/\s*minutes*/m/g'
]]
awful.spawn.easy_async_with_shell(script, function(uptime)
uptime = string.gsub(uptime, "\n", "")
awesome.emit_signal("signal::uptime", uptime)
end)
end
awesome.connect_signal("widget::update_uptime", function()
get_uptime()
end)
get_uptime()

View file

@ -0,0 +1,26 @@
local awful = require("awful")
local vol_sc = "pamixer --get-volume"
local mute_sc = "pamixer --get-mute"
local function get_vol()
awful.spawn.easy_async_with_shell(vol_sc, function(vol)
awful.spawn.easy_async_with_shell(mute_sc, function(mute)
local muted
if mute:match("false") then
muted = false
else
muted = true
end
awesome.emit_signal("signal::volume", vol, muted)
end)
end)
end
awesome.connect_signal("widget::update_vol", function() -- Needs to be Updated if muted! For Pulseaudio Widget
get_vol()
end)
get_vol()

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="240"
height="240"
viewBox="0 0 240 240"
id="svg4"
sodipodi:docname="volume-high.svg"
inkscape:version="0.92.4 5da689c313, 2019-01-14">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1321"
inkscape:window-height="740"
id="namedview6"
showgrid="false"
inkscape:pagecheckerboard="true"
inkscape:zoom="0.98333333"
inkscape:cx="-267.45763"
inkscape:cy="120"
inkscape:window-x="45"
inkscape:window-y="28"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
d="m 142.22222,22.555558 v 22.88889 c 32.11111,9.55555 55.55556,39.33333 55.55556,74.555552 0,35.22222 -23.44445,64.88888 -55.55556,74.44444 v 23 C 186.66667,207.33333 220,167.55555 220,120 220,72.444448 186.66667,32.666668 142.22222,22.555558 M 170,120 C 170,100.33333 158.88889,83.444448 142.22222,75.222228 V 164.44444 C 158.88889,156.55555 170,139.55555 170,120 M 20,86.666668 V 153.33333 H 64.444444 L 120,208.88888 V 31.111118 l -55.555556,55.55555 z"
id="path2"
inkscape:connector-curvature="0"
style="fill:#ffffff;stroke-width:11.11111164" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

View file

@ -0,0 +1,202 @@
local beautiful = require("beautiful")
local gfs = require("gears.filesystem")
local config = require("config")
local helpers = require("helpers")
local palette = require("lib.catppuccin.catppuccin." .. config.theme.flavor)
local theme_assets = beautiful.theme_assets
local dpi = beautiful.xresources.apply_dpi
local theme_path = gfs.get_configuration_dir() .. "themes/catppuccin/"
local theme = {}
theme.color = {}
-- Transparent Color --
theme.color.transparent = "#00000000"
-- Base --
theme.color.crust = palette.crust.hex
theme.color.mantle = palette.mantle.hex
theme.color.base = palette.base.hex
-- Surface --
theme.color.surface0 = palette.surface0.hex
theme.color.surface1 = palette.surface1.hex
theme.color.surface2 = palette.surface2.hex
-- Overlay --
theme.color.overlay0 = palette.overlay0.hex
theme.color.overlay1 = palette.overlay1.hex
theme.color.overlay2 = palette.overlay2.hex
-- Text --
theme.color.text = palette.text.hex
theme.color.subtext0 = palette.subtext0.hex
theme.color.subtext1 = palette.subtext1.hex
theme.color.lavender = palette.lavender.hex
theme.color.blue = palette.blue.hex
theme.color.sapphire = palette.sapphire.hex
theme.color.sky = palette.sky.hex
theme.color.teal = palette.teal.hex
theme.color.green = palette.green.hex
theme.color.yellow = palette.yellow.hex
theme.color.peach = palette.peach.hex
theme.color.maroon = palette.maroon.hex
theme.color.red = palette.red.hex
theme.color.mauve = palette.mauve.hex
theme.color.pink = palette.pink.hex
theme.color.flamingo = palette.flamingo.hex
theme.color.rosewater = palette.rosewater.hex
theme.color.accent1 = theme.color[config.theme.accent1]
theme.color.accent2 = theme.color[config.theme.accent2]
theme.music = theme_path .. "assets/music.png"
theme.volume_on = theme_path .. "assets/volume-on.png"
theme.volume_off = theme_path .. "assets/volume-off.png"
theme.pfp = config.theme.pfp
theme.wallpaper = config.theme.wallpaper
theme.font = config.theme.font.family .. " " .. config.theme.font.size
theme.titlebar_bg_focus = theme.color.base
theme.titlebar_bg = theme.color.base
theme.bg_normal = theme.color.base
theme.bg_focus = theme.color.surface0
theme.bg_urgent = theme.color.red
theme.bg_minimize = theme.color.surface1
theme.bg_systray = theme.bg_normal
theme.fg_normal = theme.color.subtext1 -- text color
theme.fg_focus = theme.color.accent1
theme.fg_urgent = theme.color.text
theme.fg_minimize = theme.color.text
theme.useless_gap = dpi(10)
theme.border_width = dpi(1)
theme.border_normal = theme.color.surface0
theme.border_focus = theme.color.accent1
theme.border_marked = theme.color.maroon
theme.menu_font = helpers.ui.set_font("12", theme.font)
theme.menu_bg_focus = theme.color.base
theme.menu_fg_focus = theme.color.accent2
theme.menu_border_width = dpi(2)
theme.menu_border_color = theme.color.surface0
theme.submenu = config.icons.arr.r .. " "
theme.menu_height = dpi(37)
theme.menu_width = dpi(194)
theme.tasklist_bg_focus = theme.color.base
theme.tasklist_fg_focus = theme.color.lavender
theme.tasklist_disable_icon = true
theme.tasklist_font = helpers.ui.set_font("11", theme.font)
theme.taglist_spacing = dpi(2)
theme.taglist_bg_focus = theme.color.base
theme.taglist_disable_icon = true
theme.taglist_font = helpers.ui.set_font("11", theme.font)
theme.taglist_fg_focus = theme.color.accent2
theme.taglist_fg_empty = theme.color.surface2
theme.taglist_fg_occupied = theme.color.sky
-- Generate taglist squares:
local taglist_square_size = dpi(0)
theme.taglist_squares_sel = theme_assets.taglist_squares_sel(taglist_square_size, theme.color.accent2)
theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(taglist_square_size, theme.taglist_fg_occupied)
-- Edge Snap
theme.snap_bg = theme.color.accent1
theme.snap_border_width = dpi(5)
theme.snap_shape = helpers.ui.rrect(0)
-- Hotkey Popup
theme.hotkeys_shape = helpers.ui.rrect(12)
theme.hotkeys_border_color = theme.color.accent1
theme.hotkeys_modifiers_fg = theme.color.overlay2
theme.hotkeys_font = helpers.ui.set_font("10", theme.font)
theme.hotkeys_description_font = helpers.ui.set_font("10", theme.font)
-- Layoutlist
theme.layoutlist_shape_selected = helpers.ui.rrect(7)
-- Tabs
theme.mstab_bar_height = dpi(1)
theme.mstab_dont_resize_slaves = true
theme.mstab_bar_padding = dpi(10)
theme.mstab_border_radius = dpi(6)
theme.mstab_bar_ontop = false
theme.mstab_tabbar_position = "top"
theme.mstab_tabbar_style = "default"
theme.mstab_bar_disable = true
-- Layout Machi
theme.machi_switcher_border_color = theme.color.surface0
theme.machi_switcher_border_opacity = 0.4
theme.machi_editor_border_color = theme.color.surface1
theme.machi_editor_border_opacity = 0.4
theme.machi_editor_active_opacity = 0.4
-- Bling
theme.tag_preview_widget_border_radius = dpi(6)
theme.tag_preview_client_border_radius = dpi(6)
theme.tag_preview_client_opacity = 1
theme.tag_preview_client_bg = theme.color.base
theme.tag_preview_client_border_color = theme.color.surface0
theme.tag_preview_client_border_width = dpi(2)
theme.tag_preview_widget_border_color = theme.color.accent1
theme.tag_preview_widget_border_width = dpi(2)
theme.tag_preview_widget_margin = 4
-- Notifications
theme.notification_spacing = dpi(4)
theme.notification_bg = theme.color.base
-- Titlebar icons
theme.titlebar_close_button_normal = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_close_button_focus = theme_path .. "titlebar/close.svg"
theme.titlebar_close_button_normal_hover = theme_path .. "titlebar/close_hover.svg"
theme.titlebar_close_button_focus_hover = theme_path .. "titlebar/close_hover.svg"
theme.titlebar_minimize_button_normal = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_minimize_button_focus = theme_path .. "titlebar/minimize.svg"
theme.titlebar_minimize_button_normal_hover = theme_path .. "titlebar/minimize_hover.svg"
theme.titlebar_minimize_button_focus_hover = theme_path .. "titlebar/minimize_hover.svg"
theme.titlebar_ontop_button_normal_inactive = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_ontop_button_focus_inactive = theme_path .. "titlebar/ontop.svg"
theme.titlebar_ontop_button_normal_active = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_ontop_button_focus_active = theme_path .. "titlebar/ontop.svg"
theme.titlebar_maximized_button_normal_active = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_maximized_button_focus_active = theme_path .. "titlebar/maximize.svg"
theme.titlebar_maximized_button_normal_active_hover = theme_path .. "titlebar/maximize_hover.svg"
theme.titlebar_maximized_button_focus_active_hover = theme_path .. "titlebar/maximize_hover.svg"
theme.titlebar_maximized_button_normal_inactive = theme_path .. "titlebar/unfocus.svg"
theme.titlebar_maximized_button_focus_inactive = theme_path .. "titlebar/maximize.svg"
theme.titlebar_maximized_button_normal_inactive_hover = theme_path .. "titlebar/maximize_hover.svg"
theme.titlebar_maximized_button_focus_inactive_hover = theme_path .. "titlebar/maximize_hover.svg"
-- Layout icons
theme.layout_floating = theme_path .. "layouts/floating.png"
theme.layout_max = theme_path .. "layouts/max.png"
theme.layout_tile = theme_path .. "layouts/tile.png"
theme.layout_dwindle = theme_path .. "layouts/dwindle.png"
theme.layout_centered = theme_path .. "layouts/centered.png"
theme.layout_mstab = theme_path .. "layouts/mstab.png"
theme.layout_equalarea = theme_path .. "layouts/equalarea.png"
theme.layout_machi = theme_path .. "layouts/machi.png"
-- Generate Awesome icon:
theme.awesome_icon = theme_assets.awesome_icon(theme.menu_height, theme.bg_focus, theme.fg_focus)
-- Define the icon theme for application icons. If not set then the icons
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = config.theme.icon_theme
return theme

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#f38ba8" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0.0001,0.00009)"><g><g transform="translate(0,0.00001) scale(30.23622,30.23622)"><g id="layer1"><circle cx="4.23333" cy="4.23333" r="4.23333" id="mdi-close-normal"></circle></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 656 B

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#f24f86" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0,0) scale(30.23622,30.23622)"><g id="layer1"><path d="M4.23333,0c-1.12275,0 -2.19951,0.44601 -2.99342,1.23991c-0.7939,0.7939 -1.23991,1.87067 -1.23991,2.99342c0,1.12275 0.44601,2.19951 1.23991,2.99342c0.7939,0.7939 1.87067,1.23991 2.99342,1.23991c1.12275,0 2.19951,-0.44601 2.99342,-1.23991c0.7939,-0.7939 1.23991,-1.87067 1.23991,-2.99342c0,-1.12275 -0.44601,-2.19951 -1.23991,-2.99342c-0.7939,-0.7939 -1.87067,-1.23991 -2.99342,-1.23991zM2.92334,2.36471c0.13935,0.00056 0.27812,0.05454 0.38447,0.16175l0.92863,0.93586l0.93586,-0.92811c0.21441,-0.2127 0.55831,-0.2113 0.77101,0.0031c0.2127,0.21441 0.2113,0.55831 -0.0031,0.77101l-0.93586,0.92811l0.92811,0.93586c0.2127,0.21441 0.21182,0.55831 -0.00258,0.77101c-0.21441,0.2127 -0.55831,0.2113 -0.77101,-0.0031l-0.92863,-0.93586l-0.93586,0.92863c-0.21441,0.2127 -0.55831,0.2113 -0.77101,-0.0031c-0.2127,-0.21441 -0.2113,-0.55831 0.0031,-0.77101l0.93586,-0.92863l-0.92811,-0.93586c-0.2127,-0.21441 -0.21182,-0.55831 0.00258,-0.77101c0.1072,-0.10635 0.24719,-0.1592 0.38654,-0.15865z" id="mdi-close-normal"></path></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#a6e3a1" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0.0001,0.00009)"><g><g transform="translate(0,0.00001) scale(30.23622,30.23622)"><g id="layer1"><circle cx="4.23333" cy="4.23333" r="4.23333" id="mdi-close-normal"></circle></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 656 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.4666665 8.4666666" version="1.1" id="svg4249" inkscape:export-filename="../../png/maximize/maximize_3.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" sodipodi:docname="maximize_3.svg" fill="#52e0ad">
<sodipodi:namedview id="namedview4251" pagecolor="#505050" bordercolor="#ffffff" borderopacity="1" inkscape:showpageshadow="0" inkscape:pageopacity="0" inkscape:pagecheckerboard="1" inkscape:deskcolor="#505050" inkscape:document-units="mm" showgrid="false" inkscape:zoom="5.6568543" inkscape:cx="27.577164" inkscape:cy="18.384776" inkscape:window-width="1260" inkscape:window-height="724" inkscape:window-x="10" inkscape:window-y="66" inkscape:window-maximized="1" inkscape:current-layer="layer1"/>
<defs id="defs4246"/>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1">
<path id="mdi-close-normal" style="fill: #52e0ad;fill-rule:evenodd;stroke-width:0.264583;paint-order:normal;fill-opacity:1" d="M 4.2333333 0 A 4.2333331 4.2333331 0 0 0 0 4.2333333 A 4.2333331 4.2333331 0 0 0 4.2333333 8.4666667 A 4.2333331 4.2333331 0 0 0 8.4666667 4.2333333 A 4.2333331 4.2333331 0 0 0 4.2333333 0 z M 3.0907674 2.0789429 L 5.7303996 2.0789429 C 6.0818693 2.0789429 6.369637 2.3661641 6.369637 2.7176636 L 6.369637 5.3572957 L 3.0907674 2.0789429 z M 2.0970296 3.0990356 L 5.3862345 6.3877238 L 2.7362671 6.3877238 C 2.3847577 6.3877238 2.0970296 6.1005024 2.0970296 5.7490031 L 2.0970296 3.0990356 z "/>
<path style="fill: #52e0ad;fill-opacity:1;stroke-width:0.264583" d="M 10.768947,5.8246909 10.743132,3.2134246" id="path7007"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#f9e2af" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0.0001,0.00009)"><g><g transform="translate(0,0.00001) scale(30.23622,30.23622)"><g id="layer1"><circle cx="4.23333" cy="4.23333" r="4.23333" id="mdi-close-normal"></circle></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 656 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.4666665 8.4666666" version="1.1" id="svg4249" inkscape:export-filename="../../png/minimize/minimize_3.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" sodipodi:docname="minimize_3.svg" fill="#f0fc52">
<sodipodi:namedview id="namedview4251" pagecolor="#505050" bordercolor="#ffffff" borderopacity="1" inkscape:showpageshadow="0" inkscape:pageopacity="0" inkscape:pagecheckerboard="1" inkscape:deskcolor="#505050" inkscape:document-units="mm" showgrid="false" inkscape:zoom="5.6568543" inkscape:cx="31.643028" inkscape:cy="18.384776" inkscape:window-width="1260" inkscape:window-height="724" inkscape:window-x="10" inkscape:window-y="66" inkscape:window-maximized="1" inkscape:current-layer="layer1"/>
<defs id="defs4246"/>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1">
<path id="mdi-close-normal" style="fill: #f0fc52;fill-rule:evenodd;stroke-width:0.264583;paint-order:normal;fill-opacity:1" d="M 4.2333333 0 A 4.2333331 4.2333331 0 0 0 0 4.2333333 A 4.2333331 4.2333331 0 0 0 4.2333333 8.4666667 A 4.2333331 4.2333331 0 0 0 8.4666667 4.2333333 A 4.2333331 4.2333331 0 0 0 4.2333333 0 z M 1.6810343 3.8137207 L 6.7856323 3.8137207 C 6.98317 3.8137207 7.1447835 3.9997533 7.1447835 4.2276489 L 7.1447835 4.2390177 C 7.1447835 4.4669017 6.98317 4.652946 6.7856323 4.652946 L 1.6810343 4.652946 C 1.4834557 4.652946 1.3218831 4.4669017 1.3218831 4.2390177 L 1.3218831 4.2276489 C 1.3218831 3.9997533 1.4834557 3.8137207 1.6810343 3.8137207 z "/>
<path style="fill: #f0fc52;fill-opacity:1;stroke-width:0.264583" d="M 10.768947,5.8246909 10.743132,3.2134246" id="path7007"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#6394ed" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0,0.00001) scale(30.23622,30.23622)"><g id="layer1"><circle cx="4.23333" cy="4.23333" r="4.23333" id="mdi-close-normal"></circle></g></g></g></svg>

After

Width:  |  Height:  |  Size: 604 B

View file

@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0,0,256,256"><g fill="#404358" fill-rule="evenodd" stroke="none" stroke-width="0.26458" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="translate(0,0.00001) scale(30.23622,30.23622)"><g id="layer1"><circle cx="4.23333" cy="4.23333" r="4.23333" id="mdi-close-normal"></circle></g></g></g></svg>

After

Width:  |  Height:  |  Size: 604 B

View file

@ -0,0 +1,85 @@
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local dpi = beautiful.xresources.apply_dpi
local theme = beautiful.get()
-- Creating Calendar
----------------------
-- copied from awesome doc and adjusted a bit
local styles = {}
styles.month = { bg_color = theme.color.surface0 }
styles.normal = {
bg_color = theme.color.surface0,
padding = dpi(6),
fg_color = theme.color.subtext1,
}
styles.focus = {
fg_color = theme.color.yellow,
padding = dpi(6),
markup = function(t)
return "<b>" .. t .. "</b>"
end,
}
styles.header = {
fg_color = theme.color.blue,
markup = function(t)
return "<b>" .. t .. "</b>"
end,
}
styles.weekday = {
fg_color = theme.color.subtext1,
markup = function(t)
local f = helpers.ui.set_font("16")
return '<span font_desc="' .. f .. '">' .. t .. "</span>"
end,
}
-- The Function
local function decorate_cell(widget, flag)
if flag == "monthheader" and not styles.monthheader then
flag = "header"
end
local props = styles[flag] or {}
if props.markup and widget.get_text and widget.set_markup then
widget:set_markup(props.markup(widget:get_text()))
end
-- Change bg color for weekends
local ret = wibox.widget({
{
widget,
margins = props.padding,
widget = wibox.container.margin,
},
fg = props.fg_color,
bg = props.bg_color,
widget = wibox.container.background,
})
return ret
end
local calendar = wibox.widget({
date = os.date("*t"),
font = helpers.ui.set_font("14"),
fn_embed = decorate_cell,
widget = wibox.widget.calendar.month,
})
return wibox.widget({
nil,
{
nil,
calendar,
expand = "none",
layout = wibox.layout.align.horizontal,
},
expand = "none",
layout = wibox.layout.align.vertical,
})

View file

@ -0,0 +1,121 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local rubato = require("lib.rubato")
local dpi = beautiful.xresources.apply_dpi
local theme = beautiful.get()
-- Var
local width = dpi(410)
local height = awful.screen.focused().geometry.height - dpi(100)
-- Helper
-----------
local function round_widget(radius)
return function(cr, w, h)
gears.shape.rounded_rect(cr, w, h, radius)
end
end
local function box_widget(widgets, _width, _height)
return wibox.widget({
{
{
widgets,
margins = dpi(16),
widget = wibox.container.margin,
},
forced_width = dpi(_width),
forced_height = dpi(_height),
shape = round_widget(8),
bg = theme.bg_focus, --for widget Rounded and Border
widget = wibox.container.background,
},
margins = { left = dpi(20), right = dpi(20) },
widget = wibox.container.margin,
})
end
-- Get widgets
local weather_widget = require("ui.info-panel.weather")
local profile_widget = require("ui.info-panel.profile")
local calendar_widget = require("ui.info-panel.calendar")
local music_widget = require("ui.info-panel.music-player")
-- Combine some widgets
local weather = box_widget(weather_widget, 380, 180)
local profile = box_widget(profile_widget, 380, 210)
local calendar = box_widget(calendar_widget, 380, 340)
-- Sidebar
local sidebar = wibox({
visible = false,
ontop = true,
width = width,
height = height,
y = dpi(60),
bg = theme.bg_normal,
border_width = theme.border_width * 2,
border_color = theme.border_normal,
})
-- Sidebar widget setup
sidebar:setup({
{
profile,
music_widget,
weather,
calendar,
spacing = dpi(20),
layout = wibox.layout.fixed.vertical,
},
margins = { top = dpi(20), bottom = dpi(20) },
widget = wibox.container.margin,
})
-- Slide animation
local slide = rubato.timed({
pos = awful.screen.focused().geometry.x - sidebar.width,
rate = 60,
intro = 0.2,
duration = 0.4,
subscribed = function(pos)
sidebar.x = awful.screen.focused().geometry.x + pos
end,
})
-- Timer of sidebar's death
sidebar.timer = gears.timer({
timeout = 0.5,
single_shot = true,
callback = function()
sidebar.visible = not sidebar.visible
end,
})
sidebar.shape = function(cr, w, h) --Rounded Corners
gears.shape.rounded_rect(cr, w, h, 14)
end
-- Toggle function
sidebar.toggle = function()
if sidebar.visible then
slide.target = awful.screen.focused().geometry.x - sidebar.width
sidebar.timer:start()
else
awesome.emit_signal("widget::update_uptime")
slide.target = awful.screen.focused().geometry.x + dpi(20)
sidebar.visible = not sidebar.visible
end
end
-- Get signal to execute the function (if that makes sense)
awesome.connect_signal("sidebar::toggle", function()
sidebar.toggle()
end)
return sidebar

View file

@ -0,0 +1,256 @@
local awful = require("awful")
local gears = require("gears")
local beautiful = require("beautiful")
local wibox = require("wibox")
local helpers = require("helpers")
local playerctl_daemon = require("signals.playerctl")
local config = require("config")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
---- Music Player
---- ~~~~~~~~~~~~
local music_text = wibox.widget({
font = helpers.ui.set_font("Medium 10"),
valign = "center",
widget = wibox.widget.textbox,
})
local music_art = wibox.widget({
image = theme.music,
resize = true,
widget = wibox.widget.imagebox,
})
local music_art_container = wibox.widget({
music_art,
forced_height = dpi(200),
forced_width = dpi(200),
widget = wibox.container.background,
})
local filter_color = {
type = "linear",
from = { 0, 0 },
to = { 0, 160 },
stops = { { 0, theme.color.surface0 .. "cc" }, { 1, theme.color.surface0 } },
}
local music_art_filter = wibox.widget({
{
bg = filter_color,
forced_height = dpi(120),
forced_width = dpi(120),
widget = wibox.container.background,
},
direction = "east",
widget = wibox.container.rotate,
})
local music_title = wibox.widget({
font = helpers.ui.set_font("Regular 13"),
valign = "center",
widget = wibox.widget.textbox,
})
local music_artist = wibox.widget({
font = helpers.ui.set_font("Bold 16"),
valign = "center",
widget = wibox.widget.textbox,
})
--- Volume Control
local function volume_control()
local volume_bar = wibox.widget({
max_value = 100,
value = 100,
bar_height = dpi(12),
bar_width = dpi(4),
shape = helpers.ui.rrect(6),
bar_shape = helpers.ui.rrect(6),
color = theme.color.blue,
background_color = theme.color.surface0,
border_width = 0,
widget = wibox.widget.progressbar,
})
-- Update bar
local function set_slider_value(_, volume)
volume_bar.value = volume * 100
end
playerctl_daemon:connect_signal("volume", set_slider_value)
volume_bar:connect_signal("button::press", function()
playerctl_daemon:disconnect_signal("volume", set_slider_value)
end)
volume_bar:connect_signal("button::release", function()
playerctl_daemon:connect_signal("volume", set_slider_value)
end)
local volume = wibox.widget({
volume_bar,
direction = "east",
widget = wibox.container.rotate,
})
volume:buttons(gears.table.join(
-- Scroll - Increase or decrease volume
awful.button({}, 4, function()
awful.spawn.with_shell("playerctl volume 0.05+")
end),
awful.button({}, 5, function()
awful.spawn.with_shell("playerctl volume 0.05-")
end)
))
return volume
end
-- Player's Button
local toggle = wibox.widget.textbox()
toggle.font = helpers.ui.set_font("26")
toggle:buttons(gears.table.join(awful.button({}, 1, function()
playerctl_daemon:play_pause()
end)))
local next = wibox.widget.textbox()
next.font = helpers.ui.set_font("26")
next.markup = config.icons.music.next
next:buttons(gears.table.join(awful.button({}, 1, function()
playerctl_daemon:next()
end)))
local back = wibox.widget.textbox()
back.font = helpers.ui.set_font("26")
back.markup = config.icons.music.prev
back:buttons(gears.table.join(awful.button({}, 1, function()
playerctl_daemon:previous()
end)))
local function music()
return wibox.widget({
{
{
music_art_container,
music_art_filter,
layout = wibox.layout.stack,
},
{
{
{
music_text,
helpers.ui.vertical_pad(dpi(15)),
{
{
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
fps = 60,
speed = 75,
music_artist,
},
{
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
fps = 60,
speed = 75,
music_title,
},
forced_width = dpi(170),
layout = wibox.layout.fixed.vertical,
},
layout = wibox.layout.fixed.vertical,
},
nil,
{
{
back,
toggle,
next,
spacing = dpi(25),
layout = wibox.layout.fixed.horizontal,
},
forced_height = dpi(70),
top = dpi(10),
bottom = dpi(10),
right = dpi(10),
left = dpi(115),
widget = wibox.container.margin,
},
expand = "none",
layout = wibox.layout.align.vertical,
},
top = dpi(9),
bottom = dpi(9),
left = dpi(10),
right = dpi(10),
widget = wibox.container.margin,
},
layout = wibox.layout.stack,
},
forced_width = dpi(350),
shape = helpers.ui.prrect(8, false, true, true, false),
bg = theme.color.surface0,
widget = wibox.container.background,
})
end
local music_widget = wibox.widget({
{
{
music(),
{
volume_control(),
margins = { top = dpi(0), bottom = dpi(0), left = dpi(10), right = dpi(10) },
widget = wibox.container.margin,
},
layout = wibox.layout.align.horizontal,
},
forced_height = dpi(150),
bg = theme.color.base,
shape = helpers.ui.rrect(8),
widget = wibox.container.background,
},
left = dpi(20),
right = dpi(10),
color = "#FF000000",
widget = wibox.container.margin,
})
--- playerctl
--- -------------
playerctl_daemon:connect_signal("metadata", function(_, title, artist, album_path, _, _, _)
if title == "" then
title = "Nothing Playing"
end
if artist == "" then
artist = "Nothing Playing"
end
if album_path == "" then
album_path = theme.music
end
music_art:set_image(gears.surface.load_uncached(album_path))
music_title:set_markup_silently(helpers.ui.colorize_text(title, theme.color.subtext1))
music_artist:set_markup_silently(helpers.ui.colorize_text(artist, theme.color.blue))
end)
playerctl_daemon:connect_signal("playback_status", function(_, playing, _)
if playing then
music_text:set_markup_silently(helpers.ui.colorize_text("Now Playing", theme.color.overlay0))
toggle.markup = helpers.ui.colorize_text(config.icons.music.pause, theme.color.blue)
else
music_text:set_markup_silently(helpers.ui.colorize_text("Music", theme.color.overlay0))
toggle.markup = helpers.ui.colorize_text(config.icons.music.play, theme.color.blue)
end
end)
return music_widget

View file

@ -0,0 +1,116 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local config = require("config")
local dpi = beautiful.xresources.apply_dpi
-- Make Widgets
-----------------
-- Song's Title
local title = wibox.widget.textbox()
title.font = helpers.ui.set_font("Medium 16")
title.halign = "left"
title.valign = "bottom"
-- Song's Artist
local artist = wibox.widget.textbox()
artist.font = helpers.ui.set_font("Regular 16")
artist.halign = "left"
artist.valign = "bottom"
-- Song's Length
local length = wibox.widget.textbox()
length.font = helpers.ui.set_font("Regular 14")
length.halign = "center"
length.valign = "center"
-- Player's Button
local toggle = wibox.widget.textbox()
toggle.font = helpers.ui.set_font("26")
toggle:buttons(gears.table.join(awful.button({}, 1, function()
awful.spawn("mpc toggle", false)
if toggle.markup:match("󰏤") then
toggle.markup = config.icons.music.play
else
toggle.markup = config.icons.music.pause
end
end)))
local next = wibox.widget.textbox()
next.font = helpers.ui.set_font("26")
next.markup = config.icons.music.next
next:buttons(gears.table.join(awful.button({}, 1, function()
awful.spawn("mpc next", false)
end)))
local back = wibox.widget.textbox()
back.font = helpers.ui.set_font("26")
back.markup = config.icons.music.prev
back:buttons(gears.table.join(awful.button({}, 1, function()
awful.spawn("mpc prev", false)
end)))
-- Get data
awesome.connect_signal("signal::player", function(t, a, l, s)
if not s:match("playing") then
toggle.markup = config.icons.music.play
else
toggle.markup = config.icons.music.pause
end
title.markup = t
artist.markup = a
length.markup = l
end)
-- Grouping Widgets
---------------------
local buttons = wibox.widget({
back,
toggle,
next,
spacing = dpi(11),
layout = wibox.layout.fixed.horizontal,
})
return wibox.widget({
{
nil,
{
title,
artist,
spacing = dpi(12),
layout = wibox.layout.fixed.vertical,
},
expand = "none",
layout = wibox.layout.align.vertical,
},
{
nil,
nil,
{
length,
{
nil,
buttons,
expand = "none",
layout = wibox.layout.align.horizontal,
},
spacing = dpi(6),
layout = wibox.layout.fixed.vertical,
},
top = dpi(30),
bottom = 0,
layout = wibox.container.margin,
},
layout = wibox.layout.flex.horizontal,
})

View file

@ -0,0 +1,179 @@
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local beautiful = require("beautiful")
local helpers = require("helpers")
local config = require("config")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local os_user = os.getenv("USER")
if not os_user then
os_user = "user"
end
-- Create Widgets
-------------------
-- Pfp
local pfp = wibox.widget.imagebox()
pfp.image = require("config").theme.pfp
pfp.clip_shape = gears.shape.circle
pfp.forced_width = dpi(130)
pfp.forced_height = dpi(130)
-- User
local user = wibox.widget.textbox()
user.font = helpers.ui.set_font("SemiBold 18")
user.halign = "left"
user.markup = helpers.ui.colorize_text(os_user, theme.fg_normal)
-- Hostname
local hostname = wibox.widget.textbox()
hostname.font = helpers.ui.set_font("Regular 14")
hostname.halign = "left"
awful.spawn.easy_async_with_shell("hostnamectl --static", function(stdout)
hostname.markup = helpers.ui.colorize_text("@" .. tostring(stdout), theme.color.lavender)
end)
-- Battery
local uptimeosd = wibox.widget.textbox()
uptimeosd.font = helpers.ui.set_font("12")
uptimeosd.halign = "center"
-- Get data 4 widgets!
awesome.connect_signal("signal::uptime", function(uptime)
uptimeosd.markup = helpers.ui.colorize_text("up " .. uptime, theme.fg_normal)
end)
-- Spacing horizontally
local shutdown = wibox.widget({
{
{
font = helpers.ui.set_font("30"),
markup = helpers.ui.colorize_text(config.icons.power, theme.color.red),
halign = "center",
valign = "center",
widget = wibox.widget.textbox,
},
top = dpi(9),
bottom = dpi(9),
left = dpi(11),
right = dpi(11),
widget = wibox.container.margin,
},
bg = theme.color.surface1,
shape = helpers.ui.rrect(8),
widget = wibox.container.background,
})
local reboot = wibox.widget({
{
{
font = helpers.ui.set_font("30"),
markup = helpers.ui.colorize_text(config.icons.restart, theme.color.blue),
halign = "center",
valign = "center",
widget = wibox.widget.textbox,
},
top = dpi(9),
bottom = dpi(9),
left = dpi(11),
right = dpi(11),
widget = wibox.container.margin,
},
bg = theme.color.surface1,
shape = helpers.ui.rrect(8),
widget = wibox.container.background,
})
shutdown:connect_signal("mouse::enter", function()
shutdown.bg = theme.color.surface2
end)
shutdown:connect_signal("mouse::leave", function()
shutdown.bg = theme.color.surface1
end)
reboot:connect_signal("mouse::enter", function()
reboot.bg = theme.color.surface2
end)
reboot:connect_signal("mouse::leave", function()
reboot.bg = theme.color.surface1
end)
shutdown:buttons(gears.table.join(awful.button({}, 1, function()
awesome.emit_signal("module::exit_screen:show")
end)))
reboot:buttons(gears.table.join(awful.button({}, 1, function()
awful.spawn.with_shell("loginctl reboot")
end)))
-- Grouping widgets
---------------------
local buttons = wibox.widget({
{
reboot,
shutdown,
spacing = dpi(8),
layout = wibox.layout.fixed.horizontal,
},
top = dpi(10),
left = dpi(57),
widget = wibox.container.margin,
})
local name = wibox.widget({
{
user,
hostname,
spacing = dpi(4),
layout = wibox.layout.fixed.vertical,
},
left = 0,
widget = wibox.container.margin,
})
local uptimebox = wibox.widget({
{
{
uptimeosd,
spacing = dpi(2),
layout = wibox.layout.fixed.vertical,
},
top = dpi(3),
bottom = dpi(3),
widget = wibox.container.margin,
},
bg = theme.color.surface0,
shape = helpers.ui.rrect(7),
widget = wibox.container.background,
})
-- The Profile Widget
return wibox.widget({
{
{
pfp,
uptimebox,
spacing = dpi(20),
layout = wibox.layout.fixed.vertical,
},
layout = wibox.layout.fixed.vertical,
},
{
{
name,
buttons,
layout = wibox.layout.fixed.vertical,
},
top = dpi(30),
layout = wibox.container.margin,
},
spacing = dpi(30),
layout = wibox.layout.fixed.horizontal,
})

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 1,8 C 1,11.866 4.134,15 8,15 9.9252,15 11.68,14.117 13,12.715 12.482,12.847 12.034,13 11.5,13 7.9101,13 5,10.09 5,6.5 5,4.267 6.1294,2.19 8,1 4.1145,1 1,4.134 1,8 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 6.9999991,-6.4999999e-8 V 2.085937 a 6,6 0 0 1 1,-0.085937 6,6 0 0 1 1,0.08984 V -6.4999999e-8 Z M 3.0507801,1.6367189 1.6367181,3.050781 3.1132801,4.527344 a 6,6 0 0 1 1.416016,-1.41211 z m 9.8984379,0 -1.476563,1.4765621 a 6,6 0 0 1 1.41211,1.416016 L 14.36328,3.050781 Z M 7.9999991,3 a 5,5 0 0 0 -5,5 5,5 0 0 0 5,5 A 5,5 0 0 0 12.999999,8 5,5 0 0 0 7.9999991,3 Z m -8,4 v 2 h 2.085937 a 6,6 0 0 1 -0.08594,-1 6,6 0 0 1 0.08984,-1 z M 13.914061,7 a 6,6 0 0 1 0.08594,1 6,6 0 0 1 -0.08984,1 h 2.08984 V 7 Z m -10.7988279,4.470703 -1.478515,1.478516 1.414062,1.414062 1.476563,-1.476562 a 6,6 0 0 1 -1.41211,-1.416016 z m 9.7714849,0.002 a 6,6 0 0 1 -1.416016,1.41211 l 1.478516,1.478515 1.414062,-1.414062 z M 6.9999991,13.910156 V 16 h 2 v -2.085938 a 6,6 0 0 1 -1,0.08594 6,6 0 0 1 -1,-0.08984 z"/>
</svg>

After

Width:  |  Height:  |  Size: 921 B

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 7.736,0.9962 C 4.9732,1.0977 2.4273,2.8008 1.4235,5.5587 0.89934,6.999 0.87974,8.501 1.2653,9.875 1.669,8.557 2.7497,7.542 4.1032,7.192 4.2732,6.9013 4.4747,6.6319 4.693,6.3791 4.7035,5.6688 4.8234,4.9505 5.0797,4.2462 5.5939,2.8336 6.5542,1.7379 7.736,0.9962 Z M 8.086,5.7502 C 6.5323,5.7502 5.2096,6.7011 4.6403,8.047 3.1944,8.262 2.0856,9.494 2.0856,11 2.0856,12.657 3.4287,14 5.0856,14 H 11.461 C 12.91,14 14.086,12.825 14.086,11.375 14.086,10.028 13.073,8.924 11.765,8.774 11.424,7.054 9.906,5.7502 8.086,5.7502 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 966 B

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 7,0 V 2.0859375 A 6,6 0 0 1 8,2 6,6 0 0 1 9,2.089844 V 0 Z M 3.0507812,1.6367188 1.6367188,3.0507812 3.1132812,4.5273438 A 6,6 0 0 1 4.5292969,3.1152344 Z m 9.8984378,0 -1.476563,1.4765624 a 6,6 0 0 1 1.41211,1.4160157 L 14.363281,3.0507812 Z M 8,3 A 5,5 0 0 0 3,8 5,5 0 0 0 3.1464844,9.175781 c 0.0073,-0.0017 0.014172,-0.0042 0.021484,-0.0059 C 3.5797152,6.827355 5.5442774,5 8,5 c 2.072335,0.0018 3.855484,1.320297 4.595703,3.212891 0.134007,0.03469 0.263609,0.07922 0.392578,0.125 A 5,5 0 0 0 13,8 5,5 0 0 0 8,3 Z m 0,3 a 4,4 0 0 0 -4,4 3,3 0 0 0 -3,3 3,3 0 0 0 3,3 H 11.5 12 V 15.96094 A 3.5,3.5 0 0 0 15,12.5 3.5,3.5 0 0 0 11.875,9.021484 4,4 0 0 0 8,6 Z M 0,7 V 9 H 2.0859375 A 6,6 0 0 1 2,8 6,6 0 0 1 2.0898438,7 Z M 13.914062,7 A 6,6 0 0 1 14,8 6,6 0 0 1 13.910156,9 H 16 V 7 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 13.5,16 C 14.88,16 16,14.88 16,13.5 16,12.23 15.04,11.19 13.81,11.03 13.41,9.86 12.31,9 11,9 9.69,9 8.6,9.86 8.19,11.03 6.96,11.19 6,12.23 6,13.5 6,14.88 7.12,16 8.5,16"/>
<path style="fill:#dfdfdf" d="M 8,1 C 4.1145,0.999 1,4.134 1,8 1,10.841 2.6956,13.28 5.127,14.377 5.0526,14.095 5,13.804 5,13.5 5,12.309 5.6566,11.348 6.5957,10.758 5.6043,9.6168 5,8.1303 5,6.5 5.0014,4.267 6.1294,2.19 8,1 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 519 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 7 0 L 7 2.0859375 A 6 6 0 0 1 8 2 A 6 6 0 0 1 9 2.0898438 L 9 0 L 7 0 z M 3.0507812 1.6367188 L 1.6367188 3.0507812 L 3.1132812 4.5273438 A 6 6 0 0 1 4.5292969 3.1152344 L 3.0507812 1.6367188 z M 12.949219 1.6367188 L 11.472656 3.1132812 A 6 6 0 0 1 12.884766 4.5292969 L 14.363281 3.0507812 L 12.949219 1.6367188 z M 8 3 A 5 5 0 0 0 3 8 A 5 5 0 0 0 5.2949219 12.205078 C 5.713317 11.305716 6.5416242 10.637052 7.5234375 10.322266 C 8.1696152 9.0017204 9.4227843 8 11 8 C 11.732994 8 12.393594 8.2229024 12.958984 8.5878906 A 5 5 0 0 0 13 8 A 5 5 0 0 0 8 3 z M 0 7 L 0 9 L 2.0859375 9 A 6 6 0 0 1 2 8 A 6 6 0 0 1 2.0898438 7 L 0 7 z M 13.914062 7 A 6 6 0 0 1 14 8 A 6 6 0 0 1 13.910156 9 L 16 9 L 16 7 L 13.914062 7 z M 11 9 C 9.69 9 8.5994531 9.8592969 8.1894531 11.029297 C 6.9594531 11.189297 6 12.23 6 13.5 C 6 14.88 7.12 16 8.5 16 L 13.5 16 C 14.88 16 16 14.88 16 13.5 C 16 12.23 15.040547 11.189297 13.810547 11.029297 C 13.410547 9.8592969 12.31 9 11 9 z M 3.1152344 11.470703 L 1.6367188 12.949219 L 3.0507812 14.363281 L 4.5273438 12.886719 A 6 6 0 0 1 3.1152344 11.470703 z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="opacity:0.3;fill:#dfdfdf" d="M 2 1 C 1.446 1 1 1.446 1 2 C 1 2.554 1.446 3 2 3 L 8 3 C 8.554 3 9 2.554 9 2 C 9 1.446 8.554 1 8 1 L 2 1 z M 5 5 C 4.446 5 4 5.446 4 6 C 4 6.554 4.446 7 5 7 L 15 7 C 15.554 7 16 6.554 16 6 C 16 5.446 15.554 5 15 5 L 5 5 z M 1 9 C 0.446 9 0 9.446 0 10 C 0 10.554 0.446 11 1 11 L 12 11 C 12.554 11 13 10.554 13 10 C 13 9.446 12.554 9 12 9 L 1 9 z M 3 13 C 2.446 13 2 13.446 2 14 C 2 14.554 2.446 15 3 15 L 15 15 C 15.554 15 16 14.554 16 14 C 16 13.446 15.554 13 15 13 L 3 13 z"/>
</svg>

After

Width:  |  Height:  |  Size: 607 B

View file

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.929,0 4.165,1.27 3.406,3.07 1.478,3.35 0,5 0,7 0,8.94 1.365,10.54 3.187,10.91 3.951,10.13 4.709,9.35 5.5,8.6 6.073,9.14 6.633,9.7 7.187,10.25 7.43,10.18 7.57,9.41 7.906,9.16 8.76,8.29 9.615,7.43 10.5,6.6 11.166,7.22 11.791,7.86 12.437,8.5 13.035,9.07 13.665,9.71 13.875,10.53 13.891,10.59 13.893,10.64 13.906,10.69 15.141,10.15 16,8.94 16,7.5 16,5.71 14.649,4.23 12.906,4.03 12.451,1.74 10.427,0 8,0 Z M 10.5,9.44 C 10.415,9.52 10.335,9.61 10.25,9.69 9.853,10.11 9.351,10.47 9.125,11 H 11.906 C 11.88,10.94 11.85,10.87 11.812,10.82 11.439,10.3 10.933,9.9 10.5,9.44 Z"/>
<path style="fill:currentColor" class="ColorScheme-Highlight" d="M 10.5,8 10.156,8.34 8.75,9.75 C 8.297,10.2 8,10.81 8,11.5 8,12.87 9.125,14 10.5,14 11.875,14 13,12.87 13,11.5 13,10.81 12.703,10.2 12.25,9.75 L 10.844,8.34 Z M 5.5,10 5.156,10.34 3.75,11.75 C 3.297,12.2 3,12.81 3,13.5 3,14.87 4.125,16 5.5,16 6.875,16 8,14.87 8,13.5 8,12.81 7.703,12.2 7.25,11.75 L 5.844,10.34 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 10,8 C 8.69,8 7.6,8.86 7.19,10.03 5.96,10.19 5,11.23 5,12.5 5,13.88 6.12,15 7.5,15 H 12.5 C 13.88,15 15,13.88 15,12.5 15,11.23 14.04,10.19 12.81,10.03 12.41,8.86 11.31,8 10,8 Z"/>
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.1702,1.2705 3.4102,3.0605 1.4802,3.3505 0,4.99 0,7 0,9.21 1.79,11 4,11 H 4.3945 C 4.8388,10.204 5.6169,9.6129 6.5234,9.3223 7.1696,8.0017 8.4228,7 10,7 11.573,7 12.83,7.9972 13.473,9.3203 13.983,9.4834 14.453,9.7437 14.848,10.08 15.551,9.4395 16,8.5242 16,7.5 16,5.7 14.65,4.2293 12.91,4.0293 12.45,1.7393 10.43,0 8,0 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 669 B

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,1 C 5.9289,1 4.1653,2.2679 3.4062,4.0625 1.4784,4.3491 0,5.9924 0,8 0,10.209 1.7909,12 4,12 H 4.4062 C 4.8601,11.199 5.6472,10.573 6.5312,10.313 7.151,8.99 8.506,7.974 10,8 11.908,7.969 13.582,9.485 13.875,11.344 14.018,11.389 14.144,11.435 14.281,11.5 15.312,10.891 16,9.784 16,8.5 16,6.7035 14.649,5.2313 12.906,5.0312 12.452,2.7379 10.427,1 8,1 Z M 10,9 C 8.688,9 7.595,9.858 7.188,11.031 5.9567,11.187 5,12.227 5,13.5 5,14.881 6.1193,16 7.5,16 H 13 C 14.105,16 15,15.105 15,14 15,12.895 14.105,12 13,12 13,10.343 11.657,9 10,9 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 982 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#ff9800" class="warning" d="M 7,6 V 10 L 7.25,12 H 8.75 L 9,10 V 6 Z M 7,13 V 15 H 9 V 13 Z"/>
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.06 1.48,3.35 0,5 0,7 0,9.21 1.79,11 4,11 H 6 V 5 H 10 V 11 H 12.5 C 14.43,11 16,9.43 16,7.5 16,5.7 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 411 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.06 1.48,3.35 0,4.99 0,7 0,7.73 0.2,8.41 0.54,9 H 0.52 C 1.08,9.97 2.04,10.68 3.17,10.91 L 5.5,8.58 7.25,10.33 C 7.43,9.84 7.69,9.39 8.04,9.04 L 10.5,6.58 12.96,9.04 C 13.4,9.48 13.73,10.05 13.89,10.69 H 13.91 V 10.69 L 13.92,10.68 H 13.93 L 13.94,10.67 C 15.16,10.12 16,8.92 16,7.5 16,5.7 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
<path style="fill:#dfdfdf" d="M 10.5,8 8.75,9.75 C 8.3,10.2 8,10.81 8,11.5 8,12.87 9.13,14 10.5,14 11.87,14 13,12.87 13,11.5 13,10.81 12.7,10.2 12.25,9.75 Z M 5.5,10 3.75,11.75 C 3.3,12.2 3,12.81 3,13.5 3,14.87 4.13,16 5.5,16 6.87,16 8,14.87 8,13.5 8,12.81 7.7,12.2 7.25,11.75 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 770 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.06 1.48,3.35 0,4.99 0,7 0,9.21 1.79,11 4,11 H 12.5 C 14.43,11 16,9.43 16,7.5 16,5.7 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
<path style="fill:#dfdfdf" d="M 2.9766,11.994 A 0.5,0.5 0 0 0 2.5527,12.277 L 1.5527,14.277 A 0.5,0.5 0 1 0 2.4473,14.723 L 3.4473,12.723 A 0.5,0.5 0 0 0 2.9766,11.994 Z M 5.4766,11.994 A 0.5,0.5 0 0 0 5.0527,12.277 L 4.0527,14.277 A 0.5,0.5 0 1 0 4.9473,14.723 L 5.9473,12.723 A 0.5,0.5 0 0 0 5.4766,11.994 Z M 7.9766,11.994 A 0.5,0.5 0 0 0 7.5527,12.277 L 6.5527,14.277 A 0.5,0.5 0 1 0 7.4473,14.723 L 8.4473,12.723 A 0.5,0.5 0 0 0 7.9766,11.994 Z M 10.477,11.994 A 0.5,0.5 0 0 0 10.053,12.277 L 9.0527,14.277 A 0.5,0.5 0 1 0 9.9473,14.723 L 10.947,12.723 A 0.5,0.5 0 0 0 10.477,11.994 Z M 12.977,11.994 A 0.5,0.5 0 0 0 12.553,12.277 L 11.553,14.277 A 0.5,0.5 0 1 0 12.447,14.723 L 13.447,12.723 A 0.5,0.5 0 0 0 12.977,11.994 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1,016 B

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0.004 C 5.9289,0.004 4.1653,1.2719 3.4062,3.0665 1.4784,3.3531 0,4.9964 0,7.004 0,9.213 1.7909,11.004 4,11.004 H 12.5 C 14.433,11.004 16,9.437 16,7.504 16,5.7075 14.649,4.2353 12.906,4.0353 12.452,1.7419 10.427,0.004 8,0.004 Z M 3.4785,11.992 A 0.50005,0.50005 0 0 0 3.0527,12.275 L 2.0527,14.275 A 0.50025,0.50025 0 0 0 2.9473,14.723 L 3.9473,12.723 A 0.50005,0.50005 0 0 0 3.4785,11.992 Z M 6.4785,11.994 A 0.50005,0.50005 0 0 0 6.0527,12.277 L 5.0527,14.277 A 0.50025,0.50025 0 1 0 5.9473,14.725 L 6.9473,12.725 A 0.50005,0.50005 0 0 0 6.4785,11.994 Z M 11,12 A 1,1 0 0 0 10,13 1,1 0 0 0 11,14 1,1 0 0 0 12,13 1,1 0 0 0 11,12 Z M 9,14 A 1,1 0 0 0 8,15 1,1 0 0 0 9,16 1,1 0 0 0 10,15 1,1 0 0 0 9,14 Z M 13,14 A 1,1 0 0 0 12,15 1,1 0 0 0 13,16 1,1 0 0 0 14,15 1,1 0 0 0 13,14 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.9289,0 4.1653,1.2679 3.4062,3.0625 1.4784,3.3491 0,4.9924 0,7 0,9.209 1.7909,11 4,11 H 5.1855 C 5.6024,9.842 6.7062,9 8,9 9.294,9 10.398,9.842 10.814,11 H 12.5 C 14.433,11 16,9.433 16,7.5 16,5.7035 14.649,4.2313 12.906,4.0312 12.452,1.7379 10.427,0 8,0 Z M 8,10 A 2,2 0 0 0 6,12 2,2 0 0 0 8,14 2,2 0 0 0 10,12 2,2 0 0 0 8,10 Z M 3,12 A 2,2 0 0 0 1,14 2,2 0 0 0 3,16 2,2 0 0 0 5,14 2,2 0 0 0 3,12 Z M 13,12 A 2,2 0 0 0 11,14 2,2 0 0 0 13,16 2,2 0 0 0 15,14 2,2 0 0 0 13,12 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 929 B

View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0.004 C 5.9289,0.004 4.1653,1.2719 3.4062,3.0665 1.4784,3.3531 0,4.9964 0,7.004 0,9.213 1.7909,11.004 4,11.004 H 12.5 C 14.433,11.004 16,9.437 16,7.504 16,5.7075 14.649,4.2353 12.906,4.0353 12.452,1.7419 10.427,0.004 8,0.004 Z M 4,12 A 1,1 0 0 0 3,13 1,1 0 0 0 4,14 1,1 0 0 0 5,13 1,1 0 0 0 4,12 Z M 8,12 A 1,1 0 0 0 7,13 1,1 0 0 0 8,14 1,1 0 0 0 9,13 1,1 0 0 0 8,12 Z M 12,12 A 1,1 0 0 0 11,13 1,1 0 0 0 12,14 1,1 0 0 0 13,13 1,1 0 0 0 12,12 Z M 2,14 A 1,1 0 0 0 1,15 1,1 0 0 0 2,16 1,1 0 0 0 3,15 1,1 0 0 0 2,14 Z M 6,14 A 1,1 0 0 0 5,15 1,1 0 0 0 6,16 1,1 0 0 0 7,15 1,1 0 0 0 6,14 Z M 10,14 A 1,1 0 0 0 9,15 1,1 0 0 0 10,16 1,1 0 0 0 11,15 1,1 0 0 0 10,14 Z M 14,14 A 1,1 0 0 0 13,15 1,1 0 0 0 14,16 1,1 0 0 0 15,15 1,1 0 0 0 14,14 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.07 1.48,3.35 0,5 0,7 0,9.21 1.79,11 4,11 L 6,11 6,8.5 C 6,7.67 6.67,7 7.5,7 8.33,7 9,7.67 9,8.5 l 0,2.5 3.5,0 C 14.43,11 16,9.44 16,7.5 16,5.71 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
<path style="fill:currentColor" class="ColorScheme-Highlight" d="m 7.34,8.029287 c -0.2,0.07 -0.35,0.28 -0.34,0.5 l 0,3.78 -0.03,0.09 -0.63,0.63 -0.03,0 -1.81,0 -0.22,0 -0.12,0.16 -1,1 c -0.26,0.15 -0.31,0.56 -0.1,0.78 0.22,0.21 0.63,0.16 0.78,-0.1 l 0.85,-0.84 1.31,0 0,1.4 c 0,0.26 0.24,0.51 0.5,0.51 0.26,0 0.5,-0.25 0.5,-0.51 l 0,-1.71 0.69,-0.69 2.12,0 0.75,0.75 -1.4,1.31 c -0.26,0.15 -0.31,0.56 -0.1,0.78 0.22,0.21 0.63,0.16 0.78,-0.1 l 1.41,-1.3 1.41,1.3 c 0.15,0.26 0.56,0.31 0.78,0.1 0.21,-0.22 0.16,-0.63 -0.1,-0.78 l -3,-2.9 -0.12,-0.16 -0.22,0 -2,0 0,-3.5 c 0,-0.3 -0.3,-0.56 -0.59,-0.5 z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 8,16 C 8,16 7,16 7,15 7,14 8,14 8,14 8,14 9,14 9,13 9,12 8,12 8,12 H 1 C 1,12 0,12 0,11 0,10 1,10 1,10 H 8 C 8,10 11,10 11,13 11,16 8,16 8,16 Z M 13,3 C 13,3 12,3 12,4 12,5 13,5 13,5 13,5 14,5 14,6 14,7 13,7 13,7 H 5 C 5,7 4,7 4,8 4,9 5,9 5,9 H 13 C 13,9 16,9 16,6 16,3 13,3 13,3 Z M 8,0 C 8,0 7,0 7,1 7,2 8,2 8,2 8,2 9,2 9,3 9,4 8,4 8,4 H 1 C 1,4 0,4 0,5 0,6 1,6 1,6 H 8 C 8,6 11,6 11,3 11,0 8,0 8,0 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 524 B

View file

@ -0,0 +1,229 @@
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local beautiful = require("beautiful")
local json = require("lib.json")
local helpers = require("helpers")
local config = require("config").widget.weather
local dpi = beautiful.xresources.apply_dpi
local icon_dir = gears.filesystem.get_configuration_dir() .. "ui/info-panel/weather/icons/"
--- Weather Widget
--- ~~~~~~~~~~~~~~
local GET_FORECAST_CMD = [[bash -c "curl -s --show-error -X GET '%s'"]]
local icon_map = {
["01d"] = "weather-clear-sky",
["02d"] = "weather-few-clouds",
["03d"] = "weather-clouds",
["04d"] = "weather-few-clouds",
["09d"] = "weather-showers-scattered",
["10d"] = "weather-showers",
["11d"] = "weather-strom",
["13d"] = "weather-snow",
["50d"] = "weather-fog",
["01n"] = "weather-clear-night",
["02n"] = "weather-few-clouds-night",
["03n"] = "weather-clouds-night",
["04n"] = "weather-clouds-night",
["09n"] = "weather-showers-scattered",
["10n"] = "weather-showers",
["11n"] = "weather-strom",
["13n"] = "weather-snow",
["50n"] = "weather-fog",
}
local current_weather_widget = wibox.widget({
{
{
id = "icon",
image = icon_dir .. "weather-showers.svg",
resize = true,
forced_height = dpi(42),
forced_width = dpi(42),
widget = wibox.widget.imagebox,
},
{
{
{
id = "description",
text = "Mostly cloudy",
font = helpers.ui.set_font("Bold 10"),
widget = wibox.widget.textbox,
},
{
id = "humidity",
text = "Humidity: 80%",
font = helpers.ui.set_font("9"),
widget = wibox.widget.textbox,
},
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.place,
},
spacing = dpi(10),
layout = wibox.layout.fixed.horizontal,
},
nil,
{
{
{
id = "temp_current",
markup = "20<sup><span>°</span></sup>",
halign = "right",
font = helpers.ui.set_font("Bold 16"),
widget = wibox.widget.textbox,
},
{
id = "feels_like",
markup = "Feels like: 19<sup><span>°</span></sup>",
font = helpers.ui.set_font("8"),
widget = wibox.widget.textbox,
},
spacing = dpi(-6),
layout = wibox.layout.fixed.vertical,
},
widget = wibox.container.place,
},
layout = wibox.layout.align.horizontal,
})
local hourly_widget = function()
local widget = wibox.widget({
{
{
id = "time",
text = "12PM",
font = helpers.ui.set_font("9"),
widget = wibox.widget.textbox,
},
widget = wibox.container.place,
},
{
{
id = "icon",
image = icon_dir .. "weather-clear-sky.svg",
resize = true,
forced_height = dpi(16),
forced_width = dpi(16),
widget = wibox.widget.imagebox,
},
widget = wibox.container.place,
},
{
{
id = "temp",
markup = "1<sup><span>°</span></sup>",
font = helpers.ui.set_font("9"),
widget = wibox.widget.textbox,
},
widget = wibox.container.place,
},
spacing = dpi(6),
layout = wibox.layout.fixed.vertical,
})
widget.update = function(result)
local time = widget:get_children_by_id("time")[1]
local icon = widget:get_children_by_id("icon")[1]
local temp = widget:get_children_by_id("temp")[1]
temp:set_markup(math.floor(result.temp) .. "<sup><span>°</span></sup>")
time:set_text(os.date("%I%p", tonumber(result.dt)))
icon.image = icon_dir .. icon_map[result.weather[1].icon] .. ".svg"
icon:emit_signal("widget::redraw_needed")
end
return widget
end
local hourly_widget_1 = hourly_widget()
local hourly_widget_2 = hourly_widget()
local hourly_widget_3 = hourly_widget()
local hourly_widget_4 = hourly_widget()
local hourly_widget_5 = hourly_widget()
local hourly_widget_6 = hourly_widget()
local weather_widget = wibox.widget({
{
text = "Weather",
font = helpers.ui.set_font("Bold 16"),
halign = "center",
widget = wibox.widget.textbox,
},
current_weather_widget,
{
hourly_widget_1,
hourly_widget_2,
hourly_widget_3,
hourly_widget_4,
hourly_widget_5,
hourly_widget_6,
spacing = dpi(10),
layout = wibox.layout.flex.horizontal,
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
})
local show_hourly_forecast = true
local show_daily_forecast = true
local url = (
"https://api.openweathermap.org/data/2.5/onecall"
.. "?lat="
.. config.coordinates.lat
.. "&lon="
.. config.coordinates.lon
.. "&appid="
.. config.api_key
.. "&units="
.. config.units
.. "&exclude=minutely"
.. (show_hourly_forecast == false and ",hourly" or "")
.. (show_daily_forecast == false and ",daily" or "")
)
awful.widget.watch(string.format(GET_FORECAST_CMD, url), 600, function(_, stdout, stderr)
if stderr == "" then
local result = json.decode(stdout)
if not result.current then
return
end
-- Current weather setup
local icon = current_weather_widget:get_children_by_id("icon")[1]
local description = current_weather_widget:get_children_by_id("description")[1]
local humidity = current_weather_widget:get_children_by_id("humidity")[1]
local temp_current = current_weather_widget:get_children_by_id("temp_current")[1]
local feels_like = current_weather_widget:get_children_by_id("feels_like")[1]
icon.image = icon_dir .. icon_map[result.current.weather[1].icon] .. ".svg"
icon:emit_signal("widget::redraw_needed")
description:set_text(result.current.weather[1].description:gsub("^%l", string.upper))
humidity:set_text("Humidity: " .. result.current.humidity .. "%")
temp_current:set_markup(math.floor(result.current.temp) .. "<sup><span>°</span></sup>")
feels_like:set_markup("Feels like: " .. math.floor(result.current.feels_like) .. "<sup><span>°</span></sup>")
-- Hourly widget setup
hourly_widget_1.update(result.hourly[1])
hourly_widget_2.update(result.hourly[2])
hourly_widget_3.update(result.hourly[3])
hourly_widget_4.update(result.hourly[4])
hourly_widget_5.update(result.hourly[5])
hourly_widget_6.update(result.hourly[6])
end
end)
return weather_widget

View file

@ -0,0 +1,5 @@
require("ui.popups")
require("ui.notif-panel")
require("ui.info-panel")
require("ui.top-panel")
require("ui.titlebar")

View file

@ -0,0 +1,334 @@
local gears = require("gears")
local awful = require("awful")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local naughty = require("naughty")
local rubato = require("lib.rubato")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local notifs_text = wibox.widget({
font = helpers.ui.set_font("Bold 20"),
markup = "Notifications",
halign = "center",
widget = wibox.widget.textbox,
})
local notifs_clear = wibox.widget({
markup = helpers.ui.colorize_text("", theme.color.red),
font = helpers.ui.set_font("Bold 21"),
halign = "center",
valign = "center",
widget = wibox.widget.textbox,
})
notifs_clear:buttons(gears.table.join(awful.button({}, 1, function()
_G.Notif_center_reset_notifs_container()
end)))
helpers.ui.add_hover_cursor(notifs_clear, "hand2")
local notifs_empty = wibox.widget({
{
nil,
{
nil,
{
markup = helpers.ui.colorize_text("Nothing Here!", theme.color.subtext1),
font = helpers.ui.set_font("Bold 17"),
halign = "center",
valign = "center",
widget = wibox.widget.textbox,
},
layout = wibox.layout.align.vertical,
},
layout = wibox.layout.align.horizontal,
},
forced_height = dpi(730),
widget = wibox.container.background,
bg = theme.color.surface0,
shape = helpers.ui.rrect(8),
})
local notifs_container = wibox.widget({
spacing = dpi(10),
spacing_widget = {
{
shape = helpers.ui.rrect(8),
widget = wibox.container.background,
},
top = dpi(2),
bottom = dpi(2),
left = dpi(6),
right = dpi(6),
widget = wibox.container.margin,
},
forced_width = dpi(320),
forced_height = dpi(730), --Use it like in notifs_empty else it will look weird
layout = wibox.layout.fixed.vertical,
})
local remove_notifs_empty = true
Notif_center_reset_notifs_container = function()
notifs_container:reset(notifs_container)
notifs_container:insert(1, notifs_empty)
remove_notifs_empty = true
end
Notif_center_remove_notif = function(box)
notifs_container:remove_widgets(box)
if #notifs_container.children == 0 then
notifs_container:insert(1, notifs_empty)
remove_notifs_empty = true
end
end
local create_notif = function(icon, n)
local time = os.date("%H:%M")
local box = {}
box = wibox.widget({
{
{
{
{
image = icon,
resize = true,
clip_shape = helpers.ui.rrect(8),
halign = "center",
valign = "center",
widget = wibox.widget.imagebox,
},
strategy = "exact",
height = dpi(50),
width = dpi(50),
widget = wibox.container.constraint,
},
{
{
nil,
{
{
{
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
speed = dpi(50),
{
markup = n.title,
font = helpers.ui.set_font("Bold 9"),
halign = "left",
widget = wibox.widget.textbox,
},
forced_width = dpi(140),
widget = wibox.container.scroll.horizontal,
},
nil,
{
markup = helpers.ui.colorize_text(time, theme.color.subtext1),
halign = "right",
valign = "bottom",
font = helpers.ui.set_font("Bold 10"),
widget = wibox.widget.textbox,
},
expand = "none",
layout = wibox.layout.align.horizontal,
},
{
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
speed = dpi(50),
{
markup = n.message,
halign = "left",
widget = wibox.widget.textbox,
},
forced_width = dpi(165),
widget = wibox.container.scroll.horizontal,
},
spacing = dpi(3),
layout = wibox.layout.fixed.vertical,
},
expand = "none",
layout = wibox.layout.align.vertical,
},
left = dpi(17),
widget = wibox.container.margin,
},
layout = wibox.layout.align.horizontal,
},
margins = dpi(15),
widget = wibox.container.margin,
},
forced_height = dpi(85),
widget = wibox.container.background,
bg = theme.color.surface0,
shape = helpers.ui.rrect(8),
})
box:buttons(gears.table.join(awful.button({}, 1, function()
_G.Notif_center_remove_notif(box)
end)))
return box
end
notifs_container:buttons(gears.table.join(
awful.button({}, 4, nil, function()
if #notifs_container.children == 1 then
return
end
notifs_container:insert(1, notifs_container.children[#notifs_container.children])
notifs_container:remove(#notifs_container.children)
end),
awful.button({}, 5, nil, function()
if #notifs_container.children == 1 then
return
end
notifs_container:insert(#notifs_container.children + 1, notifs_container.children[1])
notifs_container:remove(1)
end)
))
notifs_container:insert(1, notifs_empty)
naughty.connect_signal("request::display", function(n)
if #notifs_container.children == 1 and remove_notifs_empty then
notifs_container:reset(notifs_container)
remove_notifs_empty = false
end
local appicon = n.icon or n.app_icon
if not appicon then
appicon = theme.pfp --notification_icon
end
notifs_container:insert(1, create_notif(appicon, n))
end)
local notifs = wibox.widget({
{
{
{
nil,
notifs_text,
notifs_clear,
expand = "none",
layout = wibox.layout.align.horizontal,
},
left = dpi(5),
right = dpi(5),
top = dpi(7),
bottom = dpi(7),
layout = wibox.container.margin,
},
widget = wibox.container.background,
bg = theme.color.surface0,
shape = helpers.ui.rrect(8),
},
notifs_container,
spacing = dpi(20),
layout = wibox.layout.fixed.vertical,
})
local actions = wibox.widget({
{
{
{
widget = require("ui.notif-panel.widgets.vol_slider"),
},
{
widget = require("ui.notif-panel.widgets.mic_slider"),
},
layout = wibox.layout.flex.vertical,
spacing = dpi(1),
},
widget = wibox.container.margin,
top = dpi(20),
bottom = dpi(20),
left = dpi(35),
right = dpi(35),
},
forced_height = dpi(120),
widget = wibox.container.background,
bg = theme.color.surface0,
shape = helpers.ui.rrect(8),
})
-- Sidebar
local action = wibox({
visible = false,
ontop = true,
width = dpi(410),
height = awful.screen.focused().geometry.height - dpi(100),
y = dpi(60),
bg = theme.bg_normal,
border_width = theme.border_width * 2,
border_color = theme.border_normal,
})
-- Sidebar widget setup
action:setup({
{
notifs,
nil,
actions,
spacing = dpi(20),
layout = wibox.layout.align.vertical,
},
margins = {
top = dpi(20),
bottom = dpi(20),
left = dpi(20),
right = dpi(20),
},
widget = wibox.container.margin,
})
-- Slide animation
local slide = rubato.timed({
pos = awful.screen.focused().geometry.x - awful.screen.focused().geometry.width,
rate = 60,
intro = 0.2,
duration = 0.4,
subscribed = function(pos)
action.x = awful.screen.focused().geometry.x - pos
end,
})
-- Timer of action's death
action.timer = gears.timer({
timeout = 0.5,
single_shot = true,
callback = function()
action.visible = not action.visible
end,
})
action.shape = function(cr, w, h) --Rounded Corners
gears.shape.rounded_rect(cr, w, h, 14)
end
-- Toggle function
action.toggle = function()
if action.visible then
slide.target = awful.screen.focused().geometry.x - awful.screen.focused().geometry.width
action.timer:start()
else
awesome.emit_signal("widget::update_vol")
awesome.emit_signal("widget::update_mic")
slide.target = awful.screen.focused().geometry.x
- awful.screen.focused().geometry.width
+ action.width
+ dpi(25)
action.visible = not action.visible
end
end
-- Get signal to execute the function (if that makes sense)
awesome.connect_signal("action::toggle", function()
action.toggle()
end)
return action

View file

@ -0,0 +1,50 @@
local gears = require("gears")
local awful = require("awful")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local slider = wibox.widget({
bar_shape = helpers.ui.rrect(9),
bar_height = 6,
bar_color = theme.bg_focus,
bar_active_color = theme.color.yellow,
handle_shape = gears.shape.circle,
handle_color = theme.color.yellow,
handle_width = dpi(12),
value = dpi(25),
widget = wibox.widget.slider,
})
helpers.ui.add_hover_cursor(slider, "hand1")
local bri_slider = wibox.widget({
{
markup = helpers.ui.colorize_text("󰃞 ", theme.color.yellow),
font = helpers.ui.set_font("14"),
halign = "center",
valign = "center",
widget = wibox.widget.textbox(),
},
slider,
layout = wibox.layout.fixed.horizontal,
spacing = 0,
})
awful.spawn.easy_async_with_shell(
"brightnessctl | grep -i 'current' | awk '{ print $4}' | tr -d \"(%)\"",
function(stdout)
local value = string.gsub(stdout, "^%s*(.-)%s*$", "%1")
bri_slider.value = tonumber(value)
end
)
slider:connect_signal("property::value", function(_, new_value)
slider.value = new_value
awful.spawn("brightnessctl set " .. new_value .. "%", false)
end)
return bri_slider

View file

@ -0,0 +1,124 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local config = require("config")
local microphone = config.widget.mic.name
local slider = wibox.widget({
bar_shape = helpers.ui.rrect(9),
bar_height = dpi(6),
bar_color = theme.color.base,
bar_active_color = theme.color.blue,
handle_shape = gears.shape.circle,
handle_color = theme.color.blue,
handle_width = dpi(12),
value = dpi(75),
forced_width = dpi(239),
widget = wibox.widget.slider,
})
local osd_value = wibox.widget({
text = "0%",
font = helpers.ui.set_font("10"),
widget = wibox.widget.textbox(),
})
local icon = wibox.widget({
markup = helpers.ui.colorize_text("󰍬", theme.color.blue),
font = helpers.ui.set_font("14"),
halign = "center",
valign = "center",
widget = wibox.widget.textbox(),
})
local function get_val()
awesome.connect_signal("signal::mic", function(_, muted)
if muted then
icon.markup = helpers.ui.colorize_text("󰍭", theme.color.blue)
icon.font = helpers.ui.set_font("14")
else
icon.markup = helpers.ui.colorize_text("󰍬", theme.color.blue)
icon.font = helpers.ui.set_font("17")
end
end)
end
get_val()
icon:buttons(gears.table.join(awful.button({}, 1, function()
local script = "pamixer --source" .. microphone .. "-t"
awful.spawn(script, false)
awesome.emit_signal("widget::update_mic")
end)))
slider:buttons(gears.table.join(
awful.button({}, 4, nil, function()
if slider:get_value() > 100 then
slider:set_value(100)
return
end
slider:set_value(slider:get_value() + 5)
end),
awful.button({}, 5, nil, function()
if slider:get_value() < 0 then
slider:set_value(0)
return
end
slider:set_value(slider:get_value() - 5)
end)
))
helpers.ui.add_hover_cursor(slider, "hand1")
helpers.ui.add_hover_cursor(icon, "hand2")
local mic_slider = wibox.widget({
{
{
layout = wibox.layout.fixed.horizontal,
icon,
},
left = 0,
right = dpi(14),
top = dpi(5),
bottom = dpi(5),
layout = wibox.container.margin,
},
slider,
layout = wibox.layout.fixed.horizontal,
{
{
layout = wibox.layout.fixed.horizontal,
osd_value,
},
left = dpi(3),
right = 0,
top = 0,
bottom = 0,
layout = wibox.container.margin,
},
})
local update_microphone = function() -- Sets the Volume Correct
awful.spawn.easy_async_with_shell("pamixer --source " .. microphone .. " --get-volume", function(stdout)
slider.value = tonumber(stdout:match("%d+"))
end)
end
awesome.connect_signal("widget::update_mic", function()
update_microphone()
end)
slider:connect_signal("property::value", function(_, new_value)
awful.spawn("pamixer --source " .. microphone .. " --set-volume " .. new_value, false)
local volume_level = slider:get_value()
osd_value.text = volume_level .. "%"
end)
return mic_slider

View file

@ -0,0 +1,124 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local helpers = require("helpers")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local slider = wibox.widget({
bar_shape = helpers.ui.rrect(9),
bar_height = dpi(6),
bar_color = theme.color.base,
bar_active_color = theme.color.blue,
handle_shape = gears.shape.circle,
handle_color = theme.color.blue,
handle_width = dpi(12),
value = dpi(75),
forced_width = dpi(239),
widget = wibox.widget.slider,
})
local osd_value = wibox.widget({
text = "0%",
font = helpers.ui.set_font("10"),
widget = wibox.widget.textbox(),
})
local icon = wibox.widget({
markup = helpers.ui.colorize_text("󰕾 ", theme.color.blue),
font = helpers.ui.set_font("14"),
halign = "center",
valign = "center",
widget = wibox.widget.textbox(),
})
local function get_val()
awesome.connect_signal("signal::volume", function(_, muted)
if muted then
icon.markup = helpers.ui.colorize_text("󰖁", theme.color.blue)
else
icon.markup = helpers.ui.colorize_text("󰕾", theme.color.blue)
end
end)
end
get_val()
icon:buttons(gears.table.join(awful.button({}, 1, function()
local script = "pamixer -t"
awful.spawn(script, false)
awesome.emit_signal("widget::update_vol")
end)))
slider:buttons(gears.table.join(
awful.button({}, 4, nil, function()
if slider:get_value() > 100 then
slider:set_value(100)
return
end
slider:set_value(slider:get_value() + 5)
end),
awful.button({}, 5, nil, function()
if slider:get_value() < 0 then
slider:set_value(0)
return
end
slider:set_value(slider:get_value() - 5)
end)
))
helpers.ui.add_hover_cursor(slider, "hand1")
helpers.ui.add_hover_cursor(icon, "hand2")
local vol_slider = wibox.widget({
{
{
layout = wibox.layout.fixed.horizontal,
icon,
},
left = 0,
right = dpi(14),
top = dpi(5),
bottom = dpi(5),
layout = wibox.container.margin,
},
slider,
layout = wibox.layout.fixed.horizontal,
{
{
layout = wibox.layout.fixed.horizontal,
osd_value,
},
left = dpi(3),
right = 0,
top = 0,
bottom = 0,
layout = wibox.container.margin,
},
})
local update_volume = function() -- Sets the Volume Correct
awful.spawn.easy_async_with_shell("pamixer --get-volume", function(stdout)
slider.value = tonumber(stdout:match("%d+"))
end)
end
awesome.connect_signal("widget::update_vol", function()
update_volume()
end)
awesome.connect_signal("widget::update_vol_slider", function(volume_level)
slider:set_value(volume_level)
end)
slider:connect_signal("property::value", function(_, new_value)
awful.spawn("pamixer --set-volume " .. new_value, false)
awesome.emit_signal("widget::update_vol_pulse") -- update_vol_pulse doesn't Update Volume Signal
local volume_level = slider:get_value()
osd_value.text = volume_level .. "%"
end)
return vol_slider

View file

@ -0,0 +1,10 @@
local req = {
"layout",
"notifications",
"scratchpad",
"volume",
}
for _, x in pairs(req) do
require(... .. "." .. x)
end

View file

@ -0,0 +1,131 @@
local awful = require("awful")
local gears = require("gears")
local beautiful = require("beautiful")
local wibox = require("wibox")
local keys = require("config").keys
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
local ll = awful.widget.layoutlist({
base_layout = wibox.widget({
spacing = dpi(5),
forced_num_cols = dpi(4),
layout = wibox.layout.grid.vertical,
}),
widget_template = {
{
{
id = "icon_role",
forced_height = dpi(1),
forced_width = dpi(1),
widget = wibox.widget.imagebox,
},
margins = dpi(15),
widget = wibox.container.margin,
},
id = "background_role",
forced_width = dpi(70),
forced_height = dpi(70),
shape = gears.shape.rounded_rect,
widget = wibox.container.background,
},
})
local layout_popup = awful.popup({
widget = wibox.widget({
ll,
margins = 4, --border margins (padding)
widget = wibox.container.margin,
}),
border_color = theme.border_normal,
bg = theme.bg_normal,
border_width = theme.border_width,
placement = awful.placement.centered,
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
})
function gears.table.iterate_value(t, value, step_size, filter, _)
local k = gears.table.hasitem(t, value)
if not k then
return
end
step_size = step_size or 1
local new_key = gears.math.cycle(#t, k + step_size)
if filter and not filter(t[new_key]) then
for i = 1, #t do
local k2 = gears.math.cycle(#t, new_key + i)
if filter(t[k2]) then
return t[k2], k2
end
end
return
end
return t[new_key], new_key
end
-- Timer for Death of PopUp
layout_popup.timer = gears.timer({
timeout = 0.8,
single_shot = true,
callback = function()
layout_popup.visible = false
end,
})
function layout_popup.changed()
layout_popup.visible = true
if not layout_popup.visible then
layout_popup.timer:start()
else
layout_popup.timer:again()
end
end
-- Mouse Support
layout_popup:connect_signal("mouse::enter", function()
layout_popup.timer:stop()
end)
layout_popup:connect_signal("mouse::leave", function()
layout_popup.timer:start()
end)
awful.keygrabber({
start_callback = function()
layout_popup.visible = true
end,
stop_callback = function()
layout_popup.visible = false
end,
export_keybindings = true,
stop_event = "release",
stop_key = { "Escape", "Super_L", "Super_R" },
keybindings = {
{
{ keys.mod },
" ",
function()
awful.layout.set(gears.table.iterate_value(ll.layouts, ll.current_layout, 1), layout_popup.changed())
end,
},
{
{ keys.mod, "Shift" },
" ",
function()
awful.layout.set(gears.table.iterate_value(ll.layouts, ll.current_layout, -1), layout_popup.changed())
end,
},
},
})

View file

@ -0,0 +1,12 @@
local naughty = require("naughty")
--- Check if awesome encountered an error during startup and fell back to
--- another config (This code will only ever execute for the fallback config)
naughty.connect_signal("request::display_error", function(message, startup)
naughty.notification({
urgency = "critical",
app_name = "Awesome",
title = "Oops, an error happened" .. (startup and " during startup!" or "!"),
message = message,
})
end)

View file

@ -0,0 +1,350 @@
local gears = require("gears")
local wibox = require("wibox")
local awful = require("awful")
local beautiful = require("beautiful")
local naughty = require("naughty")
local helpers = require("helpers")
local menubar = require("menubar")
local animation = require("lib.animation")
local theme = beautiful.get()
local dpi = beautiful.xresources.apply_dpi
--- Naughty Notifications with animation
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
naughty.persistence_enabled = true
naughty.config.defaults.ontop = true
naughty.config.defaults.timeout = 6
naughty.config.defaults.title = "System Notification"
naughty.config.defaults.position = "top_right"
local function get_oldest_notification()
for _, notification in ipairs(naughty.active) do
if notification and notification.timeout > 0 then
return notification
end
end
--- Fallback to first one.
return naughty.active[1]
end
--- Handle notification icon
naughty.connect_signal("request::icon", function(n, context, hints)
--- Handle other contexts here
if context ~= "app_icon" then
return
end
--- Use XDG icon
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)
--- Use XDG icon
naughty.connect_signal("request::action_icon", function(a, _, hints)
a.icon = menubar.utils.lookup_icon(hints.id)
end)
naughty.connect_signal("request::display", function(n)
--- random accent color
local accent_colors = theme.color.accent
--- table of icons
local app_icons = {
["firefox"] = { icon = "" },
["discord"] = { icon = "󰙯" },
["music"] = { icon = "󰝚" },
["screenshot tool"] = { icon = "󰊓" },
}
local app_icon = nil
local tolow = string.lower
if app_icons[tolow(n.app_name)] then
app_icon = app_icons[tolow(n.app_name)].icon
else
app_icon = "󰂚"
end
local app_icon_n = wibox.widget({
{
font = helpers.ui.set_font("Round 13"),
markup = helpers.ui.colorize_text(app_icon, theme.color.base),
halign = "center",
valign = "center",
widget = wibox.widget.textbox,
},
bg = accent_colors,
widget = wibox.container.background,
shape = gears.shape.circle,
forced_height = dpi(20),
forced_width = dpi(20),
})
local icon = wibox.widget({
{
{
{
image = n.icon,
resize = true,
clip_shape = gears.shape.circle,
halign = "center",
valign = "center",
widget = wibox.widget.imagebox,
},
border_width = dpi(2),
border_color = accent_colors,
shape = gears.shape.circle,
widget = wibox.container.background,
},
strategy = "exact",
height = dpi(50),
width = dpi(50),
widget = wibox.container.constraint,
},
{
nil,
nil,
{
nil,
nil,
app_icon_n,
layout = wibox.layout.align.horizontal,
expand = "none",
},
layout = wibox.layout.align.vertical,
expand = "none",
},
layout = wibox.layout.stack,
})
local app_name = wibox.widget({
font = helpers.ui.set_font("Bold 12"),
text = n.app_name:gsub("^%l", string.upper),
widget = wibox.widget.textbox,
})
local dismiss = wibox.widget({
{
font = helpers.ui.set_font("Bold 10"),
markup = helpers.ui.colorize_text("", theme.color.accent),
widget = wibox.widget.textbox,
valign = "center",
halign = "center",
},
margins = dpi(4),
widget = wibox.container.margin,
})
dismiss:buttons(gears.table.join(awful.button({}, 1, function()
n:destroy(naughty.notification_closed_reason.dismissed_by_user)
end)))
local timeout_arc = wibox.widget({
widget = wibox.container.arcchart,
forced_width = dpi(26),
forced_height = dpi(26),
max_value = 100,
min_value = 0,
value = 0,
thickness = dpi(4),
rounded_edge = true,
bg = theme.color.base,
colors = {
{
type = "linear",
from = { 0, 0 },
to = { 400, 400 },
stops = {
{ 0, accent_colors },
{ 0.2, accent_colors },
{ 0.4, accent_colors },
{ 0.6, accent_colors },
{ 0.8, accent_colors },
},
},
},
dismiss,
})
local title2 = wibox.widget.textbox()
title2.font = helpers.ui.set_font("Bold 11")
title2.text = n.title
local title = wibox.widget({
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
fps = 60,
speed = 75,
title2,
})
local message2 = wibox.widget.textbox()
message2.font = helpers.ui.set_font("11")
message2.text = n.message
local message = wibox.widget({
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
fps = 60,
speed = 75,
message2,
})
local actions = wibox.widget({
notification = n,
base_layout = wibox.widget({
spacing = dpi(3),
layout = wibox.layout.flex.horizontal,
}),
widget_template = {
{
{
{
id = "text_role",
font = helpers.ui.set_font("10"),
widget = wibox.widget.textbox,
},
left = dpi(6),
right = dpi(6),
widget = wibox.container.margin,
},
widget = wibox.container.place,
},
bg = theme.color.base,
forced_height = dpi(25),
forced_width = dpi(70),
widget = wibox.container.background,
},
style = {
underline_normal = false,
underline_selected = true,
},
widget = naughty.list.actions,
})
local widget = naughty.layout.box({
notification = n,
type = "notification",
cursor = "hand2",
shape = helpers.ui.rrect(12),
border_color = theme.color.surface0,
border_width = dpi(3),
maximum_width = dpi(350),
maximum_height = dpi(180),
bg = "#00000000",
widget_template = {
{
layout = wibox.layout.fixed.vertical,
{
{
{
layout = wibox.layout.align.horizontal,
app_name,
nil,
timeout_arc,
},
margins = { top = dpi(3), bottom = dpi(3), left = dpi(15), right = dpi(15) },
widget = wibox.container.margin,
},
bg = theme.color.surface0,
widget = wibox.container.background,
},
{
{
layout = wibox.layout.fixed.vertical,
{
layout = wibox.layout.fixed.horizontal,
spacing = dpi(10),
icon,
{
expand = "none",
layout = wibox.layout.align.vertical,
nil,
{
layout = wibox.layout.fixed.vertical,
title,
message,
},
nil,
},
},
{
helpers.ui.vertical_pad(dpi(10)),
{
actions,
shape = helpers.ui.rrect(0),
widget = wibox.container.background,
},
visible = n.actions and #n.actions > 0,
layout = wibox.layout.fixed.vertical,
},
},
margins = dpi(15),
widget = wibox.container.margin,
},
},
--- Anti-aliasing container
shape = helpers.ui.rrect(0),
bg = theme.color.base,
widget = wibox.container.background,
},
})
--- Don't destroy the notification on click ---
widget.buttons = {}
--- Disables Hand Cursor in Whole wibox ---
helpers.ui.add_hover_cursor(widget, "left_ptr")
--- Adds Close Cursor on Close Sign ---
helpers.ui.add_hover_cursor(dismiss, "hand2")
local anim = animation:new({
duration = n.timeout,
target = 100,
easing = animation.easing.linear,
reset_on_stop = false,
update = function(_, pos)
timeout_arc.value = pos
end,
})
anim:connect_signal("ended", function()
n:reset_timeout(0.0000001)
end)
widget:connect_signal("mouse::enter", function()
n:reset_timeout(0)
anim:stop()
end)
widget:connect_signal("mouse::leave", function()
anim:start()
end)
local notification_height = widget.height + theme.notification_spacing
local total_notifications_height = #naughty.active * notification_height
if total_notifications_height > n.screen.workarea.height then
get_oldest_notification():destroy(naughty.notification_closed_reason.too_many_on_screen)
end
anim:start()
--- Destroy popups notifs if dont_disturb mode is on
---@diagnostic disable-next-line: undefined-field
if _G.dnd_state then
naughty.destroy_all_notifications(nil, 1)
end
end)
require(... .. ".error")

Some files were not shown because too many files have changed in this diff Show more