├── .gitignore ├── config ├── awesome │ ├── theme │ │ ├── activetheme │ │ ├── gruvbox │ │ │ ├── colors.nvim │ │ │ ├── colors.gtk │ │ │ ├── colors.rasi │ │ │ ├── wallpapers │ │ │ │ └── gruvbox_minimal_space.png │ │ │ ├── colors.lua │ │ │ └── colors.conf │ │ ├── catppuccin │ │ │ ├── colors.nvim │ │ │ ├── colors.gtk │ │ │ ├── colors.rasi │ │ │ ├── wallpapers │ │ │ │ └── dark-cat.png │ │ │ ├── colors.lua │ │ │ └── colors.conf │ │ ├── rose-pine │ │ │ ├── colors.nvim │ │ │ ├── colors.gtk │ │ │ ├── colors.rasi │ │ │ ├── wallpapers │ │ │ │ └── rose_pine_shape.png │ │ │ ├── colors.lua │ │ │ └── colors.conf │ │ └── init.lua │ ├── env.example.lua │ ├── img │ │ ├── profile.png │ │ ├── circle.svg │ │ ├── tag.svg │ │ └── tag_sel.svg │ ├── client.lua │ ├── bar │ │ ├── task.lua │ │ ├── oth.lua │ │ ├── init.lua │ │ ├── tag.lua │ │ └── sys.lua │ ├── notifications.lua │ ├── rules.lua │ ├── scripts │ │ ├── theme.sh │ │ ├── power.sh │ │ └── wallpaper.sh │ ├── menu.lua │ ├── rc.lua │ ├── titlebar.lua │ ├── help.lua │ ├── popup.lua │ ├── signals.lua │ ├── dashboard │ │ ├── sli.lua │ │ ├── init.lua │ │ ├── wid.lua │ │ └── oth.lua │ ├── keys.lua │ └── lib │ │ └── json.lua ├── rofi │ ├── config.rasi │ ├── colors.rasi │ ├── power.rasi │ ├── theme.rasi │ ├── wallpaper.rasi │ └── apps.rasi ├── gtk │ └── themes.7z ├── kitty │ ├── colors.conf │ └── kitty.conf └── picom │ └── picom.conf ├── assets ├── gruvbox.png ├── rose-pine.png └── catppuccin.png ├── fonts ├── tabler-icons.ttf └── Font Awesome 6 Pro-Solid-900.otf ├── .gitmodules ├── format.sh ├── install.sh ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | env.lua 2 | -------------------------------------------------------------------------------- /config/awesome/theme/activetheme: -------------------------------------------------------------------------------- 1 | gruvbox 2 | -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/colors.nvim: -------------------------------------------------------------------------------- 1 | grubvox 2 | -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/colors.nvim: -------------------------------------------------------------------------------- 1 | catppuccin 2 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/colors.nvim: -------------------------------------------------------------------------------- 1 | rosepine 2 | -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/colors.gtk: -------------------------------------------------------------------------------- 1 | Gruvbox-Dark-BL 2 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/colors.gtk: -------------------------------------------------------------------------------- 1 | rose-pine-gtk 2 | -------------------------------------------------------------------------------- /config/awesome/env.example.lua: -------------------------------------------------------------------------------- 1 | local env = {} 2 | 3 | return env 4 | -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/colors.gtk: -------------------------------------------------------------------------------- 1 | Catppuccin-Mocha-Standard-Blue-Dark 2 | -------------------------------------------------------------------------------- /config/rofi/config.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | modes: "drun,filebrowser"; 3 | } 4 | -------------------------------------------------------------------------------- /assets/gruvbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/assets/gruvbox.png -------------------------------------------------------------------------------- /assets/rose-pine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/assets/rose-pine.png -------------------------------------------------------------------------------- /config/gtk/themes.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/config/gtk/themes.7z -------------------------------------------------------------------------------- /assets/catppuccin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/assets/catppuccin.png -------------------------------------------------------------------------------- /fonts/tabler-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/fonts/tabler-icons.ttf -------------------------------------------------------------------------------- /config/awesome/img/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/config/awesome/img/profile.png -------------------------------------------------------------------------------- /config/rofi/colors.rasi: -------------------------------------------------------------------------------- 1 | * { 2 | bg: #282828E6; 3 | fg: #ebdbb2; 4 | al: #ebdbb240; 5 | tr: #ebdbb21A; 6 | } 7 | -------------------------------------------------------------------------------- /fonts/Font Awesome 6 Pro-Solid-900.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/fonts/Font Awesome 6 Pro-Solid-900.otf -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/colors.rasi: -------------------------------------------------------------------------------- 1 | * { 2 | bg: #282828E6; 3 | fg: #ebdbb2; 4 | al: #ebdbb240; 5 | tr: #ebdbb21A; 6 | } 7 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/colors.rasi: -------------------------------------------------------------------------------- 1 | * { 2 | bg: #191724E6; 3 | fg: #e0def4; 4 | al: #e0def440; 5 | tr: #e0def41A; 6 | } 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "config/awesome/lib/rubato"] 2 | path = config/awesome/lib/rubato 3 | url = https://github.com/andOrlando/rubato 4 | -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/colors.rasi: -------------------------------------------------------------------------------- 1 | * { 2 | bg: #1e1e2eE6; 3 | fg: #cdd6f4; 4 | al: #cdd6f440; 5 | tr: #cdd6f41A; 6 | } 7 | -------------------------------------------------------------------------------- /config/awesome/img/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/wallpapers/dark-cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/config/awesome/theme/catppuccin/wallpapers/dark-cat.png -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | stylua --glob '**/*.lua' . 4 | find . -name "*.md" -exec prettier --write {} \; 5 | find . -name "*.sh" -exec shfmt -w {} \; 6 | -------------------------------------------------------------------------------- /config/awesome/img/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /config/awesome/img/tag_sel.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/wallpapers/rose_pine_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/config/awesome/theme/rose-pine/wallpapers/rose_pine_shape.png -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/wallpapers/gruvbox_minimal_space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdmrk/policromia/HEAD/config/awesome/theme/gruvbox/wallpapers/gruvbox_minimal_space.png -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/colors.lua: -------------------------------------------------------------------------------- 1 | local colors = {} 2 | 3 | colors.ok = "#a6e3a1" 4 | colors.err = "#f38ba8" 5 | colors.pri = "#b4befe" 6 | colors.bg = "#1e1e2e" 7 | colors.bg2 = "#181825" 8 | colors.bg3 = "#11111b" 9 | colors.fg = "#c0caf5" 10 | colors.fg2 = "#45475a" 11 | 12 | return colors 13 | -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/colors.lua: -------------------------------------------------------------------------------- 1 | local colors = {} 2 | 3 | colors.ok = "#98971a" 4 | colors.err = "#cc241d" 5 | colors.pri = "#fbf1c7" 6 | colors.bg = "#282828" 7 | colors.bg2 = "#3c3836" 8 | colors.bg3 = "#928374" 9 | colors.fg = "#ebdbb2" 10 | colors.fg2 = "#665c54" 11 | 12 | return colors 13 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/colors.lua: -------------------------------------------------------------------------------- 1 | local colors = {} 2 | 3 | colors.ok = "#31748f" 4 | colors.err = "#eb6f92" 5 | colors.pri = "#58AFC2" 6 | colors.bg = "#191724" 7 | colors.bg2 = "#26233a" 8 | colors.bg3 = "#524f67" 9 | colors.fg = "#e0def4" 10 | colors.fg2 = "#6e6a86" 11 | 12 | return colors 13 | -------------------------------------------------------------------------------- /config/awesome/client.lua: -------------------------------------------------------------------------------- 1 | -- Sloppy Focus 2 | client.connect_signal("mouse::enter", function(c) 3 | c:emit_signal("request::activate", "mouse_enter", { raise = false }) 4 | end) 5 | 6 | client.connect_signal("focus", function(c) 7 | c.border_color = beautiful.border_focus 8 | end) 9 | client.connect_signal("unfocus", function(c) 10 | c.border_color = beautiful.border_normal 11 | end) 12 | 13 | client.connect_signal("property::maximized", function(c) 14 | c.maximized = false 15 | end) 16 | 17 | client.connect_signal("property::minimized", function(c) 18 | c.minimized = false 19 | end) 20 | -------------------------------------------------------------------------------- /config/kitty/colors.conf: -------------------------------------------------------------------------------- 1 | foreground #c0caf5 2 | cursor #D20075 3 | cursor_text_color #282936 4 | background #070219 5 | 6 | # Black, Gray 7 | color0 #070219 8 | color8 #626483 9 | 10 | # Red 11 | color1 #fb007a 12 | color9 #fb007a 13 | 14 | # Green 15 | color2 #a6e22e 16 | color10 #a6e22e 17 | 18 | # Yellow 19 | color3 #f3e430 20 | color11 #f3e430 21 | 22 | # Blue 23 | color4 #58AFC2 24 | color12 #58AFC2 25 | 26 | # Magenta 27 | color5 #583794 28 | color13 #472575 29 | 30 | # Cyan 31 | color6 #926BCA 32 | color14 #926BCA 33 | 34 | # White 35 | color7 #d9d9d9 36 | color15 #f1f1f1 37 | -------------------------------------------------------------------------------- /config/picom/picom.conf: -------------------------------------------------------------------------------- 1 | shadow = true 2 | shadow-radius = 18 3 | shadow-opacity = .7 4 | shadow-offset-x = -18 5 | shadow-offset-y = -18 6 | shadow-exclude = [ 7 | "window_type = 'popup_menu'", 8 | "window_type = 'dialog'", 9 | "window_type = 'menu'", 10 | "window_type = 'tooltip'", 11 | "window_type = 'dropdown_menu'", 12 | "_GTK_FRAME_EXTENTS@:c" 13 | ] 14 | 15 | corner-radius = 24; 16 | rounded-corners-exclude = [ 17 | "window_type = 'desktop'", 18 | "window_type = 'menu'", 19 | "window_type = 'dropdown_menu'", 20 | "window_type = 'tooltip'", 21 | "window_type = 'popup_menu'", 22 | "window_type = 'dialog'" 23 | ] 24 | 25 | backend = "glx" 26 | vsync = true 27 | use_damage = true 28 | log-level = "warn" 29 | -------------------------------------------------------------------------------- /config/awesome/bar/task.lua: -------------------------------------------------------------------------------- 1 | local get_tasklist = function(s) 2 | return awful.widget.tasklist({ 3 | screen = s, 4 | filter = awful.widget.tasklist.filter.currenttags, 5 | buttons = gears.table.join( 6 | awful.button({}, 1, function(c) 7 | if c == client.focus then 8 | c.minimized = true 9 | else 10 | c:emit_signal("request::activate", "tasklist", { raise = true }) 11 | end 12 | end), 13 | awful.button({}, 3, function() 14 | awful.menu.client_list({ theme = { width = 250 } }) 15 | end), 16 | awful.button({}, 4, function() 17 | awful.client.focus.byidx(1) 18 | end), 19 | awful.button({}, 5, function() 20 | awful.client.focus.byidx(-1) 21 | end) 22 | ), 23 | }) 24 | end 25 | 26 | return get_tasklist 27 | -------------------------------------------------------------------------------- /config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | include colors.conf 2 | 3 | font_family JetBrainsMono NF Medium 4 | bold_font JetBrainsMono NF Bold 5 | italic_font JetBrainsMono NF Italic 6 | bold_italic_font JetBrainsMono NF Bold Italic 7 | window_padding_width 15 8 | font_size 10 9 | 10 | tab_bar_margin_width 9 11 | tab_bar_margin_height 9 0 12 | tab_bar_style separator 13 | tab_bar_min_tabs 1 14 | tab_separator "" 15 | active_tab_title_template "{fmt.fg._5c6370}{fmt.bg.default}{fmt.fg._abb2bf}{fmt.bg._5c6370} {title.split()[0]} {fmt.fg._5c6370}{fmt.bg.default} " 16 | tab_title_template "{fmt.fg._272829}{fmt.bg.default}{fmt.fg.default}{fmt.bg._272829} {title.split()[0]} {fmt.fg._272829}{fmt.bg.default} " 17 | -------------------------------------------------------------------------------- /config/awesome/notifications.lua: -------------------------------------------------------------------------------- 1 | naughty.config.defaults.ontop = true 2 | naughty.config.defaults.timeout = 3 3 | naughty.config.defaults.screen = awful.screen.focused() 4 | 5 | naughty.config.padding = dpi(10) 6 | naughty.config.spacing = dpi(20) 7 | naughty.config.defaults.shape = help.rrect(beautiful.br) 8 | 9 | naughty.config.defaults.border_width = dpi(15) 10 | naughty.config.defaults.border_color = beautiful.bg 11 | 12 | naughty.config.defaults.position = "bottom_right" 13 | naughty.config.defaults.fg = beautiful.fg 14 | naughty.config.defaults.bg = beautiful.bg 15 | 16 | naughty.config.presets.normal = { 17 | fg = beautiful.fg, 18 | bg = beautiful.bg, 19 | } 20 | 21 | naughty.config.presets.low = { 22 | fg = beautiful.ok, 23 | bg = beautiful.bg, 24 | } 25 | 26 | naughty.config.presets.critical = { 27 | fg = beautiful.err, 28 | bg = beautiful.bg, 29 | } 30 | -------------------------------------------------------------------------------- /config/awesome/bar/oth.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- Separator 4 | M.sep = wibox.widget({ 5 | { 6 | forced_height = dpi(2), 7 | shape = gears.shape.line, 8 | widget = wibox.widget.separator, 9 | }, 10 | top = dpi(15), 11 | left = dpi(5), 12 | right = dpi(5), 13 | bottom = dpi(15), 14 | widget = wibox.container.margin, 15 | }) 16 | 17 | M.launch = wibox.widget({ 18 | { 19 | markup = "\u{f65b}", 20 | font = beautiful.icofont, 21 | align = "center", 22 | valign = "center", 23 | widget = wibox.widget.textbox, 24 | }, 25 | widget = wibox.container.background, 26 | }) 27 | 28 | M.search = wibox.widget({ 29 | { 30 | markup = "\u{eb1c}", 31 | font = beautiful.icofont, 32 | align = "center", 33 | valign = "center", 34 | widget = wibox.widget.textbox, 35 | }, 36 | widget = wibox.container.background, 37 | }) 38 | 39 | M.search:buttons(gears.table.join(awful.button({}, 1, function() 40 | awful.spawn.with_shell("rofi -show drun -show-icons -theme apps") 41 | end))) 42 | 43 | M.launch:buttons(gears.table.join(awful.button({}, 1, function() 44 | dashboard.toggle() 45 | end))) 46 | 47 | return M 48 | -------------------------------------------------------------------------------- /config/awesome/rules.lua: -------------------------------------------------------------------------------- 1 | awful.rules.rules = { 2 | { 3 | rule = {}, 4 | properties = { 5 | border_width = beautiful.border_width, 6 | border_color = beautiful.border_color, 7 | focus = awful.client.focus.filter, 8 | raise = true, 9 | maximized = false, 10 | keys = keys.clientkeys, 11 | buttons = keys.clientbuttons, 12 | screen = awful.screen.preferred, 13 | }, 14 | }, 15 | 16 | -- Add titlebars to normal clients 17 | { 18 | rule_any = { 19 | type = { "normal" }, 20 | }, 21 | properties = { titlebars_enabled = false }, 22 | }, 23 | 24 | -- Floating, Titlebar exceptions 25 | { 26 | rule_any = { 27 | class = { "gnome", "gtk", "qt5ct", "steam", "VirtualBox Manager" }, 28 | name = { "Event Tester", "Komikku", "marker" }, 29 | type = { "dialog" }, 30 | }, 31 | properties = { floating = true, titlebars_enabled = false }, 32 | }, 33 | { 34 | rule_any = { 35 | class = { "feh", "Sxiv", "Gcr-prompter", "Pavucontrol", "Lxappearance", "Blueman-manager" }, 36 | role = { "pop-up", "GtkFileChooserDialog" }, 37 | type = { "dialog" }, 38 | }, 39 | properties = { floating = true, titlebars_enabled = false, placement = awful.placement.centered }, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /config/awesome/scripts/theme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | theme_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)/../theme 4 | directories=$(find ${theme_dir}/ -mindepth 1 -maxdepth 1 -type d) 5 | declare -A name_map 6 | 7 | for directory in $directories; do 8 | basename=$(basename "$directory") 9 | formatted_name=$(basename "$directory" | tr '-' ' ' | sed 's/\<./\u&/g') 10 | name_map["$formatted_name"]=$(basename "$directory") 11 | done 12 | 13 | theme=$(printf '%s\n' "${!name_map[@]}" | rofi -dmenu -theme theme) 14 | if [ -z "$theme" ]; then 15 | exit 1 16 | fi 17 | selectedtheme="${name_map[$theme]}" 18 | activetheme=${theme_dir}/${selectedtheme} 19 | 20 | echo "$selectedtheme" >${theme_dir}/activetheme & 21 | cp $activetheme/colors.conf $HOME/.config/kitty/colors.conf & 22 | cp $activetheme/colors.rasi $HOME/.config/rofi/colors.rasi & 23 | sed -i "s/\(gtk-theme-name=\).*/\1$(cat ${activetheme}/colors.gtk)/" $HOME/.config/gtk-3.0/settings.ini 24 | sed -i "s/\(gtk-theme-name=\).*/\1\"$(cat ${activetheme}/colors.gtk)\"/" $HOME/.gtkrc-2.0 25 | sed -i "/theme =/s/\"[^\"]*\"/\"$(cat ${activetheme}/colors.nvim)\"/" $HOME/.config/nvim/lua/chadrc.lua 26 | echo 'awesome.restart()' | awesome-client >/dev/null 27 | -------------------------------------------------------------------------------- /config/awesome/theme/rose-pine/colors.conf: -------------------------------------------------------------------------------- 1 | ## name: Rosé Pine 2 | ## author: mvllow 3 | ## license: MIT 4 | ## upstream: https://github.com/rose-pine/kitty/blob/main/dist/rose-pine.conf 5 | ## blurb: All natural pine, faux fur and a bit of soho vibes for the classy minimalist 6 | 7 | foreground #e0def4 8 | background #191724 9 | selection_foreground #e0def4 10 | selection_background #403d52 11 | 12 | cursor #524f67 13 | cursor_text_color #e0def4 14 | 15 | url_color #c4a7e7 16 | 17 | active_tab_foreground #e0def4 18 | active_tab_background #26233a 19 | inactive_tab_foreground #6e6a86 20 | inactive_tab_background #191724 21 | 22 | active_border_color #31748f 23 | inactive_border_color #403d52 24 | 25 | # black 26 | color0 #26233a 27 | color8 #6e6a86 28 | 29 | # red 30 | color1 #eb6f92 31 | color9 #eb6f92 32 | 33 | # green 34 | color2 #31748f 35 | color10 #31748f 36 | 37 | # yellow 38 | color3 #f6c177 39 | color11 #f6c177 40 | 41 | # blue 42 | color4 #9ccfd8 43 | color12 #9ccfd8 44 | 45 | # magenta 46 | color5 #c4a7e7 47 | color13 #c4a7e7 48 | 49 | # cyan 50 | color6 #ebbcba 51 | color14 #ebbcba 52 | 53 | # white 54 | color7 #e0def4 55 | color15 #e0def4 56 | 57 | -------------------------------------------------------------------------------- /config/awesome/menu.lua: -------------------------------------------------------------------------------- 1 | local system = { 2 | { 3 | "Lock screen", 4 | function() 5 | awful.spawn("betterlockscreen -l", false) 6 | end, 7 | }, 8 | { 9 | "Log out", 10 | function() 11 | awesome.quit() 12 | end, 13 | }, 14 | { 15 | "Reboot", 16 | function() 17 | awful.spawn("systemctl reboot") 18 | end, 19 | }, 20 | { 21 | "Suspend", 22 | function() 23 | awful.spawn("systemctl suspend") 24 | end, 25 | }, 26 | { 27 | "Hibernate", 28 | function() 29 | awful.spawn("systemctl hibernate") 30 | end, 31 | }, 32 | { 33 | "Shut down", 34 | function() 35 | awful.spawn("systemctl poweroff") 36 | end, 37 | }, 38 | } 39 | 40 | local awesome = { 41 | { "Refresh", awesome.restart }, 42 | } 43 | 44 | awful.menu.original_new = awful.menu.new 45 | function awful.menu.new(...) 46 | local ret = awful.menu.original_new(...) 47 | ret.wibox.shape = help.rrect(beautiful.br) 48 | return ret 49 | end 50 | 51 | local main = awful.menu({ 52 | items = { 53 | { "System", system }, 54 | { 55 | "Awesome", 56 | awesome, 57 | }, 58 | { "Terminal", "kitty" }, 59 | { "Browser", "firefox" }, 60 | { "Editor", "kitty -e nvim" }, 61 | { "Files", "thunar" }, 62 | }, 63 | }) 64 | 65 | root.buttons(gears.table.join(awful.button({}, 3, function() 66 | main:toggle() 67 | end))) 68 | -------------------------------------------------------------------------------- /config/awesome/bar/init.lua: -------------------------------------------------------------------------------- 1 | local sys = require("bar.sys") 2 | local oth = require("bar.oth") 3 | 4 | local main = wibox.widget({ 5 | { 6 | oth.launch, 7 | oth.search, 8 | spacing = dpi(20), 9 | layout = wibox.layout.fixed.vertical, 10 | }, 11 | widget = wibox.container.margin, 12 | margins = { top = dpi(20) }, 13 | }) 14 | 15 | local tags = function(s) 16 | return wibox.widget({ 17 | require("bar.tag")(s), 18 | widget = wibox.container.margin, 19 | margins = dpi(18), 20 | }) 21 | end 22 | 23 | local sys = wibox.widget({ 24 | { 25 | { 26 | sys.vol, 27 | sys.battery, 28 | spacing = dpi(20), 29 | layout = wibox.layout.fixed.vertical, 30 | }, 31 | oth.sep, 32 | sys.clock, 33 | layout = wibox.layout.fixed.vertical, 34 | }, 35 | widget = wibox.container.margin, 36 | margins = { bottom = dpi(20) }, 37 | }) 38 | 39 | awful.screen.connect_for_each_screen(function(s) 40 | awful 41 | .wibar({ 42 | position = "left", 43 | bg = beautiful.bg, 44 | fg = beautiful.fg, 45 | width = beautiful.bar_width, 46 | height = s.geometry.height - beautiful.useless_gap * 4, 47 | margins = { left = beautiful.useless_gap * 2 }, 48 | screen = s, 49 | }) 50 | :setup({ 51 | main, 52 | tags(s), 53 | sys, 54 | expand = "none", 55 | layout = wibox.layout.align.vertical, 56 | }) 57 | end) 58 | -------------------------------------------------------------------------------- /config/awesome/rc.lua: -------------------------------------------------------------------------------- 1 | -- Importing libraries 2 | help = require("help") 3 | gears = require("gears") 4 | awful = require("awful") 5 | wibox = require("wibox") 6 | naughty = require("naughty") 7 | beautiful = require("beautiful") 8 | rubato = require("lib.rubato") 9 | dpi = beautiful.xresources.apply_dpi 10 | beautiful.init("~/.config/awesome/theme/init.lua") 11 | keys = require("keys") 12 | dashboard = require("dashboard") 13 | sig = require("signals") 14 | local signals = require("signals") 15 | local req = { 16 | "notifications", 17 | "bar", 18 | "menu", 19 | "rules", 20 | "titlebar", 21 | "client", 22 | "awful.autofocus", 23 | } 24 | require("popup") 25 | 26 | for _, x in pairs(req) do 27 | require(x) 28 | end 29 | 30 | -- Layouts 31 | awful.layout.layouts = { 32 | awful.layout.suit.tile, 33 | awful.layout.suit.floating, 34 | } 35 | 36 | -- Virtual desktops/ Tabs 37 | awful.screen.connect_for_each_screen(function(s) 38 | local tagTable = {} 39 | for i = 1, keys.tags do 40 | table.insert(tagTable, tostring(i)) 41 | end 42 | awful.tag(tagTable, s, awful.layout.layouts[1]) 43 | end) 44 | 45 | -- Signals 46 | gears.timer({ 47 | timeout = 10, 48 | single_shot = true, 49 | autostart = true, 50 | call_now = true, 51 | callback = function() 52 | signals.vol() 53 | signals.mic() 54 | end, 55 | }) 56 | 57 | -- Autostart 58 | awful.spawn("picom -b", false) 59 | awful.spawn.with_shell("~/.fehbg") 60 | -------------------------------------------------------------------------------- /config/awesome/titlebar.lua: -------------------------------------------------------------------------------- 1 | client.connect_signal("request::titlebars", function(c) 2 | -- buttons for the titlebar 3 | local buttons = gears.table.join( 4 | awful.button({}, 1, function() 5 | client.focus = c 6 | c:raise() 7 | awful.mouse.client.move(c) 8 | end), 9 | awful.button({}, 3, function() 10 | client.focus = c 11 | c:raise() 12 | awful.mouse.client.resize(c) 13 | end) 14 | ) 15 | awful 16 | .titlebar(c, { 17 | size = 30, 18 | }) 19 | :setup({ 20 | { 21 | { 22 | -- Left 23 | { 24 | -- Title 25 | align = "center", 26 | widget = awful.titlebar.widget.titlewidget(c), 27 | }, 28 | -- awful.titlebar.widget.iconwidget(c), 29 | buttons = buttons, 30 | layout = wibox.layout.fixed.horizontal, 31 | }, 32 | { 33 | -- Middle 34 | buttons = buttons, 35 | layout = wibox.layout.flex.horizontal, 36 | }, 37 | { 38 | -- Right 39 | { 40 | awful.titlebar.widget.minimizebutton(c), 41 | awful.titlebar.widget.closebutton(c), 42 | spacing = dpi(10), 43 | layout = wibox.layout.fixed.horizontal, 44 | }, 45 | top = dpi(5), 46 | bottom = dpi(5), 47 | widget = wibox.container.margin, 48 | }, 49 | layout = wibox.layout.align.horizontal, 50 | }, 51 | right = dpi(10), 52 | left = dpi(10), 53 | top = dpi(0), 54 | bottom = dpi(5), 55 | widget = wibox.container.margin, 56 | }) 57 | end) 58 | -------------------------------------------------------------------------------- /config/awesome/theme/gruvbox/colors.conf: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/morhetz/gruvbox by morhetz 2 | # Adapted to kitty by wdomitrz 3 | 4 | cursor #928374 5 | cursor_text_color background 6 | 7 | url_color #83a598 8 | 9 | visual_bell_color #8ec07c 10 | bell_border_color #8ec07c 11 | 12 | active_border_color #d3869b 13 | inactive_border_color #665c54 14 | 15 | foreground #ebdbb2 16 | background #282828 17 | selection_foreground #928374 18 | selection_background #ebdbb2 19 | 20 | active_tab_foreground #fbf1c7 21 | active_tab_background #665c54 22 | inactive_tab_foreground #a89984 23 | inactive_tab_background #3c3836 24 | 25 | # black (bg3/bg4) 26 | color0 #665c54 27 | color8 #7c6f64 28 | 29 | # red 30 | color1 #cc241d 31 | color9 #fb4934 32 | 33 | #: green 34 | color2 #98971a 35 | color10 #b8bb26 36 | 37 | # yellow 38 | color3 #d79921 39 | color11 #fabd2f 40 | 41 | # blue 42 | color4 #458588 43 | color12 #83a598 44 | 45 | # purple 46 | color5 #b16286 47 | color13 #d3869b 48 | 49 | # aqua 50 | color6 #689d6a 51 | color14 #8ec07c 52 | 53 | # white (fg4/fg3) 54 | color7 #a89984 55 | color15 #bdae93 56 | -------------------------------------------------------------------------------- /config/awesome/help.lua: -------------------------------------------------------------------------------- 1 | local help = {} 2 | 3 | help.rrect = function(rad) 4 | return function(cr, width, height) 5 | gears.shape.rounded_rect(cr, width, height, rad) 6 | end 7 | end 8 | 9 | help.fg = function(text, color, thickness) 10 | return "" .. text .. "" 11 | end 12 | 13 | help.merge = function(first_table, second_table) 14 | for k, v in pairs(second_table) do 15 | first_table[k] = v 16 | end 17 | end 18 | 19 | help.write_to_file = function(path, content) 20 | local activethemefile = io.open(path, "w") 21 | if not activethemefile then 22 | return 23 | end 24 | activethemefile:write(content .. "\n") 25 | activethemefile:close() 26 | end 27 | 28 | help.screenshot = function() 29 | awful.spawn.easy_async_with_shell( 30 | "scrot -s -l mode=edge -e 'xclip -selection clipboard -t image/png -i $f' /home/" 31 | .. os.getenv("USER") 32 | .. "/Pictures/Screenshots/Screenshot_%Y-%m-%d_%H.%M.%S.png" 33 | ) 34 | end 35 | 36 | help.truncate = function(count) 37 | local COUNT_ABBRS = { "", "K", "M", "B", "T" } 38 | if count < 1000 then 39 | return count 40 | end 41 | 42 | local i = math.floor(math.log(count) / math.log(1000)) 43 | local result = count / (1000 ^ i) 44 | local digits = math.floor(math.log(result) / math.log(10)) + 1 45 | local decimals = math.max(0, 3 - digits) 46 | 47 | result = string.format("%." .. decimals .. "f", result) 48 | result = result .. COUNT_ABBRS[i + 1] 49 | 50 | return result 51 | end 52 | 53 | return help 54 | -------------------------------------------------------------------------------- /config/awesome/popup.lua: -------------------------------------------------------------------------------- 1 | local height = dpi(250) 2 | local width = dpi(50) 3 | 4 | local prg = wibox.widget({ 5 | max_value = 100, 6 | forced_height = width, 7 | forced_width = height, 8 | value = 25, 9 | shape = help.rrect(dpi(999)), 10 | color = beautiful.pri, 11 | background_color = beautiful.bg3, 12 | widget = wibox.widget.progressbar, 13 | }) 14 | 15 | local icon = wibox.widget({ 16 | font = beautiful.icofont, 17 | align = "center", 18 | valign = "bottom", 19 | widget = wibox.widget.textbox, 20 | }) 21 | 22 | local pop = wibox({ 23 | type = "popup", 24 | height = height, 25 | width = width, 26 | shape = help.rrect(dpi(999)), 27 | halign = "center", 28 | valign = "center", 29 | ontop = true, 30 | visible = false, 31 | }) 32 | 33 | awful.placement.right(pop, { margins = { right = beautiful.useless_gap * 4 } }) 34 | 35 | pop:setup({ 36 | { 37 | prg, 38 | widget = wibox.container.rotate, 39 | direction = "east", 40 | }, 41 | { 42 | icon, 43 | margins = { bottom = dpi(12) }, 44 | widget = wibox.container.margin, 45 | }, 46 | layout = wibox.layout.stack, 47 | }) 48 | 49 | local run = gears.timer({ 50 | timeout = 4, 51 | callback = function() 52 | pop.visible = false 53 | end, 54 | }) 55 | 56 | local timed = rubato.timed({ 57 | duration = 1 / 4, 58 | easing = rubato.quadratic, 59 | subscribed = function(pos) 60 | prg.value = pos 61 | end, 62 | }) 63 | 64 | awesome.connect_signal("vol::value", function(mut, vol) 65 | if mut == 0 then 66 | prg.color = beautiful.pri 67 | icon.markup = help.fg("\u{eb51}", beautiful.bg3, "normal") 68 | else 69 | prg.color = beautiful.err 70 | icon.markup = help.fg("\u{f1c3}", beautiful.bg3, "normal") 71 | end 72 | timed.target = vol 73 | if pop.visible then 74 | run:again() 75 | else 76 | pop.visible = true 77 | run:start() 78 | end 79 | end) 80 | -------------------------------------------------------------------------------- /config/awesome/theme/catppuccin/colors.conf: -------------------------------------------------------------------------------- 1 | # vim:ft=kitty 2 | 3 | ## name: Catppuccin Kitty Mocha 4 | ## author: Catppuccin Org 5 | ## license: MIT 6 | ## upstream: https://github.com/catppuccin/kitty/blob/main/themes/mocha.conf 7 | ## blurb: Soothing pastel theme for the high-spirited! 8 | 9 | 10 | 11 | # The basic colors 12 | foreground #CDD6F4 13 | background #1E1E2E 14 | selection_foreground #1E1E2E 15 | selection_background #F5E0DC 16 | 17 | # Cursor colors 18 | cursor #F5E0DC 19 | cursor_text_color #1E1E2E 20 | 21 | # URL underline color when hovering with mouse 22 | url_color #F5E0DC 23 | 24 | # Kitty window border colors 25 | active_border_color #B4BEFE 26 | inactive_border_color #6C7086 27 | bell_border_color #F9E2AF 28 | 29 | # OS Window titlebar colors 30 | wayland_titlebar_color system 31 | macos_titlebar_color system 32 | 33 | # Tab bar colors 34 | active_tab_foreground #11111B 35 | active_tab_background #CBA6F7 36 | inactive_tab_foreground #CDD6F4 37 | inactive_tab_background #181825 38 | tab_bar_background #1E1E2E 39 | 40 | # Colors for marks (marked text in the terminal) 41 | mark1_foreground #1E1E2E 42 | mark1_background #B4BEFE 43 | mark2_foreground #1E1E2E 44 | mark2_background #CBA6F7 45 | mark3_foreground #1E1E2E 46 | mark3_background #74C7EC 47 | 48 | # The 16 terminal colors 49 | 50 | # black 51 | color0 #45475A 52 | color8 #585B70 53 | 54 | # red 55 | color1 #F38BA8 56 | color9 #F38BA8 57 | 58 | # green 59 | color2 #A6E3A1 60 | color10 #A6E3A1 61 | 62 | # yellow 63 | color3 #F9E2AF 64 | color11 #F9E2AF 65 | 66 | # blue 67 | color4 #89B4FA 68 | color12 #89B4FA 69 | 70 | # magenta 71 | color5 #F5C2E7 72 | color13 #F5C2E7 73 | 74 | # cyan 75 | color6 #94E2D5 76 | color14 #94E2D5 77 | 78 | # white 79 | color7 #BAC2DE 80 | color15 #A6ADC8 81 | -------------------------------------------------------------------------------- /config/awesome/bar/tag.lua: -------------------------------------------------------------------------------- 1 | local update_tags = function(self, c3, index) 2 | local tagicon = self:get_children_by_id("icon_role")[1] 3 | local new_icon = beautiful.tag 4 | local new_color = beautiful.fg2 5 | 6 | if #c3:clients() > 0 then 7 | new_color = beautiful.fg 8 | end 9 | 10 | if c3.selected then 11 | new_color = beautiful.pri 12 | new_icon = beautiful.tag_sel 13 | end 14 | tagicon.image = gears.color.recolor_image(new_icon, new_color) 15 | end 16 | 17 | local get_taglist = function(s) 18 | return awful.widget.taglist({ 19 | screen = s, 20 | filter = awful.widget.taglist.filter.all, 21 | layout = { 22 | spacing = 2, 23 | layout = wibox.layout.fixed.vertical, 24 | }, 25 | style = { 26 | shape = gears.shape.rounded_rect, 27 | }, 28 | buttons = gears.table.join( 29 | awful.button({}, 1, function(t) 30 | t:view_only() 31 | end), 32 | awful.button({ modkey }, 1, function(t) 33 | if client.focus then 34 | client.focus:move_to_tag(t) 35 | end 36 | end), 37 | awful.button({}, 3, awful.tag.viewtoggle), 38 | awful.button({ modkey }, 3, function(t) 39 | if client.focus then 40 | client.focus:toggle_tag(t) 41 | end 42 | end), 43 | awful.button({}, 4, function(t) 44 | awful.tag.viewprev(t.screen) 45 | end), 46 | awful.button({}, 5, function(t) 47 | awful.tag.viewnext(t.screen) 48 | end) 49 | ), 50 | widget_template = { 51 | { 52 | { 53 | id = "icon_role", 54 | image = beautiful.tag_sel, 55 | valign = "center", 56 | halign = "center", 57 | widget = wibox.widget.imagebox, 58 | }, 59 | top = 2, 60 | bottom = 2, 61 | widget = wibox.container.margin, 62 | }, 63 | widget = wibox.container.background, 64 | shape = gears.shape.rectangle, 65 | create_callback = function(self, c3, index) 66 | update_tags(self, c3, index) 67 | end, 68 | update_callback = function(self, c3, index) 69 | update_tags(self, c3, index) 70 | end, 71 | }, 72 | }) 73 | end 74 | 75 | return get_taglist 76 | -------------------------------------------------------------------------------- /config/awesome/signals.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local vol = 4 | [[ str=$( pactl get-sink-volume @DEFAULT_SINK@ | awk -F' ' '{print $5}' | xargs | tr -d '[%]' ); printf "$(pactl get-sink-mute @DEFAULT_SINK@ | awk -F' ' '{print $2}' | xargs) ${str% *}\n" ]] 5 | local mic = 6 | [[ str=$( pactl get-source-volume @DEFAULT_SOURCE@ | awk -F' ' '{print $5}' | xargs | tr -d '[%]' ); printf "$(pactl get-source-mute @DEFAULT_SOURCE@ | awk -F' ' '{print $2}' | xargs) ${str% *}\n" ]] 7 | local bat = 8 | [[ charge=$(acpi | awk -F' ' '{print $4}' | xargs | tr -d '[%,]'); printf "$(acpi | awk -F' ' '{print $3}' | xargs | tr -d '[,]') ${charge% *}\n" ]] 9 | 10 | M.vol = function() 11 | awful.spawn.easy_async_with_shell(vol, function(out) 12 | local val = gears.string.split(out, " ") 13 | awesome.emit_signal("vol::value", val[1]:match("yes") and 1 or 0, tonumber(val[2])) 14 | end) 15 | end 16 | 17 | M.mic = function() 18 | awful.spawn.easy_async_with_shell(mic, function(out) 19 | local val = gears.string.split(out, " ") 20 | awesome.emit_signal("mic::value", val[1]:match("yes") and 1 or 0, tonumber(val[2])) 21 | end) 22 | end 23 | 24 | M.bat = function() 25 | awful.spawn.easy_async_with_shell(bat, function(out) 26 | local val = gears.string.split(out, " ") 27 | awesome.emit_signal("bat::value", val[1], tonumber(val[2])) 28 | end) 29 | end 30 | 31 | gears.timer({ 32 | timeout = 180, 33 | call_now = true, 34 | autostart = true, 35 | callback = function() 36 | M.bat() 37 | end, 38 | }) 39 | 40 | M.set_vol = function(val) 41 | awful.spawn.with_shell("pactl set-sink-volume @DEFAULT_SINK@ " .. val .. "%") 42 | end 43 | 44 | M.set_mic = function(val) 45 | awful.spawn.with_shell("pactl set-source-volume @DEFAULT_SOURCE@ " .. val .. "%") 46 | end 47 | 48 | M.toggle_vol_mute = function() 49 | awful.spawn.with_shell("pactl set-sink-mute @DEFAULT_SINK@ toggle") 50 | M.vol() 51 | end 52 | 53 | M.toggle_mic_mute = function() 54 | awful.spawn.with_shell("pactl set-source-mute @DEFAULT_SOURCE@ toggle") 55 | M.mic() 56 | end 57 | 58 | return M 59 | -------------------------------------------------------------------------------- /config/awesome/dashboard/sli.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.vol_sli = wibox.widget({ 4 | bar_shape = help.rrect(beautiful.br), 5 | bar_height = dpi(20), 6 | handle_width = 0, 7 | forced_height = dpi(20), 8 | maximum = 100, 9 | bar_color = "#00000000", 10 | widget = wibox.widget.slider, 11 | }) 12 | 13 | M.vol = wibox.widget({ 14 | { 15 | id = "prg", 16 | max_value = 100, 17 | value = M.vol_sli.value, 18 | forced_height = dpi(20), 19 | shape = help.rrect(beautiful.br), 20 | color = beautiful.pri, 21 | background_color = beautiful.bg3, 22 | widget = wibox.widget.progressbar, 23 | }, 24 | M.vol_sli, 25 | layout = wibox.layout.stack, 26 | }) 27 | 28 | M.mic_sli = wibox.widget({ 29 | bar_shape = help.rrect(beautiful.br), 30 | bar_height = dpi(20), 31 | handle_width = 0, 32 | forced_height = dpi(20), 33 | maximum = 100, 34 | bar_color = "#00000000", 35 | widget = wibox.widget.slider, 36 | }) 37 | 38 | M.mic = wibox.widget({ 39 | { 40 | id = "prg", 41 | max_value = 100, 42 | value = M.mic_sli.value, 43 | forced_height = dpi(20), 44 | shape = help.rrect(beautiful.br), 45 | color = beautiful.pri, 46 | background_color = beautiful.bg3, 47 | widget = wibox.widget.progressbar, 48 | }, 49 | M.mic_sli, 50 | layout = wibox.layout.stack, 51 | }) 52 | 53 | awesome.connect_signal("vol::value", function(mut, vol) 54 | local prg = M.vol:get_children_by_id("prg")[1] 55 | if mut == 0 then 56 | M.vol_sli.handle_color = beautiful.pri 57 | prg.color = beautiful.pri 58 | else 59 | M.vol_sli.handle_color = beautiful.fg2 60 | prg.color = beautiful.fg2 61 | end 62 | M.vol_sli.value = vol 63 | prg.value = vol 64 | end) 65 | 66 | M.vol_sli:connect_signal("property::value", function(val) 67 | M.vol:get_children_by_id("prg")[1].value = val.value 68 | sig.set_vol(val.value) 69 | end) 70 | 71 | awesome.connect_signal("mic::value", function(mut, vol) 72 | if mut == 0 then 73 | M.mic_sli.handle_color = beautiful.pri 74 | M.mic:get_children_by_id("prg")[1].color = beautiful.pri 75 | else 76 | M.mic_sli.handle_color = beautiful.fg2 77 | M.mic:get_children_by_id("prg")[1].color = beautiful.fg2 78 | end 79 | M.mic_sli.value = vol 80 | M.mic:get_children_by_id("prg")[1].value = vol 81 | end) 82 | 83 | M.mic_sli:connect_signal("property::value", function(val) 84 | sig.set_mic(val.value) 85 | M.mic:get_children_by_id("prg")[1].value = val.value 86 | end) 87 | 88 | return M 89 | -------------------------------------------------------------------------------- /config/awesome/dashboard/init.lua: -------------------------------------------------------------------------------- 1 | local wid = require("dashboard.wid") 2 | local sli = require("dashboard.sli") 3 | local top = require("dashboard.oth") 4 | 5 | local sliders = wibox.widget({ 6 | { 7 | { 8 | { 9 | { 10 | font = beautiful.icofont, 11 | markup = help.fg("\u{eb51}", beautiful.pri, "normal"), 12 | forced_width = dpi(25), 13 | widget = wibox.widget.textbox, 14 | align = "center", 15 | }, 16 | sli.vol, 17 | spacing = dpi(10), 18 | layout = wibox.layout.fixed.horizontal, 19 | }, 20 | { 21 | { 22 | font = beautiful.icofont, 23 | markup = help.fg("\u{eaf0}", beautiful.pri, "normal"), 24 | forced_width = dpi(25), 25 | widget = wibox.widget.textbox, 26 | align = "center", 27 | }, 28 | sli.mic, 29 | spacing = dpi(10), 30 | layout = wibox.layout.fixed.horizontal, 31 | }, 32 | spacing = dpi(10), 33 | layout = wibox.layout.flex.vertical, 34 | }, 35 | widget = wibox.container.margin, 36 | margins = dpi(20), 37 | }, 38 | bg = beautiful.bg2, 39 | shape = help.rrect(beautiful.br), 40 | widget = wibox.container.background, 41 | }) 42 | 43 | local buttons = wibox.widget({ 44 | { 45 | wid.vol, 46 | wid.mic, 47 | wid.nig, 48 | spacing = dpi(15), 49 | layout = wibox.layout.flex.horizontal, 50 | }, 51 | layout = wibox.layout.fixed.vertical, 52 | spacing = dpi(15), 53 | }) 54 | 55 | local dashboard = awful.popup({ 56 | widget = { 57 | { 58 | top.ses, 59 | { 60 | top.cal, 61 | top.wth, 62 | spacing = dpi(15), 63 | layout = wibox.layout.flex.horizontal, 64 | }, 65 | { 66 | sliders, 67 | wid.bat, 68 | spacing = dpi(15), 69 | layout = wibox.layout.flex.horizontal, 70 | }, 71 | buttons, 72 | wid.tra, 73 | spacing = dpi(15), 74 | layout = wibox.layout.fixed.vertical, 75 | }, 76 | margins = dpi(20), 77 | forced_width = beautiful.dashboard_width, 78 | widget = wibox.container.margin, 79 | }, 80 | visible = false, 81 | bg = gears.color.create_pattern({ 82 | type = "radial", 83 | from = { 50, 50, 40 }, 84 | to = { 55, 55, 300 }, 85 | stops = { { 0, beautiful.bg2 }, { 1, beautiful.bg } }, 86 | }), 87 | ontop = true, 88 | placement = function(c) 89 | return awful.placement.bottom_left(c, { 90 | honor_workarea = true, 91 | margins = { 92 | bottom = beautiful.useless_gap * 4, 93 | left = beautiful.useless_gap * 4, 94 | }, 95 | }) 96 | end, 97 | }) 98 | 99 | dashboard.toggle = function() 100 | dashboard.visible = not dashboard.visible 101 | end 102 | 103 | return dashboard 104 | -------------------------------------------------------------------------------- /config/awesome/theme/init.lua: -------------------------------------------------------------------------------- 1 | local help = require("help") 2 | local gfs = require("gears.filesystem") 3 | local theme_path = gfs.get_configuration_dir() .. "theme/" 4 | local scripts_path = gfs.get_configuration_dir() .. "scripts/" 5 | local img_path = gfs.get_configuration_dir() .. "img/" 6 | 7 | local theme = {} 8 | 9 | theme.theme_dir = theme_path 10 | theme.img_dir = img_path 11 | theme.scripts_dir = scripts_path 12 | local activethemefile = io.open(theme.theme_dir .. "activetheme", "r") 13 | if not activethemefile then 14 | return 15 | end 16 | theme.activetheme = activethemefile:read() 17 | activethemefile:close() 18 | help.merge(theme, require("theme." .. theme.activetheme .. ".colors")) 19 | theme.fontname = "JetBrainsMono NF" .. " " 20 | theme.barfontname = "JetBrainsMono NF" .. " " 21 | theme.icofontname = "tabler-icons" .. " " 22 | theme.fontsize = "10" 23 | theme.barfontsize = "12" 24 | theme.icofontsize = "15" 25 | theme.font = theme.fontname .. theme.fontsize 26 | theme.barfont = theme.barfontname .. theme.barfontsize 27 | theme.icofont = theme.icofontname .. theme.icofontsize 28 | theme.br = dpi(24) 29 | theme.wall = "" 30 | 31 | theme.dashboard_width = dpi(500) 32 | theme.bar_width = dpi(50) 33 | theme.fg_focus = theme.fg 34 | theme.fg_normal = theme.fg .. "40" 35 | theme.fg_minimize = theme.fg2 36 | 37 | theme.bg_normal = theme.bg2 38 | theme.bg_urgent = theme.err .. "40" 39 | theme.bg_minimize = theme.fg .. "10" 40 | theme.bg_focus = theme.fg2 .. "cc" 41 | 42 | theme.useless_gap = dpi(4) 43 | theme.snap_bg = theme.fg2 44 | theme.border_width = dpi(0) 45 | theme.border_color = theme.bg 46 | 47 | theme.titlebar_fg = theme.fg .. "40" 48 | theme.titlebar_fg_normal = theme.fg2 49 | theme.titlebar_fg_focus = theme.fg 50 | theme.titlebar_bg = theme.bg 51 | theme.titlebar_bg_normal = theme.bg 52 | theme.titlebar_font = theme.font 53 | 54 | theme.taglist_bg = theme.bg 55 | theme.taglist_bg_focus = theme.pri 56 | theme.taglist_font = theme.barfont 57 | 58 | theme.menu_bg_normal = theme.bg 59 | theme.menu_bg_focus = theme.bg2 60 | theme.menu_fg_normal = theme.fg 61 | theme.menu_font = theme.font 62 | theme.menu_border_color = theme.bg 63 | theme.menu_height = dpi(32) 64 | theme.menu_width = dpi(200) 65 | theme.menu_border_width = dpi(12) 66 | 67 | theme.tasklist_plain_task_name = true 68 | 69 | theme.bg_systray = theme.bg 70 | theme.systray_icon_spacing = dpi(10) 71 | theme.systray_base_size = dpi(26) 72 | 73 | theme.notification_bg = theme.bg 74 | theme.notification_fg = theme.fg 75 | theme.max_notification_width = dpi(225) 76 | theme.notification_width = dpi(225) 77 | theme.notification_max_height = dpi(100) 78 | theme.notification_icon_size = dpi(50) 79 | 80 | theme.separator_color = theme.fg2 81 | 82 | theme.titlebar_minimize_button_focus = gears.color.recolor_image(img_path .. "circle.svg", theme.ok) 83 | theme.titlebar_minimize_button_normal = gears.color.recolor_image(img_path .. "circle.svg", theme.fg2) 84 | theme.titlebar_close_button_normal = gears.color.recolor_image(img_path .. "circle.svg", theme.fg2) 85 | theme.titlebar_close_button_focus = gears.color.recolor_image(img_path .. "circle.svg", theme.err) 86 | theme.tag = img_path .. "tag.svg" 87 | theme.tag_sel = img_path .. "tag_sel.svg" 88 | theme.yt = img_path .. "yt.svg" 89 | 90 | return theme 91 | -------------------------------------------------------------------------------- /config/awesome/dashboard/wid.lua: -------------------------------------------------------------------------------- 1 | local signals = require("signals") 2 | 3 | local M = {} 4 | local on = beautiful.pri 5 | local off = beautiful.fg2 6 | 7 | local create_button = function(id, icon, comm, state) 8 | local button = wibox.widget({ 9 | { 10 | { 11 | id = id, 12 | widget = wibox.widget.textbox, 13 | font = beautiful.icofont, 14 | markup = icon, 15 | align = "center", 16 | }, 17 | widget = wibox.container.margin, 18 | top = dpi(20), 19 | bottom = dpi(20), 20 | }, 21 | bg = beautiful.bg2, 22 | fg = state or on, 23 | buttons = { 24 | awful.button({}, 1, function() 25 | comm() 26 | end), 27 | }, 28 | shape = help.rrect(dpi(99)), 29 | widget = wibox.container.background, 30 | }) 31 | return button 32 | end 33 | 34 | local nig = false 35 | local nig_callback = function() 36 | nig = not nig 37 | if nig then 38 | M.nig.fg = on 39 | awful.spawn.with_shell("redshift -x && redshift -O 5000K") 40 | else 41 | M.nig.fg = off 42 | awful.spawn.with_shell("redshift -x") 43 | end 44 | end 45 | 46 | M.vol = create_button("vol", "\u{eb51}", signals.toggle_vol_mute) 47 | M.mic = create_button("mic", "\u{eaf0}", signals.toggle_mic_mute) 48 | M.nig = create_button("nig", "\u{ea51}", nig_callback, off) 49 | 50 | M.emp = wibox.widget({ 51 | fg = on, 52 | bg = beautiful.bg2, 53 | shape = help.rrect(beautiful.br), 54 | widget = wibox.container.background, 55 | }) 56 | 57 | M.bat = wibox.widget({ 58 | { 59 | id = "prg", 60 | max_value = 100, 61 | value = 0.5, 62 | shape = help.rrect(beautiful.br), 63 | background_color = beautiful.bg2, 64 | forced_height = 20, 65 | widget = wibox.widget.progressbar, 66 | }, 67 | { 68 | { 69 | { 70 | id = "txt", 71 | font = beautiful.barfontname .. "18", 72 | widget = wibox.widget.textbox, 73 | }, 74 | { 75 | id = "ico", 76 | font = beautiful.icofont, 77 | widget = wibox.widget.textbox, 78 | }, 79 | layout = wibox.layout.fixed.horizontal, 80 | spacing = dpi(5), 81 | }, 82 | margins = dpi(20), 83 | widget = wibox.container.margin, 84 | }, 85 | layout = wibox.layout.stack, 86 | }) 87 | 88 | M.tra = wibox.widget({ 89 | base_size = beautiful.systray_base_size, 90 | widget = wibox.widget.systray, 91 | }) 92 | 93 | awesome.connect_signal("vol::value", function(mut, vol) 94 | if mut == 0 then 95 | M.vol.fg = on 96 | else 97 | M.vol.fg = off 98 | end 99 | end) 100 | 101 | awesome.connect_signal("mic::value", function(mut, vol) 102 | if mut == 0 then 103 | M.mic.fg = on 104 | else 105 | M.mic.fg = off 106 | end 107 | end) 108 | 109 | awesome.connect_signal("bat::value", function(status, charge) 110 | local prg = M.bat:get_children_by_id("prg")[1] 111 | 112 | prg.value = charge 113 | if charge < 20 and status == "Discharging" then 114 | prg.color = beautiful.err 115 | else 116 | prg.color = beautiful.ok 117 | end 118 | if status == "Charging" then 119 | M.bat:get_children_by_id("ico")[1].markup = help.fg("\u{ea38}", beautiful.bg, "1000") 120 | else 121 | M.bat:get_children_by_id("ico")[1].markup = "" 122 | end 123 | M.bat:get_children_by_id("txt")[1].markup = help.fg(charge .. "%", beautiful.bg, "1000") 124 | end) 125 | 126 | return M 127 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | PACKAGES="awesome-git picom-git redshift kitty rofi xclip xorg-xwininfo scrot ttf-jetbrains-mono-nerd noto-fonts noto-fonts-cjk networkmanager betterlockscreen brightnessctl acpi zsh gvfs gvfs-mtp thunar lsd zoxide bat lxappearance jq curl p7zip sxiv" 6 | 7 | if [ -t 1 ]; then 8 | is_tty() { 9 | true 10 | } 11 | else 12 | is_tty() { 13 | false 14 | } 15 | fi 16 | 17 | setup_color() { 18 | if ! is_tty; then 19 | # Reset 20 | Normal='' 21 | 22 | # Regular Colors 23 | Black='' 24 | Red='' 25 | Green='' 26 | Yellow='' 27 | Blue='' 28 | Purple='' 29 | Cyan='' 30 | White='' 31 | 32 | # Bold 33 | BBlack='' 34 | BRed='' 35 | BGreen='' 36 | BYellow='' 37 | BBlue='' 38 | BPurple='' 39 | BCyan='' 40 | BWhite='' 41 | 42 | # Undeline 43 | UBlack='' 44 | URed='' 45 | UGreen='' 46 | UYellow='' 47 | UBlue='' 48 | UPurple='' 49 | UCyan='' 50 | UWhite='' 51 | 52 | # Background 53 | On_Black='' 54 | On_Red='' 55 | On_Green='' 56 | On_Yellow='' 57 | On_Blue='' 58 | On_Purple='' 59 | On_Cyan='' 60 | On_White='' 61 | return 62 | fi 63 | 64 | # Reset 65 | Normal='\033[0m' 66 | 67 | # Regular Colors 68 | Black='\033[0;30m' 69 | Red='\033[0;31m' 70 | Green='\033[0;32m' 71 | Yellow='\033[0;33m' 72 | Blue='\033[0;34m' 73 | Purple='\033[0;35m' 74 | Cyan='\033[0;36m' 75 | White='\033[0;37m' 76 | 77 | # Bold 78 | BBlack='\033[1;30m' 79 | BRed='\033[1;31m' 80 | BGreen='\033[1;32m' 81 | BYellow='\033[1;33m' 82 | BBlue='\033[1;34m' 83 | BPurple='\033[1;35m' 84 | BCyan='\033[1;36m' 85 | BWhite='\033[1;37m' 86 | 87 | # Underline 88 | UBlack='\033[4;30m' 89 | URed='\033[4;31m' 90 | UGreen='\033[4;32m' 91 | UYellow='\033[4;33m' 92 | UBlue='\033[4;34m' 93 | UPurple='\033[4;35m' 94 | UCyan='\033[4;36m' 95 | UWhite='\033[4;37m' 96 | 97 | # Background 98 | On_Black='\033[40m' 99 | On_Red='\033[41m' 100 | On_Green='\033[42m' 101 | On_Yellow='\033[43m' 102 | On_Blue='\033[44m' 103 | On_Purple='\033[45m' 104 | On_Cyan='\033[46m' 105 | On_White='\033[47m' 106 | } 107 | 108 | print_style() { 109 | printf "%s$*${Normal}\n" 110 | } 111 | 112 | error() { 113 | print_style "${Red}err: $*" 114 | exit 1 115 | } 116 | 117 | setup_policromia() { 118 | print_style ${Yellow} "downloading and installing packages" 119 | sudo pacman -Syy 120 | paru -S ${PACKAGES} 121 | cd /tmp 122 | print_style ${Yellow} "cloning policromia" 123 | git clone --depth 1 --recurse-submodules --shallow-submodules https://github.com/mdmrk/policromia 124 | cd policromia 125 | print_style ${Yellow} "installing" 126 | mkdir -p ~/.config/awesome && cp -r config/awesome/* ~/.config/awesome 127 | cp ~/.config/awesome/env.example.lua ~/.config/awesome/env.lua 128 | mkdir -p ~/.config/picom && cp -r config/picom/* ~/.config/picom 129 | mkdir -p ~/.config/kitty && cp -r config/kitty/* ~/.config/kitty 130 | mkdir -p ~/.config/rofi && cp -r config/rofi/* ~/.config/rofi 131 | mkdir -p ~/.local/share/fonts && cp -r fonts/* ~/.local/share/fonts 132 | mkdir -p ~/.themes && 7z x config/gtk/themes.7z -oconfig/gtk && rm config/gtk/themes.7z && cp -r config/gtk/* ~/.themes 133 | chmod +x ~/.config/awesome/scripts/*.sh 134 | print_style ${BYellow} "installation complete" 135 | print_success 136 | } 137 | 138 | print_title() { 139 | print_style "${Yellow} ▄▄▄· ▄▄▌ ▪ ▄▄· ▄▄▄ • ▌ ▄ ·. ▪ ▄▄▄· " 140 | print_style "${Yellow}▐█ ▄█▪ ██• ██ ▐█ ▌▪▀▄ █·▪ ·██ ▐███▪██ ▐█ ▀█ " 141 | print_style "${Yellow} ██▀· ▄█▀▄ ██▪ ▐█·██ ▄▄▐▀▀▄ ▄█▀▄ ▐█ ▌▐▌▐█·▐█·▄█▀▀█ " 142 | print_style "${Yellow}▐█▪·•▐█▌.▐▌▐█▌▐▌▐█▌▐███▌▐█•█▌▐█▌.▐▌██ ██▌▐█▌▐█▌▐█ ▪▐▌" 143 | print_style "${Yellow}.▀ ▀█▄▀▪.▀▀▀ ▀▀▀·▀▀▀ .▀ ▀ ▀█▄▀▪▀▀ █▪▀▀▀▀▀▀ ▀ ▀ " 144 | } 145 | 146 | print_success() { 147 | print_style "${Green}success!" 148 | print_style "${UGreen}rebooting is recommended" 149 | } 150 | 151 | main() { 152 | setup_color 153 | print_title 154 | setup_policromia # Main workflow 155 | } 156 | 157 | main "$@" 158 | -------------------------------------------------------------------------------- /config/rofi/power.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | modi: "drun"; 3 | show-icons: false; 4 | drun-display-format: "{name}"; 5 | font: "JetBrainsMono Nerd Font Bold 10"; 6 | } 7 | 8 | @theme "colors.rasi" 9 | 10 | /*****----- Main Window -----*****/ 11 | window { 12 | transparency: "real"; 13 | location: center; 14 | anchor: center; 15 | fullscreen: false; 16 | width: 700px; 17 | x-offset: 0px; 18 | y-offset: 0px; 19 | enabled: true; 20 | margin: 0px; 21 | padding: 0px; 22 | background-color: @bg; 23 | cursor: "default"; 24 | } 25 | 26 | /*****----- Main Box -----*****/ 27 | mainbox { 28 | enabled: true; 29 | spacing: 20px; 30 | margin: 0px; 31 | padding: 20px; 32 | border: 0px solid; 33 | border-color: @selected; 34 | background-color: transparent; 35 | children: [ "listview" ]; 36 | } 37 | 38 | /*****----- Listview -----*****/ 39 | listview { 40 | enabled: true; 41 | columns: 3; 42 | lines: 3; 43 | cycle: true; 44 | dynamic: true; 45 | scrollbar: false; 46 | layout: vertical; 47 | reverse: false; 48 | fixed-height: true; 49 | fixed-columns: true; 50 | 51 | spacing: 0px; 52 | margin: 0px; 53 | padding: 0px; 54 | border: 0px solid; 55 | border-radius: 0px; 56 | border-color: @selected; 57 | background-color: transparent; 58 | text-color: @fg; 59 | cursor: "default"; 60 | } 61 | scrollbar { 62 | handle-width: 5px ; 63 | handle-color: @selected; 64 | border-radius: 0px; 65 | background-color: @background-alt; 66 | } 67 | 68 | /*****----- Elements -----*****/ 69 | element { 70 | enabled: true; 71 | spacing: 15px; 72 | margin: 0px; 73 | padding: 20px; 74 | border: 0px solid; 75 | border-radius: 24px; 76 | border-color: @selected; 77 | background-color: transparent; 78 | text-color: @fg; 79 | orientation: vertical; 80 | cursor: pointer; 81 | } 82 | element normal.normal { 83 | background-color: transparent; 84 | text-color: @foreground; 85 | } 86 | element selected.normal { 87 | background-color: @tr; 88 | text-color: @foreground; 89 | } 90 | 91 | element-text { 92 | background-color: transparent; 93 | text-color: inherit; 94 | highlight: inherit; 95 | cursor: inherit; 96 | vertical-align: 0.5; 97 | horizontal-align: 0.5; 98 | } 99 | 100 | /*****----- Message -----*****/ 101 | error-message { 102 | padding: 15px; 103 | border: 2px solid; 104 | border-radius: 12px; 105 | border-color: @selected; 106 | background-color: @bg; 107 | text-color: @fg; 108 | } 109 | textbox { 110 | background-color: transparent; 111 | text-color: @fg; 112 | vertical-align: 0.5; 113 | horizontal-align: 0.0; 114 | highlight: none; 115 | } 116 | -------------------------------------------------------------------------------- /config/rofi/theme.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | modi: "drun"; 3 | show-icons: false; 4 | drun-display-format: "{name}"; 5 | font: "JetBrainsMono Nerd Font Bold 10"; 6 | } 7 | 8 | @theme "colors.rasi" 9 | 10 | /*****----- Main Window -----*****/ 11 | window { 12 | transparency: "real"; 13 | location: center; 14 | anchor: center; 15 | fullscreen: false; 16 | width: 300px; 17 | x-offset: 0px; 18 | y-offset: 0px; 19 | enabled: true; 20 | margin: 0px; 21 | padding: 0px; 22 | background-color: @bg; 23 | cursor: "default"; 24 | } 25 | 26 | /*****----- Main Box -----*****/ 27 | mainbox { 28 | enabled: true; 29 | spacing: 20px; 30 | margin: 0px; 31 | padding: 20px; 32 | border: 0px solid; 33 | border-color: @selected; 34 | background-color: transparent; 35 | children: [ "listview" ]; 36 | } 37 | 38 | /*****----- Listview -----*****/ 39 | listview { 40 | enabled: true; 41 | columns: 1; 42 | lines: 3; 43 | cycle: true; 44 | dynamic: true; 45 | scrollbar: false; 46 | layout: vertical; 47 | reverse: false; 48 | fixed-height: true; 49 | fixed-columns: true; 50 | 51 | spacing: 0px; 52 | margin: 0px; 53 | padding: 0px; 54 | border: 0px solid; 55 | border-radius: 0px; 56 | border-color: @selected; 57 | background-color: transparent; 58 | text-color: @fg; 59 | cursor: "default"; 60 | } 61 | scrollbar { 62 | handle-width: 5px ; 63 | handle-color: @selected; 64 | border-radius: 0px; 65 | background-color: @background-alt; 66 | } 67 | 68 | /*****----- Elements -----*****/ 69 | element { 70 | enabled: true; 71 | spacing: 15px; 72 | margin: 0px; 73 | padding: 20px; 74 | border: 0px solid; 75 | border-radius: 24px; 76 | border-color: @selected; 77 | background-color: transparent; 78 | text-color: @fg; 79 | orientation: vertical; 80 | cursor: pointer; 81 | } 82 | element normal.normal { 83 | background-color: transparent; 84 | text-color: @foreground; 85 | } 86 | element selected.normal { 87 | background-color: @tr; 88 | text-color: @foreground; 89 | } 90 | 91 | element-text { 92 | background-color: transparent; 93 | text-color: inherit; 94 | highlight: inherit; 95 | cursor: inherit; 96 | vertical-align: 0.5; 97 | horizontal-align: 0.5; 98 | } 99 | 100 | /*****----- Message -----*****/ 101 | error-message { 102 | padding: 15px; 103 | border: 2px solid; 104 | border-radius: 12px; 105 | border-color: @selected; 106 | background-color: @bg; 107 | text-color: @fg; 108 | } 109 | textbox { 110 | background-color: transparent; 111 | text-color: @fg; 112 | vertical-align: 0.5; 113 | horizontal-align: 0.0; 114 | highlight: none; 115 | } 116 | -------------------------------------------------------------------------------- /config/rofi/wallpaper.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | modi: "drun"; 3 | show-icons: false; 4 | drun-display-format: "{name}"; 5 | font: "JetBrainsMono Nerd Font Bold 10"; 6 | } 7 | 8 | @theme "colors.rasi" 9 | 10 | /*****----- Main Window -----*****/ 11 | window { 12 | transparency: "real"; 13 | location: center; 14 | anchor: center; 15 | fullscreen: false; 16 | width: 700px; 17 | x-offset: 0px; 18 | y-offset: 0px; 19 | enabled: true; 20 | margin: 0px; 21 | padding: 0px; 22 | background-color: @bg; 23 | cursor: "default"; 24 | } 25 | 26 | /*****----- Main Box -----*****/ 27 | mainbox { 28 | enabled: true; 29 | spacing: 20px; 30 | margin: 0px; 31 | padding: 20px; 32 | border: 0px solid; 33 | border-color: @selected; 34 | background-color: transparent; 35 | children: [ "listview" ]; 36 | } 37 | 38 | /*****----- Listview -----*****/ 39 | listview { 40 | enabled: true; 41 | columns: 3; 42 | lines: 3; 43 | cycle: true; 44 | dynamic: true; 45 | scrollbar: false; 46 | layout: vertical; 47 | reverse: false; 48 | fixed-height: true; 49 | fixed-columns: true; 50 | 51 | spacing: 0px; 52 | margin: 0px; 53 | padding: 0px; 54 | border: 0px solid; 55 | border-radius: 0px; 56 | border-color: @selected; 57 | background-color: transparent; 58 | text-color: @fg; 59 | cursor: "default"; 60 | } 61 | scrollbar { 62 | handle-width: 5px ; 63 | handle-color: @selected; 64 | border-radius: 0px; 65 | background-color: @background-alt; 66 | } 67 | 68 | /*****----- Elements -----*****/ 69 | element { 70 | enabled: true; 71 | spacing: 15px; 72 | margin: 0px; 73 | padding: 20px; 74 | border: 0px solid; 75 | border-radius: 24px; 76 | border-color: @selected; 77 | background-color: transparent; 78 | text-color: @fg; 79 | orientation: vertical; 80 | cursor: pointer; 81 | } 82 | element normal.normal { 83 | background-color: transparent; 84 | text-color: @foreground; 85 | } 86 | element selected.normal { 87 | background-color: @tr; 88 | text-color: @foreground; 89 | } 90 | 91 | element-text { 92 | background-color: transparent; 93 | text-color: inherit; 94 | highlight: inherit; 95 | cursor: inherit; 96 | vertical-align: 0.5; 97 | horizontal-align: 0.5; 98 | } 99 | 100 | /*****----- Message -----*****/ 101 | error-message { 102 | padding: 15px; 103 | border: 2px solid; 104 | border-radius: 12px; 105 | border-color: @selected; 106 | background-color: @bg; 107 | text-color: @fg; 108 | } 109 | textbox { 110 | background-color: transparent; 111 | text-color: @fg; 112 | vertical-align: 0.5; 113 | horizontal-align: 0.0; 114 | highlight: none; 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # policromia 4 | 5 | awesomewm setup 6 | 7 |
8 | 9 | ## table of contents 10 | 11 | - [details](#details) 12 | - [themes](#themes) 13 | - [gruvbox](#gruvbox) 14 | - [rose pine](#rose-pine) 15 | - [catppuccin](#catppuccin) 16 | - [add a theme](#add-a-theme) 17 | - [keybindings](#keybindings) 18 | - [setup](#setup) 19 | - [automatic](#automatic) 20 | - [manual](#manual) 21 | 22 | ## details 23 | 24 | - os · [arch linux](https://archlinux.org/) 25 | - shell · [zsh](https://www.zsh.org/) 26 | - wm · [awesomewm](https://awesomewm.org/) 27 | - terminal · [kitty](https://sw.kovidgoyal.net/kitty/) 28 | - menus · [rofi](https://github.com/davatorium/rofi) 29 | 30 | ## themes 31 | 32 | ### gruvbox 33 | 34 |
35 | screenshot 36 |

37 | 38 |

39 |
40 | 41 | ### rose pine 42 | 43 |
44 | screenshot 45 |

46 | 47 |

48 |
49 | 50 | ### catppuccin 51 | 52 |
53 | screenshot 54 |

55 | 56 |

57 |
58 | 59 | #### add a theme 60 | 61 | themes reside under the directory `.config/awesome/theme/{theme_name}`. Each 62 | theme has a file containing the color scheme imported by a certain application 63 | and a folder named `wallpapers`. 64 | 65 | - `colors.lua` · awesomewm 66 | - `colors.rasi` · rofi 67 | - `colors.gtk` · gtk 2/3 68 | - `colors.nvim` · neovim [nvchad](https://github.com/NvChad/NvChad) 69 | - `colors.conf` · kitty 70 | 71 | > [!TIP] 72 | > copy an existing theme folder and modify the values in each file accordingly 73 | 74 | ## keybindings 75 | 76 | | Keys | Action | 77 | | :-------------------------------------------------------- | :------------------------ | 78 | | Super + d | Toggle dashboard | 79 | | Super + e | Open application launcher | 80 | | Super + Shift + e | Open theme switcher | 81 | | Super + Shift + s | Cropped screenshot | 82 | | Super + t | Toggle on top | 83 | | Super + f | Toggle fullscreen | 84 | | Super + s | Toggle floating | 85 | | Super + Tab | Focus next | 86 | | Super + Control + + | Increase window opacity | 87 | | Super + Control + - | Decrease window opacity | 88 | | Super + Control + Return | Reset window opacity | 89 | 90 | ## setup 91 | 92 | ### automatic 93 | 94 | > [!NOTE] 95 | > you won't be asked for any customization parameters, so consider tweaking before running 96 | 97 | ```sh 98 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/mdmrk/policromia/main/install.sh)" 99 | ``` 100 | 101 | ### manual 102 | 103 | #### dependencies 104 | 105 | Using [paru](https://github.com/Morganamilo/paru) as the AUR helper 106 | 107 | ```sh 108 | paru -S awesome-git picom-git redshift kitty rofi xclip xorg-xwininfo scrot ttf-jetbrains-mono-nerd noto-fonts noto-fonts-cjk networkmanager betterlockscreen brightnessctl acpi zsh gvfs gvfs-mtp thunar lsd zoxide bat lxappearance jq curl p7zip sxiv 109 | ``` 110 | 111 | #### clone the repo 112 | 113 | ```sh 114 | git clone --depth 1 --recurse-submodules --shallow-submodules https://github.com/mdmrk/policromia 115 | cd policromia 116 | ``` 117 | 118 | #### install 119 | 120 | ```sh 121 | mkdir -p ~/.config/awesome && cp -r config/awesome/* ~/.config/awesome 122 | cp ~/.config/awesome/env.example.lua ~/.config/awesome/env.lua 123 | mkdir -p ~/.config/picom && cp -r config/picom/* ~/.config/picom 124 | mkdir -p ~/.config/kitty && cp -r config/kitty/* ~/.config/kitty 125 | mkdir -p ~/.config/rofi && cp -r config/rofi/* ~/.config/rofi 126 | mkdir -p ~/.local/share/fonts && cp -r fonts/* ~/.local/share/fonts 127 | mkdir -p ~/.themes && 7z x config/gtk/themes.7z -oconfig/gtk && rm config/gtk/themes.7z && cp -r config/gtk/* ~/.themes 128 | chmod +x ~/.config/awesome/scripts/*.sh 129 | ``` 130 | -------------------------------------------------------------------------------- /config/awesome/bar/sys.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- Volume 4 | M.vol = wibox.widget({ 5 | font = beautiful.icofont, 6 | align = "center", 7 | widget = wibox.widget.textbox, 8 | }) 9 | 10 | -- Battery 11 | M.battery = wibox.widget({ 12 | font = beautiful.icofontname .. "18", 13 | align = "center", 14 | widget = wibox.widget.textbox, 15 | }) 16 | 17 | -- Clock 18 | M.clock = wibox.widget({ 19 | font = beautiful.barfont, 20 | format = help.fg("%H\n%M", beautiful.fg, "bold"), 21 | refresh = 1, 22 | align = "center", 23 | valign = "center", 24 | widget = wibox.widget.textclock, 25 | }) 26 | 27 | local cal_btn = function(icon, comm, margin) 28 | local button = wibox.widget({ 29 | { 30 | { 31 | widget = wibox.widget.textbox, 32 | font = beautiful.icofont, 33 | markup = help.fg(icon, beautiful.fg, "normal"), 34 | halign = "center", 35 | align = "center", 36 | }, 37 | margins = margin, 38 | widget = wibox.container.margin, 39 | }, 40 | bg = beautiful.bg2, 41 | buttons = { awful.button({}, 1, function() 42 | comm() 43 | end) }, 44 | shape = gears.shape.circle, 45 | widget = wibox.container.background, 46 | }) 47 | button:connect_signal("mouse::enter", function() 48 | button.bg = beautiful.bg3 49 | end) 50 | button:connect_signal("mouse::leave", function() 51 | button.bg = beautiful.bg2 52 | end) 53 | return button 54 | end 55 | 56 | local day = tonumber(os.date("%d")) 57 | local month = tonumber(os.date("%m")) 58 | local year = tonumber(os.date("%Y")) 59 | local function deco_cell(widget, flag, date) 60 | if flag == "header" then 61 | widget:set_markup(help.fg(widget:get_text(), beautiful.pri, "1000")) 62 | return wibox.widget({ 63 | nil, --cal_btn("\u{f0d9}", nil, { left = dpi(8), right = dpi(8) }), 64 | widget, 65 | nil, --cal_btn("\u{f0da}", nil, { left = dpi(8), right = dpi(8) }), 66 | layout = wibox.layout.align.horizontal, 67 | }) 68 | elseif flag == "month" then 69 | return widget 70 | elseif flag == "weekday" then 71 | local ret = wibox.widget({ 72 | markup = help.fg(widget:get_text(), beautiful.fg, "bold"), 73 | halign = "center", 74 | widget = wibox.widget.textbox, 75 | }) 76 | return ret 77 | end 78 | local today = date.day == day and date.month == month and date.year == year 79 | local ret = wibox.widget({ 80 | { 81 | { 82 | nil, 83 | { 84 | markup = today and help.fg(widget:get_text(), beautiful.bg, "bold") 85 | or help.fg(widget:get_text(), beautiful.fg, "normal"), 86 | halign = "center", 87 | widget = wibox.widget.textbox, 88 | }, 89 | nil, 90 | layout = wibox.layout.align.horizontal, 91 | }, 92 | widget = wibox.container.margin, 93 | margins = dpi(5), 94 | }, 95 | bg = today and beautiful.pri or beautiful.bg, 96 | shape = gears.shape.circle, 97 | widget = wibox.container.background, 98 | }) 99 | return ret 100 | end 101 | 102 | M.cal = awful.popup({ 103 | widget = { 104 | { 105 | date = os.date("*t"), 106 | font = beautiful.font, 107 | week_numbers = false, 108 | start_sunday = false, 109 | spacing = dpi(5), 110 | fn_embed = deco_cell, 111 | widget = wibox.widget.calendar.month, 112 | }, 113 | margins = dpi(20), 114 | widget = wibox.container.margin, 115 | }, 116 | shape = help.rrect(beautiful.br), 117 | bg = beautiful.bg, 118 | fg = beautiful.fg, 119 | visible = false, 120 | ontop = true, 121 | placement = function(c) 122 | return awful.placement.bottom_left(c, { 123 | honor_workarea = true, 124 | margins = { 125 | bottom = beautiful.useless_gap * 4, 126 | left = beautiful.useless_gap * 4, 127 | }, 128 | }) 129 | end, 130 | }) 131 | 132 | M.cal.toggle = function() 133 | M.cal.visible = not M.cal.visible 134 | end 135 | 136 | M.clock:buttons(gears.table.join(awful.button({}, 1, function() 137 | M.cal.toggle() 138 | end))) 139 | 140 | awesome.connect_signal("bat::value", function(status, charge) 141 | local icon = "\u{f668}" 142 | 143 | if charge >= 80 then 144 | icon = "\u{f721}" 145 | elseif charge >= 55 and charge < 80 then 146 | icon = "\u{f720}" 147 | elseif charge >= 20 and charge < 55 then 148 | icon = "\u{f71f}" 149 | elseif charge >= 10 and charge < 20 then 150 | icon = "\u{f71e}" 151 | else 152 | icon = "\u{ea34}" 153 | end 154 | if status == "Charging" or status == "Full" then 155 | icon = help.fg(icon, beautiful.ok, "normal") 156 | if charge >= 90 then 157 | naughty.notify({ 158 | title = "Battery charged", 159 | text = charge .. "% full", 160 | timeout = 4, 161 | }) 162 | end 163 | elseif charge < 20 and status == "Discharging" then 164 | icon = help.fg(icon, beautiful.err, "normal") 165 | naughty.notify({ 166 | title = "Low battery", 167 | text = charge .. "% battery remaining", 168 | preset = naughty.config.presets.critical, 169 | timeout = 4, 170 | }) 171 | end 172 | M.battery.markup = icon 173 | end) 174 | 175 | awesome.connect_signal("vol::value", function(mut, vol) 176 | if mut == 0 then 177 | M.vol.opacity = 1 178 | M.vol.markup = "\u{eb51}" 179 | else 180 | M.vol.opacity = 0.25 181 | M.vol.markup = "\u{eb50}" 182 | end 183 | end) 184 | 185 | return M 186 | -------------------------------------------------------------------------------- /config/awesome/keys.lua: -------------------------------------------------------------------------------- 1 | local signals = require("signals") 2 | 3 | -- Variables 4 | local keys = {} 5 | 6 | local mod = "Mod4" 7 | local tags = 5 8 | keys.tags = tags 9 | 10 | -- Keybindings 11 | keys.globalkeys = gears.table.join( 12 | -- Awesome 13 | awful.key({ mod, "Shift" }, "r", awesome.restart), 14 | awful.key({ mod }, "d", function() 15 | dashboard.toggle() 16 | end), 17 | 18 | --Hardware ( Laptop Users ) 19 | awful.key({}, "XF86MonBrightnessUp", function() 20 | awful.spawn.with_shell("brightnessctl set 5%+ -q") 21 | end), 22 | awful.key({}, "XF86MonBrightnessDown", function() 23 | awful.spawn.with_shell("brightnessctl set 5%- -q") 24 | end), 25 | awful.key({}, "XF86AudioRaiseVolume", function() 26 | awful.spawn.with_shell("pactl set-sink-volume @DEFAULT_SINK@ +5%") 27 | signals.vol() 28 | end), 29 | awful.key({}, "XF86AudioLowerVolume", function() 30 | awful.spawn.with_shell("pactl set-sink-volume @DEFAULT_SINK@ -5%") 31 | signals.vol() 32 | end), 33 | awful.key({}, "XF86AudioMute", function() 34 | signals.toggle_vol_mute() 35 | end), 36 | 37 | -- Window management 38 | awful.key({ mod }, "Tab", function() 39 | awful.client.focus.byidx(1) 40 | end), 41 | awful.key({ mod }, "t", function(c) 42 | c.ontop = not c.ontop 43 | end, { description = "toggle keep on top", group = "client" }), 44 | awful.key({ mod, "Shift" }, "t", function(c) 45 | c.sticky = not c.sticky 46 | end, { description = "toggle keep on top", group = "client" }), 47 | awful.key({ mod }, "Right", function() 48 | awful.tag.incmwfact(0.025) 49 | end), 50 | awful.key({ mod }, "Left", function() 51 | awful.tag.incmwfact(-0.025) 52 | end), 53 | awful.key({ mod }, "Up", function() 54 | awful.client.incwfact(0.05) 55 | end), 56 | awful.key({ mod }, "Down", function() 57 | awful.client.incwfact(-0.05) 58 | end), 59 | awful.key({ mod, "Shift" }, "j", function() 60 | awful.client.swap.byidx(1) 61 | end, { description = "swap with next client by index", group = "client" }), 62 | awful.key({ mod, "Shift" }, "k", function() 63 | awful.client.swap.byidx(-1) 64 | end, { description = "swap with previous client by index", group = "client" }), 65 | awful.key({ mod, "Control" }, "j", function() 66 | awful.screen.focus_relative(1) 67 | end, { description = "focus the next screen", group = "screen" }), 68 | awful.key({ mod, "Control" }, "k", function() 69 | awful.screen.focus_relative(-1) 70 | end, { description = "focus the previous screen", group = "screen" }), 71 | awful.key({ mod }, "j", function() 72 | awful.client.focus.bydirection("down") 73 | end), 74 | awful.key({ mod }, "h", function() 75 | awful.client.focus.bydirection("left") 76 | end), 77 | awful.key({ mod }, "k", function() 78 | awful.client.focus.bydirection("up") 79 | end), 80 | awful.key({ mod }, "l", function() 81 | awful.client.focus.bydirection("right") 82 | end), 83 | 84 | -- Opacity 85 | awful.key({ mod, "Control" }, "KP_Subtract", function() 86 | awful.spawn("picom-trans -c -o -3", false) 87 | end), 88 | awful.key({ mod, "Control" }, "KP_Add", function() 89 | awful.spawn("picom-trans -c -o +3", false) 90 | end), 91 | awful.key({ mod, "Control" }, "Return", function() 92 | awful.spawn("picom-trans -c -d", false) 93 | end), 94 | 95 | -- Applications 96 | awful.key({ mod }, "Return", function() 97 | awful.util.spawn("kitty") 98 | end), 99 | awful.key({ mod }, "e", function() 100 | awful.util.spawn("rofi -show drun -show-icons -theme apps") 101 | end), 102 | awful.key({ mod, "Shift" }, "e", function() 103 | awful.util.spawn(awful.spawn.easy_async_with_shell("sh " .. beautiful.scripts_dir .. "theme.sh")) 104 | end), 105 | -- Screenshots 106 | awful.key({ mod, "Shift" }, "s", function() 107 | help.screenshot() 108 | end) 109 | ) 110 | 111 | -- Keyboard Control 112 | keys.clientkeys = gears.table.join( 113 | awful.key({ mod }, "q", function(c) 114 | c:kill() 115 | end), 116 | awful.key({ mod }, "f", function(c) 117 | c.fullscreen = not c.fullscreen 118 | c:raise() 119 | end), 120 | awful.key({ mod }, "s", function() 121 | awful.client.floating.toggle() 122 | end) 123 | ) 124 | 125 | -- Mouse controls 126 | keys.clientbuttons = gears.table.join( 127 | awful.button({}, 1, function(c) 128 | client.focus = c 129 | end), 130 | awful.button({ mod }, 1, function() 131 | awful.mouse.client.move() 132 | end), 133 | awful.button({ mod }, 2, function(c) 134 | c:kill() 135 | end), 136 | awful.button({ mod }, 3, function() 137 | awful.mouse.client.resize() 138 | end) 139 | ) 140 | 141 | for i = 1, tags do 142 | keys.globalkeys = gears.table.join( 143 | keys.globalkeys, 144 | -- View tag 145 | awful.key({ mod }, "#" .. i + 9, function() 146 | local tag = awful.screen.focused().tags[i] 147 | if tag then 148 | tag:view_only() 149 | end 150 | end), 151 | 152 | -- Move window to tag 153 | awful.key({ mod, "Shift" }, "#" .. i + 9, function() 154 | if client.focus then 155 | local tag = client.focus.screen.tags[i] 156 | if tag then 157 | client.focus:move_to_tag(tag) 158 | end 159 | end 160 | end) 161 | ) 162 | end 163 | 164 | -- Set globalkeys 165 | root.keys(keys.globalkeys) 166 | 167 | return keys 168 | -------------------------------------------------------------------------------- /config/rofi/apps.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | modi: "drun"; 3 | show-icons: true; 4 | display-drun: " "; 5 | drun-display-format: "{name}"; 6 | font: "JetBrainsMono Nerd Font Bold 10"; 7 | } 8 | 9 | @theme "colors.rasi" 10 | 11 | /*****----- Main Window -----*****/ 12 | window { 13 | transparency: "real"; 14 | location: center; 15 | anchor: center; 16 | fullscreen: false; 17 | width: 700px; 18 | x-offset: 0px; 19 | y-offset: 0px; 20 | enabled: true; 21 | margin: 0px; 22 | padding: 0px; 23 | background-color: @bg; 24 | cursor: "default"; 25 | } 26 | 27 | /*****----- Main Box -----*****/ 28 | mainbox { 29 | enabled: true; 30 | spacing: 20px; 31 | margin: 0px; 32 | padding: 20px; 33 | border: 0px solid; 34 | border-color: @selected; 35 | background-color: transparent; 36 | children: [ "inputbar", "listview" ]; 37 | } 38 | 39 | /*****----- Inputbar -----*****/ 40 | inputbar { 41 | enabled: true; 42 | spacing: 10px; 43 | margin: 0px 150px; 44 | padding: 15px 20px; 45 | border: 0px solid; 46 | border-radius: 999px; 47 | border-color: @selected; 48 | background-color: @al; 49 | text-color: @fg; 50 | children: [ "prompt", "entry" ]; 51 | } 52 | 53 | prompt { 54 | enabled: true; 55 | background-color: transparent; 56 | text-color: inherit; 57 | } 58 | textbox-prompt-colon { 59 | enabled: true; 60 | expand: false; 61 | str: "::"; 62 | background-color: transparent; 63 | text-color: inherit; 64 | } 65 | entry { 66 | enabled: true; 67 | background-color: transparent; 68 | text-color: inherit; 69 | cursor: text; 70 | placeholder: "Search"; 71 | placeholder-color: inherit; 72 | font: "JetBrainsMono Nerd Font Medium 10"; 73 | } 74 | 75 | /*****----- Listview -----*****/ 76 | listview { 77 | enabled: true; 78 | columns: 4; 79 | lines: 5; 80 | cycle: true; 81 | dynamic: true; 82 | scrollbar: false; 83 | layout: vertical; 84 | reverse: false; 85 | fixed-height: true; 86 | fixed-columns: true; 87 | 88 | spacing: 0px; 89 | margin: 0px; 90 | padding: 0px; 91 | border: 0px solid; 92 | border-radius: 0px; 93 | border-color: @selected; 94 | background-color: transparent; 95 | text-color: @fg; 96 | cursor: "default"; 97 | } 98 | scrollbar { 99 | handle-width: 5px ; 100 | handle-color: @selected; 101 | border-radius: 0px; 102 | background-color: @background-alt; 103 | } 104 | 105 | /*****----- Elements -----*****/ 106 | element { 107 | enabled: true; 108 | spacing: 15px; 109 | margin: 0px; 110 | padding: 20px; 111 | border: 0px solid; 112 | border-radius: 24px; 113 | border-color: @selected; 114 | background-color: transparent; 115 | text-color: @fg; 116 | orientation: vertical; 117 | cursor: pointer; 118 | } 119 | element normal.normal { 120 | background-color: transparent; 121 | text-color: @foreground; 122 | } 123 | element selected.normal { 124 | background-color: @tr; 125 | text-color: @foreground; 126 | } 127 | element-icon { 128 | background-color: transparent; 129 | text-color: inherit; 130 | size: 64px; 131 | cursor: inherit; 132 | } 133 | element-text { 134 | background-color: transparent; 135 | text-color: inherit; 136 | highlight: inherit; 137 | cursor: inherit; 138 | vertical-align: 0.5; 139 | horizontal-align: 0.5; 140 | } 141 | 142 | /*****----- Message -----*****/ 143 | error-message { 144 | padding: 15px; 145 | border: 2px solid; 146 | border-radius: 12px; 147 | border-color: @selected; 148 | background-color: @bg; 149 | text-color: @fg; 150 | } 151 | textbox { 152 | background-color: transparent; 153 | text-color: @fg; 154 | vertical-align: 0.5; 155 | horizontal-align: 0.0; 156 | highlight: none; 157 | } 158 | -------------------------------------------------------------------------------- /config/awesome/dashboard/oth.lua: -------------------------------------------------------------------------------- 1 | local json = require("lib.json") 2 | local env = require("env") 3 | 4 | local M = {} 5 | 6 | local create_button = function(icon, comm) 7 | local button = wibox.widget({ 8 | { 9 | { 10 | widget = wibox.widget.textbox, 11 | font = beautiful.icofont, 12 | markup = help.fg(icon, beautiful.fg, "normal"), 13 | }, 14 | margins = dpi(20), 15 | widget = wibox.container.margin, 16 | }, 17 | bg = beautiful.bg2, 18 | buttons = { 19 | awful.button({}, 1, function() 20 | if type(comm) == "string" then 21 | awful.spawn(comm, false) 22 | else 23 | comm() 24 | end 25 | end), 26 | }, 27 | shape = help.rrect(beautiful.br), 28 | widget = wibox.container.background, 29 | }) 30 | return button 31 | end 32 | 33 | local create_stat = function(id, icon) 34 | local stat = { 35 | { 36 | markup = help.fg(icon, beautiful.fg, "bold"), 37 | font = beautiful.icofontname .. "12", 38 | widget = wibox.widget.textbox, 39 | }, 40 | { 41 | id = id, 42 | markup = "-", 43 | font = beautiful.fontname .. "10", 44 | widget = wibox.widget.textbox, 45 | }, 46 | spacing = dpi(4), 47 | layout = wibox.layout.fixed.horizontal, 48 | } 49 | return stat 50 | end 51 | 52 | M.ses = wibox.widget({ 53 | { 54 | { 55 | { 56 | { 57 | { 58 | image = beautiful.img_dir .. "profile.png", 59 | resize = true, 60 | clip_shape = gears.shape.circle, 61 | widget = wibox.widget.imagebox, 62 | }, 63 | forced_height = dpi(110), 64 | forced_width = dpi(110), 65 | widget = wibox.container.background, 66 | }, 67 | { 68 | { 69 | { 70 | markup = help.fg(os.getenv("USER") or "foo", beautiful.pri, "1000"), 71 | font = beautiful.fontname .. "18", 72 | widget = wibox.widget.textbox, 73 | }, 74 | { 75 | markup = help.fg(awesome.hostname or "arch", beautiful.fg, "bold"), 76 | font = beautiful.fontname .. "10", 77 | widget = wibox.widget.textbox, 78 | }, 79 | spacing = dpi(4), 80 | layout = wibox.layout.fixed.vertical, 81 | }, 82 | valign = "center", 83 | widget = wibox.container.place, 84 | }, 85 | spacing = dpi(16), 86 | layout = wibox.layout.fixed.horizontal, 87 | }, 88 | nil, 89 | { 90 | { 91 | create_button("\u{eb0a}", function() 92 | awful.spawn.easy_async_with_shell( 93 | "sh " 94 | .. beautiful.scripts_dir 95 | .. "wallpaper.sh -R -f -d " 96 | .. beautiful.theme_dir 97 | .. beautiful.activetheme 98 | .. "/wallpapers" 99 | ) 100 | end), 101 | create_button("\u{eb0d}", function() 102 | awful.spawn.easy_async_with_shell( 103 | "rofi -show p -modi p:'" 104 | .. beautiful.scripts_dir 105 | .. "/power.sh" 106 | .. ' --symbols-font "tabler-icons"\' -theme Paper -theme power' 107 | ) 108 | end), 109 | spacing = dpi(15), 110 | layout = wibox.layout.fixed.horizontal, 111 | }, 112 | valign = "center", 113 | widget = wibox.container.place, 114 | }, 115 | spacing = dpi(16), 116 | layout = wibox.layout.align.horizontal, 117 | }, 118 | spacing = dpi(16), 119 | layout = wibox.layout.fixed.vertical, 120 | }, 121 | widget = wibox.container.margin, 122 | margins = { bottom = dpi(10), top = dpi(10), left = dpi(20), right = dpi(20) }, 123 | }) 124 | 125 | M.cal = wibox.widget({ 126 | { 127 | { 128 | { 129 | format = help.fg("%a, %B %e", beautiful.pri, "bold"), 130 | refresh = 1, 131 | widget = wibox.widget.textclock, 132 | font = beautiful.fontname .. "10", 133 | align = "center", 134 | }, 135 | { 136 | format = help.fg("%H:%M:%S", beautiful.pri, "1000"), 137 | refresh = 1, 138 | fg = beautiful.bg2, 139 | font = beautiful.fontname .. "18", 140 | align = "center", 141 | widget = wibox.widget.textclock, 142 | }, 143 | spacing = dpi(10), 144 | layout = wibox.layout.flex.vertical, 145 | }, 146 | widget = wibox.container.margin, 147 | margins = { top = dpi(30), bottom = dpi(30), right = dpi(20), left = dpi(20) }, 148 | }, 149 | shape = help.rrect(beautiful.br), 150 | bg = beautiful.bg2, 151 | fg = beautiful.pri, 152 | widget = wibox.container.background, 153 | }) 154 | 155 | M.wth = wibox.widget({ 156 | { 157 | { 158 | { 159 | id = "icn", 160 | align = "left", 161 | font = beautiful.fontname .. "36", 162 | widget = wibox.widget.textbox, 163 | }, 164 | { 165 | 166 | { 167 | markup = "...", 168 | id = "wth", 169 | align = "right", 170 | font = beautiful.fontname .. "18", 171 | widget = wibox.widget.textbox, 172 | }, 173 | { 174 | id = "wnd", 175 | align = "right", 176 | font = beautiful.fontname .. "10", 177 | widget = wibox.widget.textbox, 178 | }, 179 | spacing = dpi(10), 180 | layout = wibox.layout.flex.vertical, 181 | }, 182 | layout = wibox.layout.flex.horizontal, 183 | }, 184 | widget = wibox.container.margin, 185 | margins = { top = dpi(30), bottom = dpi(30), right = dpi(20), left = dpi(20) }, 186 | }, 187 | shape = help.rrect(beautiful.br), 188 | bg = beautiful.bg2, 189 | fg = beautiful.fg2, 190 | widget = wibox.container.background, 191 | }) 192 | 193 | local function wth_fch() 194 | -- m = ºC, km/h 195 | -- u = ºF, mph 196 | local unit = "m" 197 | -- empty: auto location 198 | local city = "alicante" 199 | -- seconds 200 | local interval = 60 * 30 201 | local com = "curl 'wttr.in/" .. city .. "?" .. unit .. "&format=%c+%t+%w'" 202 | 203 | awful.widget.watch(com, interval, function(_, out) 204 | local val = gears.string.split(out, " ") 205 | local sign = val[2]:sub(1, 1) 206 | 207 | M.wth:get_children_by_id("icn")[1].markup = val[1] 208 | M.wth:get_children_by_id("wth")[1].markup = 209 | help.fg((sign == "-" and "-" or "") .. val[2]:sub(2), beautiful.pri, "1000") 210 | M.wth:get_children_by_id("wnd")[1].markup = help.fg(val[3]:sub(1, -2), beautiful.fg2, "bold") 211 | end) 212 | end 213 | 214 | gears.timer({ 215 | timeout = 10, 216 | single_shot = true, 217 | autostart = true, 218 | callback = function() 219 | wth_fch() 220 | end, 221 | }) 222 | 223 | return M 224 | -------------------------------------------------------------------------------- /config/awesome/lib/json.lua: -------------------------------------------------------------------------------- 1 | --[[ json.lua 2 | 3 | A compact pure-Lua JSON library. 4 | The main functions are: json.stringify, json.parse. 5 | 6 | ## json.stringify: 7 | 8 | This expects the following to be true of any tables being encoded: 9 | * They only have string or number keys. Number keys must be represented as 10 | strings in json; this is part of the json spec. 11 | * They are not recursive. Such a structure cannot be specified in json. 12 | 13 | A Lua table is considered to be an array if and only if its set of keys is a 14 | consecutive sequence of positive integers starting at 1. Arrays are encoded like 15 | so: `[2, 3, false, "hi"]`. Any other type of Lua table is encoded as a json 16 | object, encoded like so: `{"key1": 2, "key2": false}`. 17 | 18 | Because the Lua nil value cannot be a key, and as a table value is considerd 19 | equivalent to a missing key, there is no way to express the json "null" value in 20 | a Lua table. The only way this will output "null" is if your entire input obj is 21 | nil itself. 22 | 23 | An empty Lua table, {}, could be considered either a json object or array - 24 | it's an ambiguous edge case. We choose to treat this as an object as it is the 25 | more general type. 26 | 27 | To be clear, none of the above considerations is a limitation of this code. 28 | Rather, it is what we get when we completely observe the json specification for 29 | as arbitrary a Lua object as json is capable of expressing. 30 | 31 | ## json.parse: 32 | 33 | This function parses json, with the exception that it does not pay attention to 34 | \u-escaped unicode code points in strings. 35 | 36 | It is difficult for Lua to return null as a value. In order to prevent the loss 37 | of keys with a null value in a json string, this function uses the one-off 38 | table value json.null (which is just an empty table) to indicate null values. 39 | This way you can check if a value is null with the conditional 40 | `val == json.null`. 41 | 42 | If you have control over the data and are using Lua, I would recommend just 43 | avoiding null values in your data to begin with. 44 | 45 | --]] 46 | 47 | local json = {} 48 | 49 | -- Internal functions. 50 | 51 | local function kind_of(obj) 52 | if type(obj) ~= "table" then 53 | return type(obj) 54 | end 55 | local i = 1 56 | for _ in pairs(obj) do 57 | if obj[i] ~= nil then 58 | i = i + 1 59 | else 60 | return "table" 61 | end 62 | end 63 | if i == 1 then 64 | return "table" 65 | else 66 | return "array" 67 | end 68 | end 69 | 70 | local function escape_str(s) 71 | local in_char = { "\\", '"', "/", "\b", "\f", "\n", "\r", "\t" } 72 | local out_char = { "\\", '"', "/", "b", "f", "n", "r", "t" } 73 | for i, c in ipairs(in_char) do 74 | s = s:gsub(c, "\\" .. out_char[i]) 75 | end 76 | return s 77 | end 78 | 79 | -- Returns pos, did_find; there are two cases: 80 | -- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. 81 | -- 2. Delimiter not found: pos = pos after leading space; did_find = false. 82 | -- This throws an error if err_if_missing is true and the delim is not found. 83 | local function skip_delim(str, pos, delim, err_if_missing) 84 | pos = pos + #str:match("^%s*", pos) 85 | if str:sub(pos, pos) ~= delim then 86 | if err_if_missing then 87 | error("Expected " .. delim .. " near position " .. pos) 88 | end 89 | return pos, false 90 | end 91 | return pos + 1, true 92 | end 93 | 94 | -- Expects the given pos to be the first character after the opening quote. 95 | -- Returns val, pos; the returned pos is after the closing quote character. 96 | local function parse_str_val(str, pos, val) 97 | val = val or "" 98 | local early_end_error = "End of input found while parsing string." 99 | if pos > #str then 100 | error(early_end_error) 101 | end 102 | local c = str:sub(pos, pos) 103 | if c == '"' then 104 | return val, pos + 1 105 | end 106 | if c ~= "\\" then 107 | return parse_str_val(str, pos + 1, val .. c) 108 | end 109 | -- We must have a \ character. 110 | local esc_map = { b = "\b", f = "\f", n = "\n", r = "\r", t = "\t" } 111 | local nextc = str:sub(pos + 1, pos + 1) 112 | if not nextc then 113 | error(early_end_error) 114 | end 115 | return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) 116 | end 117 | 118 | -- Returns val, pos; the returned pos is after the number's final character. 119 | local function parse_num_val(str, pos) 120 | local num_str = str:match("^-?%d+%.?%d*[eE]?[+-]?%d*", pos) 121 | local val = tonumber(num_str) 122 | if not val then 123 | error("Error parsing number at position " .. pos .. ".") 124 | end 125 | return val, pos + #num_str 126 | end 127 | 128 | -- Public values and functions. 129 | 130 | function json.stringify(obj, as_key) 131 | local s = {} -- We'll build the string as an array of strings to be concatenated. 132 | local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise. 133 | if kind == "array" then 134 | if as_key then 135 | error("Can't encode array as key.") 136 | end 137 | s[#s + 1] = "[" 138 | for i, val in ipairs(obj) do 139 | if i > 1 then 140 | s[#s + 1] = ", " 141 | end 142 | s[#s + 1] = json.stringify(val) 143 | end 144 | s[#s + 1] = "]" 145 | elseif kind == "table" then 146 | if as_key then 147 | error("Can't encode table as key.") 148 | end 149 | s[#s + 1] = "{" 150 | for k, v in pairs(obj) do 151 | if #s > 1 then 152 | s[#s + 1] = ", " 153 | end 154 | s[#s + 1] = json.stringify(k, true) 155 | s[#s + 1] = ":" 156 | s[#s + 1] = json.stringify(v) 157 | end 158 | s[#s + 1] = "}" 159 | elseif kind == "string" then 160 | return '"' .. escape_str(obj) .. '"' 161 | elseif kind == "number" then 162 | if as_key then 163 | return '"' .. tostring(obj) .. '"' 164 | end 165 | return tostring(obj) 166 | elseif kind == "boolean" then 167 | return tostring(obj) 168 | elseif kind == "nil" then 169 | return "null" 170 | else 171 | error("Unjsonifiable type: " .. kind .. ".") 172 | end 173 | return table.concat(s) 174 | end 175 | 176 | json.null = {} -- This is a one-off table to represent the null value. 177 | 178 | function json.parse(str, pos, end_delim) 179 | pos = pos or 1 180 | if pos > #str then 181 | error("Reached unexpected end of input.") 182 | end 183 | local pos = pos + #str:match("^%s*", pos) -- Skip whitespace. 184 | local first = str:sub(pos, pos) 185 | if first == "{" then -- Parse an object. 186 | local obj, key, delim_found = {}, true, true 187 | pos = pos + 1 188 | while true do 189 | key, pos = json.parse(str, pos, "}") 190 | if key == nil then 191 | return obj, pos 192 | end 193 | if not delim_found then 194 | error("Comma missing between object items.") 195 | end 196 | pos = skip_delim(str, pos, ":", true) -- true -> error if missing. 197 | obj[key], pos = json.parse(str, pos) 198 | pos, delim_found = skip_delim(str, pos, ",") 199 | end 200 | elseif first == "[" then -- Parse an array. 201 | local arr, val, delim_found = {}, true, true 202 | pos = pos + 1 203 | while true do 204 | val, pos = json.parse(str, pos, "]") 205 | if val == nil then 206 | return arr, pos 207 | end 208 | if not delim_found then 209 | error("Comma missing between array items.") 210 | end 211 | arr[#arr + 1] = val 212 | pos, delim_found = skip_delim(str, pos, ",") 213 | end 214 | elseif first == '"' then -- Parse a string. 215 | return parse_str_val(str, pos + 1) 216 | elseif first == "-" or first:match("%d") then -- Parse a number. 217 | return parse_num_val(str, pos) 218 | elseif first == end_delim then -- End of an object or array. 219 | return nil, pos + 1 220 | else -- Parse true, false, or null. 221 | local literals = { ["true"] = true, ["false"] = false, ["null"] = json.null } 222 | for lit_str, lit_val in pairs(literals) do 223 | local lit_end = pos + #lit_str - 1 224 | if str:sub(pos, lit_end) == lit_str then 225 | return lit_val, lit_end + 1 226 | end 227 | end 228 | local pos_info_str = "position " .. pos .. ": " .. str:sub(pos, pos + 10) 229 | error("Invalid json syntax starting at " .. pos_info_str) 230 | end 231 | end 232 | 233 | return json 234 | -------------------------------------------------------------------------------- /config/awesome/scripts/power.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script defines just a mode for rofi instead of being a self-contained 4 | # executable that launches rofi by itself. This makes it more flexible than 5 | # running rofi inside this script as now the user can call rofi as one pleases. 6 | # For instance: 7 | # 8 | # rofi -show powermenu -modi powermenu:./rofi-power-menu 9 | # 10 | # See README.md for more information. 11 | 12 | set -e 13 | set -u 14 | 15 | # All supported choices 16 | all=(shutdown reboot suspend hibernate logout lockscreen) 17 | 18 | # By default, show all (i.e., just copy the array) 19 | show=("${all[@]}") 20 | 21 | declare -A texts 22 | texts[lockscreen]="lock screen" 23 | texts[switchuser]="switch user" 24 | texts[logout]="log out" 25 | texts[suspend]="suspend" 26 | texts[hibernate]="hibernate" 27 | texts[reboot]="reboot" 28 | texts[shutdown]="shut down" 29 | 30 | declare -A icons 31 | icons[lockscreen]="\Uf033e" 32 | icons[switchuser]="\Uf0019" 33 | icons[logout]="\Uf0343" 34 | icons[suspend]="\Uf04b2" 35 | icons[hibernate]="\Uf02ca" 36 | icons[reboot]="\Uf0709" 37 | icons[shutdown]="\Uf0425" 38 | icons[cancel]="\Uf0156" 39 | 40 | declare -A actions 41 | actions[lockscreen]="betterlockscreen -l" 42 | #actions[switchuser]="???" 43 | actions[logout]="loginctl terminate-session ${XDG_SESSION_ID-}" 44 | actions[suspend]="systemctl suspend" 45 | actions[hibernate]="systemctl hibernate" 46 | actions[reboot]="systemctl reboot" 47 | actions[shutdown]="systemctl poweroff" 48 | 49 | # By default, ask for confirmation for actions that are irreversible 50 | confirmations=(reboot shutdown logout) 51 | 52 | # By default, no dry run 53 | dryrun=false 54 | showsymbols=true 55 | showtext=true 56 | 57 | function check_valid { 58 | option="$1" 59 | shift 1 60 | for entry in "${@}"; do 61 | if [ -z "${actions[$entry]+x}" ]; then 62 | echo "Invalid choice in $1: $entry" >&2 63 | exit 1 64 | fi 65 | done 66 | } 67 | 68 | # Parse command-line options 69 | parsed=$(getopt --options=h --longoptions=help,dry-run,confirm:,choices:,choose:,symbols,no-symbols,text,no-text,symbols-font: --name "$0" -- "$@") 70 | if [ $? -ne 0 ]; then 71 | echo 'Terminating...' >&2 72 | exit 1 73 | fi 74 | eval set -- "$parsed" 75 | unset parsed 76 | while true; do 77 | case "$1" in 78 | "-h" | "--help") 79 | echo "rofi-power-menu - a power menu mode for Rofi" 80 | echo 81 | echo "Usage: rofi-power-menu [--choices CHOICES] [--confirm CHOICES]" 82 | echo " [--choose CHOICE] [--dry-run] [--symbols|--no-symbols]" 83 | echo 84 | echo "Use with Rofi in script mode. For instance, to ask for shutdown or reboot:" 85 | echo 86 | echo " rofi -show menu -modi \"menu:rofi-power-menu --choices=shutdown/reboot\"" 87 | echo 88 | echo "Available options:" 89 | echo " --dry-run Don't perform the selected action but print it to stderr." 90 | echo " --choices CHOICES Show only the selected choices in the given order. Use /" 91 | echo " as the separator. Available choices are lockscreen," 92 | echo " logout,suspend, hibernate, reboot and shutdown. By" 93 | echo " default, all available choices are shown." 94 | echo " --confirm CHOICES Require confirmation for the gives choices only. Use / as" 95 | echo " the separator. Available choices are lockscreen, logout," 96 | echo " suspend, hibernate, reboot and shutdown. By default, only" 97 | echo " irreversible actions logout, reboot and shutdown require" 98 | echo " confirmation." 99 | echo " --choose CHOICE Preselect the given choice and only ask for a" 100 | echo " confirmation (if confirmation is set to be requested). It" 101 | echo " is strongly recommended to combine this option with" 102 | echo " --confirm=CHOICE if the choice wouldn't require" 103 | echo " confirmation by default. Available choices are" 104 | echo " lockscreen, logout, suspend, hibernate, reboot and" 105 | echo " shutdown." 106 | echo " --[no-]symbols Show Unicode symbols or not. Requires a font with support" 107 | echo " for the symbols. Use, for instance, fonts from the" 108 | echo " Nerdfonts collection. By default, they are shown" 109 | echo " --[no-]text Show text description or not." 110 | echo " --symbols-font FONT Use the given font for symbols. By default, the symbols" 111 | echo " use the same font as the text. That font is configured" 112 | echo " with rofi." 113 | echo " -h,--help Show this help text." 114 | exit 0 115 | ;; 116 | "--dry-run") 117 | dryrun=true 118 | shift 1 119 | ;; 120 | "--confirm") 121 | IFS='/' read -ra confirmations <<<"$2" 122 | check_valid "$1" "${confirmations[@]}" 123 | shift 2 124 | ;; 125 | "--choices") 126 | IFS='/' read -ra show <<<"$2" 127 | check_valid "$1" "${show[@]}" 128 | shift 2 129 | ;; 130 | "--choose") 131 | # Check that the choice is valid 132 | check_valid "$1" "$2" 133 | selectionID="$2" 134 | shift 2 135 | ;; 136 | "--symbols") 137 | showsymbols=true 138 | shift 1 139 | ;; 140 | "--no-symbols") 141 | showsymbols=false 142 | shift 1 143 | ;; 144 | "--text") 145 | showtext=true 146 | shift 1 147 | ;; 148 | "--no-text") 149 | showtext=false 150 | shift 1 151 | ;; 152 | "--symbols-font") 153 | symbols_font="$2" 154 | shift 2 155 | ;; 156 | "--") 157 | shift 158 | break 159 | ;; 160 | *) 161 | echo "Internal error" >&2 162 | exit 1 163 | ;; 164 | esac 165 | done 166 | 167 | if [ "$showsymbols" = "false" -a "$showtext" = "false" ]; then 168 | echo "Invalid options: cannot have --no-symbols and --no-text enabled at the same time." >&2 169 | exit 1 170 | fi 171 | 172 | # Define the messages after parsing the CLI options so that it is possible to 173 | # configure them in the future. 174 | 175 | function write_message { 176 | if [ -z ${symbols_font+x} ]; then 177 | icon="$1" 178 | else 179 | icon="$1" 180 | fi 181 | text="$2" 182 | if [ "$showsymbols" = "true" ]; then 183 | if [ "$showtext" = "true" ]; then 184 | echo -n "\u200e$icon \u2068$text\u2069" 185 | else 186 | echo -n "\u200e$icon" 187 | fi 188 | else 189 | echo -n "$text" 190 | fi 191 | } 192 | 193 | function print_selection { 194 | echo -e "$1" | $( 195 | read -r -d '' entry 196 | echo "echo $entry" 197 | ) 198 | } 199 | 200 | declare -A messages 201 | declare -A confirmationMessages 202 | for entry in "${all[@]}"; do 203 | messages[$entry]=$(write_message "${icons[$entry]}" "${texts[$entry]^}") 204 | done 205 | for entry in "${all[@]}"; do 206 | confirmationMessages[$entry]=$(write_message "${icons[$entry]}" "Yes, ${texts[$entry]}") 207 | done 208 | confirmationMessages[cancel]=$(write_message "${icons[cancel]}" "No, cancel") 209 | 210 | if [ $# -gt 0 ]; then 211 | # If arguments given, use those as the selection 212 | selection="${@}" 213 | else 214 | # Otherwise, use the CLI passed choice if given 215 | if [ -n "${selectionID+x}" ]; then 216 | selection="${messages[$selectionID]}" 217 | fi 218 | fi 219 | 220 | # Don't allow custom entries 221 | echo -e "\0no-custom\x1ftrue" 222 | # Use markup 223 | echo -e "\0markup-rows\x1ftrue" 224 | 225 | if [ -z "${selection+x}" ]; then 226 | echo -e "\0prompt\x1fPower menu" 227 | for entry in "${show[@]}"; do 228 | echo -e "${messages[$entry]}\0icon\x1f${icons[$entry]}" 229 | done 230 | else 231 | for entry in "${show[@]}"; do 232 | if [ "$selection" = "$(print_selection "${messages[$entry]}")" ]; then 233 | # Check if the selected entry is listed in confirmation requirements 234 | for confirmation in "${confirmations[@]}"; do 235 | if [ "$entry" = "$confirmation" ]; then 236 | # Ask for confirmation 237 | echo -e "\0prompt\x1fAre you sure" 238 | echo -e "${confirmationMessages[$entry]}\0icon\x1f${icons[$entry]}" 239 | echo -e "${confirmationMessages[cancel]}\0icon\x1f${icons[cancel]}" 240 | exit 0 241 | fi 242 | done 243 | # If not, then no confirmation is required, so mark confirmed 244 | selection=$(print_selection "${confirmationMessages[$entry]}") 245 | fi 246 | if [ "$selection" = "$(print_selection "${confirmationMessages[$entry]}")" ]; then 247 | if [ $dryrun = true ]; then 248 | # Tell what would have been done 249 | echo "Selected: $entry" >&2 250 | else 251 | # Perform the action 252 | ${actions[$entry]} 253 | fi 254 | exit 0 255 | fi 256 | if [ "$selection" = "$(print_selection "${confirmationMessages[cancel]}")" ]; then 257 | # Do nothing 258 | exit 0 259 | fi 260 | done 261 | # The selection didn't match anything, so raise an error 262 | echo "Invalid selection: $selection" >&2 263 | exit 1 264 | fi 265 | -------------------------------------------------------------------------------- /config/awesome/scripts/wallpaper.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # __ ___ _ _ ____ 4 | # \ \ / / \ | | | | | _ \ 5 | # \ \ /\ / / _ \ | | | | _____| | | | 6 | # \ V V / ___ \| |___| |__|_____| |_| | 7 | # \_/\_/_/ \_\_____|_____| |____/ 8 | 9 | DIR="" # Path to wallpapers directory 10 | defaultwallpaper="$HOME/.local/bin/defaultwallpaper.sh" 11 | 12 | Monitor1=$(xrandr --listactivemonitors | grep "+" | awk '{print $4}' | awk NR==1) # Select the first monitor for dual mode 13 | [ ! -z $Monitor1 ] && Resolution1=$(xrandr --listactivemonitors | grep $Monitor1 | sed 's/[\/x]/ /g' | awk '{print $3 "x" $5}') 14 | Monitor2=$(xrandr --listactivemonitors | grep "+" | awk '{print $4}' | awk NR==2) # Select the second monitor for dual mode 15 | [ ! -z $Monitor2 ] && Resolution2=$(xrandr --listactivemonitors | grep $Monitor2 | sed 's/[\/x]/ /g' | awk '{print $3 "x" $5}') 16 | Monitor3=$(xrandr --listactivemonitors | grep "+" | awk '{print $4}' | awk NR==3) # Select the third monitor for triple mode 17 | [ ! -z $Monitor3 ] && Resolution3=$(xrandr --listactivemonitors | grep $Monitor3 | sed 's/[\/x]/ /g' | awk '{print $3 "x" $5}') 18 | # get number of avilable active monitors 19 | NumOfMonitors=$(xrandr --listactivemonitors | grep "+" | wc -l) 20 | # get screen resulotion to calculate the center 21 | x=$(xrandr | grep "*" | sed 's/x/ /g' | awk -F " " '{print $1}' | sed 's/\ //g') 22 | y=$(xrandr | grep "*" | sed 's/x/ /g' | awk -F " " '{print $2}' | sed 's/\ //g') 23 | xl=$(echo "($x-500)/2" | bc) 24 | yl=$(echo "($y-500)/2" | bc) 25 | location=$(echo 500x500+$xl+$yl) 26 | # will be set to true when using -p flag to activate pywal 27 | WithPywall="False" 28 | # will be set to true when using -n flag to activate random photo selection 29 | randomly="False" 30 | # Will be set to True when using -b flag to only change betterlockscreen background 31 | OnlyBetterlockscreen="False" 32 | # Will be set to True when using -b flag to also change betterlockscreen background 33 | WithBetterlockscreen="False" 34 | startMessage="Apply wallpaper to lockscreen" 35 | finishMessage="Finished applying wallpaper to lockscreen" 36 | UseFeh="False" 37 | UseRofi="False" 38 | 39 | # function to reset the last set wallpaper(s) 40 | restore() { 41 | if [ "$UseFeh" = "True" ]; then 42 | ~/.fehbg & 43 | else 44 | defaultwallpaper.sh 45 | fi 46 | } 47 | 48 | # help message 49 | usage() { 50 | echo "Wall-d: A simple and fast wallpaper manager for x" 51 | echo "" 52 | echo "Usage:" 53 | echo "-h print this help message and exit" 54 | echo "-d path/to/your/wallpapers" 55 | echo "-r restore last set Wallpaper(s)" 56 | echo "-p Change colorscheme using pywall" 57 | echo "-b Change Betterlockscreen wallpaper too" 58 | echo "-l Only change Betterlockscreen wallpaper" 59 | echo "-n Choose a randome wallpaper(s)" 60 | echo "-f use feh instead of xwallpaper to set and restore the wallpaper" 61 | echo "-R use rofi instead of dmenu" 62 | echo "" 63 | } 64 | 65 | while getopts :d:rhpbnlfR option; do 66 | case "${option}" in 67 | d) DIR=${OPTARG} ;; 68 | r) restore && exit ;; 69 | p) WithPywall="True" ;; 70 | b) WithBetterlockscreen="True" ;; 71 | l) OnlyBetterlockscreen="True" ;; 72 | n) randomly="True" ;; 73 | h) usage && exit 0 ;; 74 | f) UseFeh="True" ;; 75 | R) UseRofi="True" ;; 76 | *) usage && exit 0 ;; 77 | esac 78 | done 79 | 80 | [ -z "$DIR" ] && usage && exit 0 # if no directory is set, print help message and exit 81 | 82 | # show dmenu in pywal colors only if ran with -p flag 83 | if [ "$WithPywall" = "True" ]; then 84 | colorOptions="-nb $color0 -nf $color15 -sb $color1 -sf $color15" 85 | else 86 | colorOptions="" 87 | fi 88 | 89 | Single() { 90 | if [ "$randomly" = "True" ]; then 91 | walls=$(du -a $DIR | grep 'jpg\|jpeg\|png\|gif' | shuf -n 1 | awk '{print $2}') 92 | else 93 | walls=$(sxiv -t -o -r -b -g $location $DIR | xargs) # running sxiv in thumbnail mode. 94 | fi 95 | wall1=$(printf "%s" "$walls" | awk '{w = 1; for (--w; w >=0; w--){printf "%s\t",$(NF-w)}print ""}') # Only print the last marked Wallpaper 96 | 97 | # if no picture is marked in sxiv, exit. 98 | [ -z "$walls" ] && exit 0 99 | 100 | if [ "$UseRofi" = "True" ] && [ "$UseFeh" = "True" ]; then 101 | WallMenu="rofi -dmenu -theme wallpaper -i" 102 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 103 | elif [ "$UseRofi" = "True" ] && [ "$UseFeh" = "False" ]; then 104 | WallMenu="rofi -dmenu -theme wallpaper -i -l 5 -p "Options"" 105 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 106 | elif [ "$UseRofi" = "False" ] && [ "$UseFeh" = "True" ]; then 107 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 108 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 109 | else 110 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 111 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 112 | fi 113 | 114 | [ -z "$WallOptions" ] && exit 0 115 | 116 | if [ "$OnlyBetterlockscreen" = "True" ]; then 117 | betterlockscreen -u $wall1 -r $Resolution1 118 | else 119 | if [ "$UseFeh" = "True" ]; then 120 | feh --bg-$WallOptions $wall1 121 | else 122 | xwallpaper --$WallOptions $wall1 && sed -i "s|xwallpaper.*|xwallpaper --$WallOptions $wall1|" $HOME/.local/bin/defaultwallpaper.sh 123 | fi 124 | fi 125 | 126 | [ "$WithPywall" = "True" ] && wal -i $wall1 -n 127 | 128 | if [ "$WithBetterlockscreen" = "True" ]; then 129 | dunstify "Wall-d" "$startMessage" 130 | betterlockscreen -u $wall1 -r $Resolution1 131 | dunstify "Wall-d" "$finishMessage" 132 | fi 133 | } 134 | 135 | # to set to diffrent wallpapers on each desktop 136 | Dual() { 137 | if [ "$randomly" = "True" ]; then 138 | dwalls=$(du -a $DIR | grep 'jpg\|jpeg\|png\|gif' | shuf -n 1 | awk '{print $2}') 139 | else 140 | dwalls=$(sxiv -t -o -r -b -g $location $DIR | xargs) # running sxiv in thimbnail mode. 141 | fi 142 | dwallslast2=$(printf "%s" "$dwalls" | awk '{w = 2; for (--w; w >=0; w--){printf "%s\t",$(NF-w)}print ""}') # Only print the two last marked Wallpapers 143 | dwall1=$(printf "%s" "$dwallslast2" | awk '{print $1}') # Print the path to the before-last marked wallpaper 144 | dwall2=$(printf "%s" "$dwallslast2" | awk '{print $2}') # Print the path to the last marked wallpaper 145 | 146 | # if no picture is marked in sxiv, exit. 147 | [ -z "$dwalls" ] && exit 0 148 | 149 | if [ "$UseRofi" = "True" ] && [ "$UseFeh" = "True" ]; then 150 | WallMenu="rofi -dmenu -i -l 5 -p "Options"" 151 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 152 | elif [ "$UseRofi" = "True" ] && [ "$UseFeh" = "False" ]; then 153 | WallMenu="rofi -dmenu -i -l 5 -p "Options"" 154 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 155 | elif [ "$UseRofi" = "False" ] && [ "$UseFeh" = "True" ]; then 156 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 157 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 158 | else 159 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 160 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 161 | fi 162 | 163 | [ -z "$WallOptions" ] && exit 0 164 | 165 | if [ "$UseFeh" = "True" ]; then 166 | feh --bg-$WallOptions $dwall1 $dwall2 167 | else 168 | xwallpaper --output $Monitor1 --$WallOptions $dwall1 --output $Monitor2 --$WallOptions $dwall2 && sed -i "s|xwallpaper.*|xwallpaper --output $Monitor1 --$WallOptions $dwall1 --output $Monitor2 --$WallOptions $dwall2|" $HOME/.local/bin/defaultwallpaper.sh 169 | fi 170 | 171 | [ "$WithPywall" = "True" ] && wal -i $dwall1 -n 172 | 173 | if [ "$WithBetterlockscreen" = "True" ]; then 174 | dunstify "Wall-d" "$startMessage" 175 | betterlockscreen -u $dwall1 -r $Resolution1 176 | dunstify "Wall-d" "$finishMessage" 177 | fi 178 | } 179 | 180 | Triple() { 181 | 182 | if [ "$randomly" = "True" ]; then 183 | twalls=$(du -a $DIR | grep 'jpg\|jpeg\|png\|gif' | shuf -n 1 | awk '{print $2}') 184 | else 185 | twalls=$(sxiv -t -o -r -b -g $location $DIR | xargs) # running sxiv in thimbnail mode. 186 | fi 187 | twallslast3=$(printf "%s" "$twalls" | awk '{w = 3; for (--w; w >=0; w--){printf "%s\t",$(NF-w)}print ""}') # Only print the three last marked Wallpapers 188 | twall1=$(printf "%s" "$twallslast3" | awk '{print $1}') # Print the path to the before-before-last marked wallpaper 189 | twall2=$(printf "%s" "$twallslast3" | awk '{print $2}') # Print the path to the before-last marked wallpaper 190 | twall3=$(printf "%s" "$twallslast3" | awk '{print $3}') # Print the path to the last marked wallpaper 191 | 192 | # if no picture is marked in sxiv, exit. 193 | [ -z "$twalls" ] && exit 0 194 | 195 | if [ "$UseRofi" = "True" ] && [ "$UseFeh" = "True" ]; then 196 | WallMenu="rofi -dmenu -i -l 5 -p "Options"" 197 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 198 | elif [ "$UseRofi" = "True" ] && [ "$UseFeh" = "False" ]; then 199 | WallMenu="rofi -dmenu -i -l 5 -p "Options"" 200 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 201 | elif [ "$UseRofi" = "False" ] && [ "$UseFeh" = "True" ]; then 202 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 203 | WallOptions=$(echo -e "fill\ncenter\ntile\nscale\nno-xinerama" | $WallMenu) 204 | else 205 | WallMenu="dmenu $colorOptions -i -l 5 -p "Options"" 206 | WallOptions=$(echo -e "zoom\ncenter\ntile\nstretch\nno-randr" | $WallMenu) 207 | fi 208 | 209 | [ -z "$WallOptions" ] && exit 0 210 | 211 | if [ "$UseFeh" = "True" ]; then 212 | feh --bg-$WallOptions $dwall1 $dwall2 213 | else 214 | xwallpaper --output $Monitor1 --$WallOptions $twall1 --output $Monitor2 --$WallOptions $twall2 --output $Monitor3 --$WallOptions $twall3 && sed -i "s|xwallpaper.*|xwallpaper --output $Monitor1 --$WallOptions $twall1 --output $Monitor2 --$WallOptions $twall2 --output $Monitor3 --$WallOptions $twall3 |" $HOME/.local/bin/defaultwallpaper.sh 215 | fi 216 | 217 | [ "$WithPywall" = "True" ] && wal -i $twall2 -n 218 | 219 | if [ "$WithBetterlockscreen" = "True" ]; then 220 | dunstify "Wall-d" "$startMessage" 221 | betterlockscreen -u $twall2 -r $Resolution2 222 | dunstify "Wall-d" "$finishMessage" 223 | fi 224 | } 225 | 226 | if [ "$UseRofi" = "True" ]; then 227 | MENU="rofi -dmenu -l 3 -p "Mode?"" 228 | else 229 | MENU="dmenu $colorOptions -l 3 -p "Mode?"" 230 | fi 231 | 232 | if [ "$NumOfMonitors" -eq 1 ]; then 233 | Single && exit 0 234 | elif [ "$NumOfMonitors" -eq 2 ]; then 235 | MODE=$(echo -e "Single: Choose one Wallpaper\nDual: Choose two Wallpapers" | $MENU) 236 | elif [ "$NumOfMonitors" -ge 3 ]; then 237 | MODE=$(echo -e "Single: Choose One Wallpaper\nDual: Choose Two Wallpapers\nTriple: Choose Three Wallpapers" | $MENU) 238 | fi 239 | 240 | case "$MODE" in 241 | Single*) Single ;; 242 | Dual*) Dual ;; 243 | Triple*) Triple ;; 244 | esac 245 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------