├── .gitignore ├── README.md ├── dotfiles ├── .bashrc ├── .local │ └── bin │ │ └── screenshot ├── awesome │ ├── .luarc.json │ ├── .rgignore │ ├── .stylua.toml │ ├── lib │ │ ├── .editorconfig │ │ └── .gitignore │ ├── logs.sh │ ├── lua │ │ ├── core │ │ │ ├── binding.lua │ │ │ ├── gearsify.lua │ │ │ ├── service.lua │ │ │ ├── variable.lua │ │ │ ├── widget.lua │ │ │ └── window.lua │ │ ├── daemons │ │ │ ├── battery.lua │ │ │ ├── init.lua │ │ │ ├── polkitagent │ │ │ │ ├── init.lua │ │ │ │ └── org.freedesktop.PolicyKit1.AuthenticationAgent.xml │ │ │ └── screencast │ │ │ │ ├── init.lua │ │ │ │ └── org.freedesktop.portal.ScreenCast.xml │ │ ├── functions.lua │ │ ├── globals.lua │ │ ├── init.lua │ │ ├── keybindings.lua │ │ ├── rules.lua │ │ ├── services │ │ │ ├── applications.lua │ │ │ ├── appmenu.lua │ │ │ ├── appmenu │ │ │ │ ├── com.canonical.AppMenu.Registrar.xml │ │ │ │ └── init.lua │ │ │ ├── brightness.lua │ │ │ ├── top.lua │ │ │ ├── userprompt.lua │ │ │ ├── wallpaper.lua │ │ │ └── wallpaper │ │ │ │ ├── init.lua │ │ │ │ └── org.freedesktop.portal.Wallpaper.xml │ │ ├── signal │ │ │ ├── client.lua │ │ │ ├── init.lua │ │ │ ├── screen.lua │ │ │ └── tag.lua │ │ ├── subclasses │ │ │ ├── color.lua │ │ │ ├── dbusservice.lua │ │ │ ├── timed.lua │ │ │ └── varmap.lua │ │ ├── tests.lua │ │ ├── user.lua │ │ ├── utils.lua │ │ ├── variables.lua │ │ └── widgets │ │ │ ├── bar │ │ │ ├── activeclient.lua │ │ │ ├── clock.lua │ │ │ ├── init.lua │ │ │ ├── kbdlayout.lua │ │ │ ├── layoutbox.lua │ │ │ ├── systray.lua │ │ │ ├── taglist.lua │ │ │ └── taglist_item.lua │ │ │ ├── controlcenter │ │ │ └── init.lua │ │ │ ├── custom │ │ │ ├── icon.lua │ │ │ ├── init.lua │ │ │ └── revealer.lua │ │ │ ├── dock │ │ │ ├── init.lua │ │ │ ├── launcher.lua │ │ │ ├── pinned.lua │ │ │ ├── tasklist.lua │ │ │ └── tasklist_item.lua │ │ │ ├── launcher │ │ │ ├── apps.lua │ │ │ ├── clients.lua │ │ │ ├── init.lua │ │ │ ├── launcher_item.lua │ │ │ └── powermenu.lua │ │ │ ├── menu.lua │ │ │ ├── notifications │ │ │ ├── init.lua │ │ │ └── notifpopup.lua │ │ │ ├── overview │ │ │ ├── init.lua │ │ │ └── overview_item.lua │ │ │ ├── titlebar.lua │ │ │ └── wallpaper.lua │ ├── rc.lua │ ├── theme │ │ ├── icons │ │ │ ├── layouts │ │ │ │ ├── cornerne.svg │ │ │ │ ├── cornernw.svg │ │ │ │ ├── cornerse.svg │ │ │ │ ├── cornersw.svg │ │ │ │ ├── dwindle.svg │ │ │ │ ├── fairh.svg │ │ │ │ ├── fairv.svg │ │ │ │ ├── floating.svg │ │ │ │ ├── fullscreen.svg │ │ │ │ ├── magnifier.svg │ │ │ │ ├── max.svg │ │ │ │ ├── spiral.svg │ │ │ │ ├── tile.svg │ │ │ │ ├── tilebottom.svg │ │ │ │ ├── tileleft.svg │ │ │ │ └── tiletop.svg │ │ │ ├── nixos-snowflake-colours.svg │ │ │ ├── submenu.png │ │ │ └── symbolic │ │ │ │ ├── arrow-circular-top-left-symbolic.svg │ │ │ │ ├── arrows-pointing-inward-symbolic.svg │ │ │ │ ├── arrows-pointing-outward-symbolic.svg │ │ │ │ ├── cross-large-symbolic.svg │ │ │ │ ├── dot-symbolic.svg │ │ │ │ ├── down-symbolic.svg │ │ │ │ ├── memory-symbolic.svg │ │ │ │ ├── moon-outline-symbolic.svg │ │ │ │ ├── multitasking-windows-symbolic.svg │ │ │ │ ├── process-symbolic.svg │ │ │ │ └── system-search-symbolic.svg │ │ ├── init.lua │ │ ├── style │ │ │ ├── bar.lua │ │ │ ├── client.lua │ │ │ ├── dock.lua │ │ │ ├── init.lua │ │ │ ├── launcher.lua │ │ │ ├── layout.lua │ │ │ ├── notification.lua │ │ │ ├── overview.lua │ │ │ ├── titlebar.lua │ │ │ ├── userprompt.lua │ │ │ └── widgets.lua │ │ └── themeutils.lua │ └── xephyr.sh ├── nvim │ ├── .gitignore │ ├── .luarc.json │ ├── init.lua │ ├── lua │ │ ├── config │ │ │ ├── keymaps.lua │ │ │ ├── lazy.lua │ │ │ └── settings.lua │ │ └── plugins │ │ │ ├── conform.lua │ │ │ ├── gitsigns.lua │ │ │ ├── lualine.lua │ │ │ ├── mason.lua │ │ │ ├── noice.lua │ │ │ ├── nvim-autopairs.lua │ │ │ ├── nvim-cmp.lua │ │ │ ├── nvim-colorizer.lua │ │ │ ├── nvim-comment.lua │ │ │ ├── nvim-lspconfig.lua │ │ │ ├── nvim-navic.lua │ │ │ ├── nvim-tree.lua │ │ │ ├── nvim-treesitter-context.lua │ │ │ ├── nvim-treesitter.lua │ │ │ ├── nvim-ufo.lua │ │ │ ├── oxocarbon.lua │ │ │ ├── presence.lua │ │ │ ├── tailwind-fold.lua │ │ │ ├── telescope.lua │ │ │ ├── trouble.lua │ │ │ └── vim-suda.lua │ └── stylua.toml ├── picom │ └── picom.conf ├── wezterm │ └── wezterm.lua └── xdg-desktop-portal │ ├── none+awesome-portals.conf │ └── portals │ └── luajit.portal ├── etc └── nixos │ ├── configuration.nix │ └── hardware-configuration.nix ├── flake.nix ├── home.nix └── nix ├── bash.nix ├── flatpak.nix ├── git.nix ├── gnome.nix ├── nvim.nix ├── packages.nix ├── picom.nix ├── portal.nix ├── spotify.nix └── wezterm.nix /.gitignore: -------------------------------------------------------------------------------- 1 | /flake.lock 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | epic 2 | -------------------------------------------------------------------------------- /dotfiles/.bashrc: -------------------------------------------------------------------------------- 1 | 2 | # Binds 3 | bind 'set completion-ignore-case on' 4 | 5 | # Tab autocompletion 6 | bind 'TAB:menu-complete' 7 | bind '"\e[Z":menu-complete-backward' 8 | 9 | # Ctrl + backspace = delete word 10 | bind '"\x08":backward-kill-word' 11 | 12 | # Ctrl + supr = delete word 13 | bind '"\e[3;5~":kill-word' 14 | 15 | bind '"\e[A": history-search-backward' 16 | bind '"\e[B": history-search-forward' 17 | 18 | battery() { 19 | upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep percentage | awk '{print $2}' 20 | } 21 | 22 | colors() { 23 | local T='•••' 24 | 25 | echo -e "\n 40m 41m 42m 43m 44m 45m 46m 47m" 26 | 27 | for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \ 28 | '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \ 29 | ' 36m' '1;36m' ' 37m' '1;37m'; do 30 | FG=${FGs// /} 31 | echo -en " $FGs \e[$FG $T " 32 | 33 | for BG in 40m 41m 42m 43m 44m 45m 46m 47m; do 34 | echo -en " \e[$FG\e[$BG $T \e[0m" 35 | done 36 | echo 37 | done 38 | echo 39 | } 40 | 41 | extract() { 42 | if [ -f "$1" ]; then 43 | case $1 in 44 | *.tar.bz2) tar xjf $1 ;; 45 | *.tar.gz) tar xzf $1 ;; 46 | *.bz2) bunzip2 $1 ;; 47 | *.rar) unrar x $1 ;; 48 | *.gz) gunzip $1 ;; 49 | *.tar) tar xf $1 ;; 50 | *.tbz2) tar xjf $1 ;; 51 | *.tgz) tar xzf $1 ;; 52 | *.zip) unzip $1 ;; 53 | *.Z) uncompress $1 ;; 54 | *.7z) 7z x $1 ;; 55 | *.deb) ar x $1 ;; 56 | *.tar.xz) tar xf $1 ;; 57 | *.tar.zst) unzstd $1 ;; 58 | *) echo "'$1' not supported." ;; 59 | esac 60 | else 61 | echo "'$1' invalid file" 62 | fi 63 | } 64 | 65 | build() { 66 | 67 | local filename 68 | filename=$(basename "$1") 69 | 70 | case "${filename##*.}" in 71 | "kt") 72 | kotlinc "$filename" -include-runtime -d "${filename%.*}.jar" && java -jar "${filename%.*}.jar" 73 | ;; 74 | "java") 75 | javac "$filename" && java "${filename%.*}" 76 | ;; 77 | "cpp") 78 | g++ "$filename" -o "${filename%.*}" && "./${filename%.*}" 79 | ;; 80 | "c") 81 | gcc "$filename" -o "${filename%.*}" && "./${filename%.*}" 82 | ;; 83 | "pas") 84 | fpc "$filename" && "./${filename%.*}" 85 | ;; 86 | *) 87 | echo "Unsupported filetype: ${filename##*.}" 88 | ;; 89 | esac 90 | } 91 | -------------------------------------------------------------------------------- /dotfiles/.local/bin/screenshot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | screenshot_dir="$HOME/Pictures/Screenshots" 4 | file_name="Screenshot_$(date +'%m%d%H%M%S').png" 5 | file_path="$screenshot_dir/$file_name" 6 | 7 | screenshot_x11() { 8 | mode="$1" 9 | if [ "$mode" = "--sel" ]; then 10 | maim -slu --color=0.74,0.58,1,0.85 | tee "$file_path" | xclip -selection clipboard -t image/png 11 | elif [ "$mode" = "--all" ]; then 12 | maim -u --color=0.74,0.58,1,0.85 | tee "$file_path" | xclip -selection clipboard -t image/png 13 | else 14 | echo "Invalid mode. Use --sel to select a region or --all to capture the entire screen." 15 | exit 1 16 | fi 17 | } 18 | 19 | if [ "$#" -ne 1 ]; then 20 | echo "Usage: $0 " 21 | echo "Available modes: --sel (select region), --all (capture entire screen)" 22 | exit 1 23 | else 24 | screenshot_x11 "$1" 25 | fi 26 | 27 | if [ -s "$file_path" ]; then 28 | 29 | notify_action=$(notify-send \ 30 | "Captured successfully" \ 31 | "The screenshot was saved and copied to the clipboard." \ 32 | -a "Screenshot" \ 33 | -i "applets-screenshooter-symbolic" \ 34 | -h "string:image-path:$file_path" \ 35 | -A 1=Open -A 2=Delete) 36 | 37 | case $notify_action in 38 | 1) 39 | xdg-open "$file_path" & 40 | ;; 41 | 2) 42 | rm -i "$file_path" & 43 | ;; 44 | esac 45 | else 46 | [ -e "$file_path" ] && rm "$file_path" 47 | fi 48 | -------------------------------------------------------------------------------- /dotfiles/awesome/.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "diagnostics": { 3 | "disableScheme": ["./lib/**/*"], 4 | "libraryFiles": "Opened", 5 | "disable": ["duplicate-set-field"], 6 | "globals": ["lgi", "bind", "derive", "dpi", "capi", "async", "wibox", "widget", "bful", "cter"] 7 | }, 8 | "workspace": { 9 | "library": [ 10 | "/run/current-system/sw/share/awesome/lib/", 11 | "/usr/share/awesome/lib/", 12 | "/usr/share/lua/5.1/", 13 | "~/.cache/luagir/", 14 | ], 15 | "maxPreload": 2000, 16 | "preloadFileSize": 1000 17 | }, 18 | "runtime": { 19 | "version": "LuaJIT" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dotfiles/awesome/.rgignore: -------------------------------------------------------------------------------- 1 | /git 2 | /theme/icons 3 | /theme/*/*.png 4 | /theme/*.png 5 | /lib/ 6 | -------------------------------------------------------------------------------- /dotfiles/awesome/.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 100 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 4 5 | quote_style = "AutoPreferSingle" 6 | call_parentheses = "NoSingleTable" 7 | syntax = "LuaJIT" 8 | collapse_simple_statement = "FunctionOnly" 9 | 10 | [sort_requires] 11 | enabled = true 12 | -------------------------------------------------------------------------------- /dotfiles/awesome/lib/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.lua] 4 | charset = utf-8 5 | intent_style = tab 6 | indent_size = 4 7 | trim_trailing_whitespace = true 8 | max_line_length = 120 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /dotfiles/awesome/lib/.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | -------------------------------------------------------------------------------- /dotfiles/awesome/logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | journalctl -f | grep $(pgrep awesome) 4 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/core/binding.lua: -------------------------------------------------------------------------------- 1 | ---@class GBinding 2 | ---@field emitter table 3 | ---@field property? string 4 | ---@field transform_fn function 5 | ---@field private __index GBinding 6 | ---@overload fun(emitter: table | userdata, property?: string): GBinding 7 | local Binding = {} 8 | Binding.__index = Binding ---@diagnostic disable-line 9 | Binding.__type = 'Binding' 10 | 11 | ---@param emitter table | GVariable | Varmap | userdata 12 | ---@param property? string 13 | ---@return GBinding 14 | Binding.new = function(emitter, property) 15 | return setmetatable({ 16 | emitter = emitter, 17 | property = property, 18 | transform_fn = function(v) return v end, 19 | }, Binding) ---@diagnostic disable-line 20 | end 21 | 22 | function Binding:is_type_of(obj) return type(obj) == 'table' and obj.__type == Binding.__type end 23 | 24 | function Binding:__tostring() 25 | local str = 'Binding<' .. tostring(self.emitter) 26 | if self.property ~= nil then 27 | str = str .. ', ' .. self.property 28 | end 29 | return str .. '>' 30 | end 31 | 32 | function Binding:__call(emitter, property) return Binding.new(emitter, property) end 33 | 34 | ---@return any 35 | function Binding:get() 36 | local Varmap = require('lua.subclasses.varmap') 37 | local Variable = require('lua.core.variable') 38 | 39 | if Varmap:is_type_of(self.emitter) then 40 | return self.transform_fn(self.emitter:values()) 41 | elseif Variable:is_type_of(self.emitter) then 42 | return self.transform_fn(self.emitter:get()) 43 | elseif self.property ~= nil then 44 | return self.transform_fn(self.emitter[self.property]) 45 | else 46 | error('Can not get: ' .. tostring(self)) 47 | end 48 | end 49 | 50 | ---@param transform fun(value: any): any 51 | ---@return GBinding 52 | function Binding:as(transform) 53 | local b = Binding.new(self.emitter, self.property) 54 | b.transform_fn = function(v) return transform(self.transform_fn(v)) end 55 | return b 56 | end 57 | 58 | ---@param callback fun(value: any) 59 | ---@return function 60 | function Binding:subscribe(callback) 61 | local Service = require('lua.core.service') 62 | 63 | if self.property ~= nil then 64 | local prop = 'property::' .. self.property 65 | return Service.smart_connect(self.emitter, prop, function() callback(self:get()) end) 66 | elseif type(self.emitter.subscribe) == 'function' then 67 | return self.emitter:subscribe(function() callback(self:get()) end) 68 | else 69 | error('Can not subscribe: ' .. tostring(self)) 70 | end 71 | end 72 | 73 | ---@param deps ( GBinding | GVariable)[] 74 | ---@param transform? fun(...: any): any 75 | ---@return GVariable 76 | Binding.merge = function(deps, transform) 77 | local Variable = require('lua.core.variable') 78 | 79 | assert(not Variable:is_type_of(deps)) 80 | 81 | transform = transform or function(...) return { ... } end 82 | 83 | for i, var in ipairs(deps) do 84 | if Variable:is_type_of(var) then 85 | deps[i] = Binding.new(var) 86 | end 87 | end 88 | 89 | local function update() 90 | local params = {} 91 | for index, value in ipairs(deps) do 92 | params[index] = value:get() 93 | end 94 | return transform(table.unpack(params, 1, #deps)) 95 | end 96 | 97 | local var = Variable.new(update()) 98 | 99 | local unsubs = {} 100 | 101 | for index, value in ipairs(deps) do 102 | unsubs[index] = value:subscribe(function() var:set(update()) end) 103 | end 104 | 105 | return var:on_dropped(function() 106 | return table.iterate(unsubs, function(value) value() end) 107 | end) 108 | end 109 | 110 | return setmetatable(Binding, { ---@diagnostic disable-line 111 | __call = function(_, emitter, prop) return Binding.new(emitter, prop) end, 112 | }) 113 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/core/gearsify.lua: -------------------------------------------------------------------------------- 1 | --- https://github.com/tokyob0t/dotfiles/blob/15def7224816670ca2b0cb91af2df6fb45950f6f/awesome/utils/init.lua 2 | local gobject = require('gears.object') 3 | local gtable = require('gears.table') 4 | 5 | local gearsified = { mt = {} } 6 | 7 | gearsified.__type = 'Gearsified' 8 | 9 | function gearsified.mt:__index(key) 10 | if gobject[key] then 11 | return gobject[key] 12 | end 13 | 14 | if rawget(self, key) then 15 | return rawget(self, key) 16 | end 17 | 18 | local object = self._private.object 19 | 20 | key = string.gsub(key, '-', '_') 21 | 22 | if self:is_method(key) then 23 | local m = object[key] 24 | return function(_, ...) return m(object, ...) end 25 | end 26 | 27 | if self:is_property(key) then 28 | return object[key] 29 | end 30 | end 31 | 32 | function gearsified.mt:__newindex(key, value) 33 | local object = self._private.object 34 | 35 | key = string.gsub(key, '-', '_') 36 | 37 | if self:is_property(key) then 38 | object[key] = value 39 | end 40 | end 41 | 42 | function gearsified.mt:__tostring() return 'Gearsified<' .. tostring(self._private.object) .. '>' end 43 | 44 | function gearsified:is_property(name) 45 | return self._private.object._property and self._private.object._property[name] ~= nil 46 | end 47 | 48 | function gearsified:is_method(name) 49 | return self._private.object._method and self._private.object._method[name] ~= nil 50 | end 51 | 52 | function gearsified:is_function(name) 53 | return self._private.object._function and self._private.object._function[name] ~= nil 54 | end 55 | 56 | function gearsified:is_signal(name) 57 | return self._private.object._signal and self._private.object._signal[name] ~= nil 58 | end 59 | 60 | function gearsified:dispose() 61 | for _, id in pairs(self._private.unsubs) do 62 | GObject.signal_handler_disconnect(self._private.object, id) 63 | end 64 | 65 | self._private.object = nil 66 | end 67 | 68 | function gearsified:connect_signal(name, func) 69 | local object = self._private.object 70 | local key = tostring(func):gsub('function: ', '') 71 | local id 72 | 73 | if string.sub(name, 1, 10) == 'property::' then 74 | local prop = string.gsub(name, 'property::', '') 75 | id = object.on_notify:connect(function() func(self, self[prop]) end, prop, false) 76 | else 77 | id = object['on_' .. name]:connect(function(_, ...) func(self, ...) end) 78 | end 79 | 80 | self._private.unsubs[key] = id 81 | end 82 | 83 | function gearsified:disconnect_signal(_, func) 84 | local key = tostring(func):gsub('function: ', '') 85 | local id = self._private.unsubs[key] 86 | 87 | if not id then 88 | return 89 | end 90 | 91 | GObject.signal_handler_disconnect(self._private.object, id) 92 | end 93 | 94 | setmetatable(gearsified, gearsified.mt) 95 | 96 | ---@generic G 97 | ---@param object G 98 | ---@return G | { connect_signal: fun(self, name, fn), disconnect_signal: fun(self, name, fn), emit_signal: fun(self, name, ...)} 99 | return function(object) 100 | local ret = gobject {} 101 | 102 | rawset(ret, '_private', {}) 103 | 104 | ret._private.object = object 105 | ret._private.unsubs = {} 106 | 107 | gtable.crush(ret, gearsified, true) 108 | setmetatable(ret, gearsified.mt) 109 | 110 | return ret 111 | end 112 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/core/service.lua: -------------------------------------------------------------------------------- 1 | local gobject = require('gears.object') 2 | 3 | ---@class Service 4 | ---@field protected __call function 5 | ---@field protected __index Service 6 | ---@field protected _private table 7 | local Service = {} 8 | Service.__index = Service 9 | 10 | Service.new = function() return setmetatable({}, Service) end 11 | 12 | function Service:__call(...) 13 | local s = gobject { class = self, enable_properties = true } 14 | 15 | if not rawget(s, '_private') then 16 | rawset(s, '_private', {}) 17 | end 18 | 19 | if s._init then 20 | s:_init(...) 21 | end 22 | 23 | return s 24 | end 25 | 26 | ---@protected 27 | function Service:_init() end 28 | 29 | ---@protected 30 | function Service:notify(prop) self:emit_signal('property::' .. prop, self[prop]) end 31 | 32 | Service.emit_signal = gobject.emit_signal 33 | Service.disconnect_signal = gobject.disconnect_signal 34 | Service.connect_signal = gobject.connect_signal 35 | 36 | function Service:smart_connect(name, callback) 37 | if table.contains(self, table.values(capi)) then 38 | self.connect_signal(name, callback) 39 | return function() self.disconnect_signal(name, callback) end 40 | else 41 | self:connect_signal(name, callback) 42 | return function() self:disconnect_signal(name, callback) end 43 | end 44 | end 45 | 46 | return Service 47 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/core/variable.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | local gobject = require('gears.object') 3 | local gtable = require('gears.table') 4 | local gtimer = require('gears.timer') 5 | 6 | ---@class GVariable: Service 7 | ---@field value any 8 | ---@field private __index GVariable 9 | ---@field private _value any 10 | ---@field private _poll? table 11 | ---@field private _watch? table 12 | ---@field private poll_interval number 13 | ---@field private poll_exec? string[] | string 14 | ---@field private poll_transform? fun(next: any, prev: any): any 15 | ---@field private poll_fn? function 16 | ---@field private watch_transform? fun(next: any, prev: any): any 17 | ---@field private watch_exec? string[] | string 18 | ---@field private emit_signal function 19 | ---@field private connect_signal function 20 | ---@field private disconnect_signal function 21 | ---@field private weak_connect_signal function 22 | ---@overload fun(value: any): GVariable 23 | local Variable = Service.new() ---@diagnostic disable-line 24 | Variable.__index = Variable ---@diagnostic disable-line 25 | Variable.__type = 'Variable' 26 | 27 | function Variable:__tostring() return 'Variable<' .. tostring(self:get()) .. '>' end 28 | 29 | ---@private 30 | ---@param transform? fun(v: any): any 31 | ---@return GBinding 32 | function Variable:__call(transform) 33 | local Binding = require('lua.core.binding') 34 | 35 | if type(transform) == 'nil' then 36 | return Binding.new(self) 37 | else 38 | return Binding.new(self):as(transform) 39 | end 40 | end 41 | 42 | ---@return GVariable 43 | Variable.new = function(value) return Variable(value) end 44 | 45 | function Variable:is_type_of(obj) return type(obj) == 'table' and obj.__type == Variable.__type end 46 | 47 | function Variable:get() return self._value end 48 | 49 | function Variable:set(new_value) 50 | if new_value ~= self:get() then 51 | self._value = new_value 52 | self:notify('value') 53 | end 54 | end 55 | 56 | function Variable:set_value(new_value) self:set(new_value) end 57 | 58 | function Variable:get_value() return self:get() end 59 | 60 | function Variable:is_polling() return self._poll ~= nil end 61 | 62 | function Variable:stop_poll() 63 | if self:is_polling() then 64 | self._poll:stop() 65 | end 66 | self._poll = nil 67 | end 68 | 69 | function Variable:start_poll() 70 | if self:is_polling() then 71 | return 72 | end 73 | 74 | if self.poll_fn then 75 | self._poll = gtimer { 76 | autostart = true, 77 | call_now = true, 78 | interval = self.poll_interval / 1000, 79 | callback = function() self:set(self.poll_fn(self:get())) end, 80 | } 81 | elseif self.poll_exec then 82 | self._poll = gtimer { 83 | autostart = true, 84 | call_now = true, 85 | interval = self.poll_interval / 1000, 86 | callback = function() 87 | io.exec(self.poll_exec, function(stdout, stderr) 88 | if stderr ~= nil then 89 | return Logger.critical(stderr) 90 | end 91 | self:set(self.poll_transform(stdout, self:get())) 92 | end) 93 | end, 94 | } 95 | end 96 | end 97 | 98 | ---@param interval number 99 | ---@param exec string | string[] | function 100 | ---@param transform? fun(next: any, prev: any): any 101 | function Variable:poll(interval, exec, transform) 102 | transform = transform or function(next) return next end 103 | 104 | self:stop_poll() 105 | self.poll_interval = interval / 1000 106 | self.poll_transform = transform 107 | 108 | if type(exec) == 'function' then 109 | self.poll_fn = exec 110 | self.poll_exec = nil 111 | else 112 | self.poll_exec = exec 113 | self.poll_fn = nil 114 | end 115 | 116 | self:start_poll() 117 | 118 | return self 119 | end 120 | 121 | function Variable:subscribe(callback) 122 | return self:smart_connect('property::value', function() callback(self:get()) end) 123 | end 124 | 125 | ---@param object any 126 | ---@param signal string 127 | ---@param transform function 128 | function Variable:observe(object, signal, transform) 129 | local is_property = string.sub(signal, 1, 8) == 'property::' 130 | local set = function(...) self:set(transform(...)) end 131 | local fn 132 | 133 | if is_property then 134 | local prop = string.gsub(signal, 'property::', '') 135 | fn = function() set(object, object[prop]) end 136 | else 137 | fn = set 138 | end 139 | 140 | self:on_dropped(self.smart_connect(object, signal, fn)) 141 | return self 142 | end 143 | 144 | function Variable:drop() self:emit_signal('dropped') end 145 | 146 | function Variable:on_dropped(callback) 147 | local unsub 148 | unsub = self:smart_connect('dropped', function() callback(unsub()) end) 149 | return self 150 | end 151 | 152 | function Variable:_init(initial) 153 | self._value = initial 154 | self:notify('value') 155 | end 156 | 157 | return Variable 158 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/core/window.lua: -------------------------------------------------------------------------------- 1 | local Binding = require('lua.core.binding') 2 | local Widget = require('lua.core.widget') 3 | 4 | ---@class Window 5 | local Window = {} 6 | 7 | Window.new = function(args) 8 | local new_window 9 | 10 | new_window = args.window { 11 | widget = args.widget, 12 | type = args.type, 13 | } 14 | 15 | args.window, args.widget, args.type = nil, nil, nil 16 | 17 | for key, value in pairs(args) do 18 | if string.match(key, '^[gs]et_') then 19 | rawset(new_window, key, value) 20 | end 21 | end 22 | 23 | new_window.hook = Widget.hook 24 | new_window.bind = Widget.bind 25 | 26 | for key, value in pairs(args) do 27 | if getmetatable(value) == Binding then 28 | value:subscribe(function(v) new_window[key] = v end) 29 | 30 | new_window[key] = value:get() 31 | elseif string.find(key, '^on_') ~= nil then 32 | local signal = key:gsub('^on_', ''):gsub('_', '-') 33 | new_window:connect_signal(signal, value) 34 | else 35 | new_window[key] = value 36 | end 37 | end 38 | 39 | if args.setup then 40 | args.setup(new_window) 41 | end 42 | 43 | return new_window 44 | end 45 | 46 | return Window 47 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/battery.lua: -------------------------------------------------------------------------------- 1 | --- https://github.com/Aylur/dotfiles/blob/ags-pre-ts/ags/js/settings/setup.js 2 | 3 | local Battery = lgi.require('AstalBattery') 4 | local gearsify = require('lua.core.gearsify') 5 | 6 | local battery = gearsify(Battery.get_default()) 7 | 8 | local LOW = 30 9 | 10 | return function() 11 | battery:connect_signal('property::percentage', function() 12 | if 13 | not battery.charging and (battery.percentage == LOW or battery.percentage == LOW / 2) 14 | then 15 | io.exec( 16 | string.format('notify-send "%.0f%% Battery Percentage"', battery.percentage * 100) 17 | ) 18 | end 19 | end) 20 | 21 | battery:connect_signal('property::charging', function(_, charging) 22 | if charging then 23 | io.exec(string.format('notify-send "Charger connected"')) 24 | end 25 | end) 26 | end 27 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/init.lua: -------------------------------------------------------------------------------- 1 | for _, fn in ipairs { 2 | -- require(... .. '.screencast'), 3 | -- require(... .. '.polkitagent'), 4 | require(... .. '.battery'), 5 | } do 6 | fn() 7 | end 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/polkitagent/init.lua: -------------------------------------------------------------------------------- 1 | ---https://www.freedesktop.org/software/polkit/docs/latest/eggdbus-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.html 2 | local DbusService = require('lua.subclasses.dbusservice') 3 | local src = require('lua.utils').src 4 | 5 | local xmlpath = src('org.freedesktop.PolicyKit1.AuthenticationAgent.xml') 6 | 7 | ----@class PolkitAgent: DbusService 8 | local PolkitAgent = DbusService.new( 9 | xmlpath, 10 | 'org.freedesktop.PolicyKit1', 11 | '/org/luajit/PolicyKit1/AuthenticationAgent' 12 | ) 13 | 14 | function PolkitAgent:begin_authentication(variant) require('gears.debug').print_error('CALLED') end 15 | 16 | function PolkitAgent:register() 17 | Gio.bus_get('SYSTEM', nil, function(_, task) 18 | local bus = Gio.bus_get_finish(task) 19 | 20 | bus:call( 21 | 'org.freedesktop.PolicyKit1', 22 | '/org/freedesktop/PolicyKit1/Authority', 23 | 'org.freedesktop.PolicyKit1.Authority', 24 | 'RegisterAuthenticationAgent', 25 | GLib.Variant('((sa{sv})ss)', { 26 | { 27 | 'unix-process', 28 | { 29 | pid = GLib.Variant('u', os.getpid()), 30 | ['start-time'] = GLib.Variant('t', 0), 31 | }, 32 | }, 33 | 'en_US', 34 | self.path, 35 | }), 36 | GLib.VariantType('()'), 37 | { 'NONE' }, 38 | -1, 39 | nil, 40 | function(_, Task) 41 | local variant, err = bus:call_finish(Task) 42 | if err ~= nil then 43 | print(err) 44 | end 45 | 46 | print(variant:print(true)) 47 | end 48 | ) 49 | end) 50 | end 51 | 52 | function PolkitAgent:_init() self:register() end 53 | 54 | return function() _ = PolkitAgent() end 55 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/polkitagent/org.freedesktop.PolicyKit1.AuthenticationAgent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/screencast/init.lua: -------------------------------------------------------------------------------- 1 | local DbusService = require('lua.subclasses.dbusservice') 2 | local src = require('lua.utils').src 3 | 4 | local xmlpath = src('org.freedesktop.portal.ScreenCast.xml') 5 | 6 | ---@class ScreenCast: DbusService 7 | local ScreenCast = DbusService.new( 8 | xmlpath, 9 | 'org.freedesktop.impl.portal.desktop.luajit', 10 | '/org/freedesktop/portal/desktop' 11 | ) 12 | 13 | ---@private 14 | function ScreenCast:get_version() return GLib.Variant('(u)', { 5 }) end 15 | 16 | return function() _ = ScreenCast() end 17 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/daemons/screencast/org.freedesktop.portal.ScreenCast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/globals.lua: -------------------------------------------------------------------------------- 1 | lgi = require('lgi') 2 | 3 | ---@generic T 4 | ---@type fun(libname: `T`, version?: string): T 5 | lgi.require = lgi.require 6 | 7 | Gtk = lgi.require('Gtk', '3.0') 8 | Gio = lgi.require('Gio') 9 | GLib = lgi.require('GLib') 10 | GObject = lgi.require('GObject') 11 | 12 | Widget = require('lua.core.widget') 13 | Window = require('lua.core.window') 14 | Variable = require('lua.core.variable') 15 | bind = require('lua.core.binding') 16 | 17 | dpi = require('beautiful.xresources').apply_dpi 18 | 19 | wibox = require('wibox.init') 20 | wibox.widget.custom = require('lua.widgets.custom') 21 | 22 | widget = wibox.widget 23 | cter = wibox.container 24 | bful = require('beautiful') 25 | 26 | capi = { 27 | ---@diagnostic disable 28 | awesome = awesome, 29 | client = client, 30 | mouse = mouse, 31 | screen = screen, 32 | root = root, 33 | mousegrabber = mousegrabber, 34 | selection = selection, 35 | drawin = drawin, 36 | tag = tag, 37 | key = key, 38 | ---@diagnostic enable 39 | } 40 | 41 | ---@generic F: function 42 | ---@param fn F 43 | ---@return F 44 | async = function(fn) 45 | return function(...) 46 | return Gio.Async.start(fn)(...) ---@diagnostic disable-line 47 | end 48 | end 49 | 50 | ---@class Logger 51 | ---@field domain string 52 | ---@field log fun(level: LogLevelString, fmt: string, ...): nil 53 | ---@field debug fun(fmt: string, ...): nil 54 | ---@field info fun(fmt: string, ...): nil 55 | ---@field message fun(fmt: string, ...): nil 56 | ---@field warning fun(fmt: string, ...): nil 57 | ---@field critical fun(fmt: string, ...): nil 58 | ---@field error fun(fmt: string, ...): nil 59 | Logger = {} 60 | 61 | ---@private 62 | Logger.domain = 'Luajit' 63 | 64 | ---@private 65 | ---@enum (key) LogLevelString 66 | Logger.levels = { 67 | DEBUG = { id = 1, color = '\27[36m' }, -- Cyan 68 | INFO = { id = 2, color = '\27[32m' }, -- Green 69 | MESSAGE = { id = 3, color = '\27[34m' }, -- Blue 70 | WARNING = { id = 4, color = '\27[33m' }, -- Yellow 71 | CRITICAL = { id = 5, color = '\27[35m' }, -- Magenta 72 | ERROR = { id = 6, color = '\27[31m' }, -- Red 73 | } 74 | ---@private 75 | Logger.reset = '\27[0m' 76 | 77 | ---@private 78 | function Logger.log(level_str, msg, ...) 79 | local level = Logger.levels[level_str] 80 | if not level then 81 | return 82 | end 83 | 84 | local timestamp = os.date('%Y-%m-%d %H:%M:%S') 85 | local color = level.color 86 | local message = string.format(msg, ...) 87 | 88 | io.stderr:write( 89 | string.format( 90 | '%s%s [%s] (%s): %s%s', 91 | timestamp, 92 | color, 93 | level_str, 94 | Logger.domain, 95 | message, 96 | Logger.reset 97 | ) 98 | ) 99 | 100 | if level_str == 'ERROR' then 101 | error(message, 2) 102 | end 103 | end 104 | 105 | for name in pairs(Logger.levels) do 106 | Logger[string.lower(name)] = function(fmt, ...) Logger.log(name, fmt, ...) end 107 | end 108 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/init.lua: -------------------------------------------------------------------------------- 1 | local gfs = require('gears').filesystem 2 | local menubar = require('menubar') 3 | local rubato = require('lib.rubato') 4 | local user = require(... .. '.user') 5 | 6 | rubato.set_def_rate(user.fps) 7 | 8 | menubar.utils.terminal = user.terminal 9 | bful.init(gfs.get_configuration_dir() .. 'theme/init.lua') 10 | 11 | capi.awesome.register_xproperty('_GTK_APPLICATION_ID', 'string') 12 | capi.awesome.register_xproperty('_GTK_APPLICATION_OBJECT_PATH', 'string') 13 | 14 | require(... .. '.signal') 15 | require(... .. '.keybindings') 16 | require(... .. '.rules') 17 | require(... .. '.daemons') 18 | -- require(... .. '.tests') 19 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/rules.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local ruled = require('ruled') 3 | 4 | ruled.client.append_rule { 5 | rule = {}, 6 | properties = { 7 | border_width = bful.border_width, 8 | border_color = bful.border_normal, 9 | focus = awful.client.focus.filter, 10 | raise = true, 11 | screen = awful.screen.preferred, 12 | placement = awful.placement.no_overlap + awful.placement.no_offscreen, 13 | }, 14 | } 15 | 16 | ruled.client.append_rule { 17 | rule_any = { type = { 'normal' } }, 18 | properties = { titlebars_enabled = true }, 19 | } 20 | 21 | ruled.client.append_rule { 22 | rule_any = { class = { 'firefox', 'discord' }, type = { 'dialog' } }, 23 | properties = { titlebars_enabled = false }, 24 | } 25 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/applications.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | 3 | ---@class App: Service 4 | ---@field app table 5 | ---@field entry string 6 | ---@field wm_class string 7 | ---@field name string 8 | ---@field description string 9 | ---@field icon_name string 10 | ---@overload fun(app: table): App 11 | local App = Service.new() ---@diagnostic disable-line 12 | 13 | function App:_init(app) self._app = app end 14 | function App:get_entry() return self.app:get_id() end 15 | function App:get_app() return self._app end 16 | function App:get_name() return self.app:get_name() end 17 | function App:get_description() return self.app:get_description() end 18 | function App:get_wm_class() return self.app:get_startup_wm_class() end 19 | function App:get_icon_name() return self.app:get_string('Icon') or 'application-x-executable' end 20 | 21 | function App:launch() return self.app:launch() end 22 | 23 | ---@param str string 24 | function App:query(str) 25 | return string.find( 26 | string.lower( 27 | table.concat( 28 | table.filter( 29 | { self.name, self.description, self.entry, self.wm_class, self.icon_name }, 30 | function(value) return value ~= nil end 31 | ), 32 | ' ' 33 | ) 34 | ), 35 | str:lower(), 36 | nil, 37 | true 38 | ) ~= nil 39 | end 40 | 41 | ---@class Applications: Service 42 | ---@field list App[] 43 | local Applications = Service.new() 44 | 45 | function Applications:_init() 46 | self._list = {} 47 | 48 | for _, value in ipairs(Gio.AppInfo.get_all()) do 49 | if not value:should_show() then 50 | goto continue 51 | end 52 | 53 | table.insert(self._list, App(value)) 54 | 55 | ::continue:: 56 | end 57 | 58 | table.sort(self._list, function(a, b) return a.name < b.name end) 59 | end 60 | 61 | function Applications:get_list() return table.copy(self._list) end 62 | 63 | function Applications:get_by_wm_class(wm_class) 64 | return table.find(self.list, function(value) return value.wm_class == wm_class end) 65 | end 66 | 67 | function Applications:query(str) 68 | return table.filter(self.list, function(value) return value:query(str) end) 69 | end 70 | 71 | ---@type Applications 72 | local apps = Applications() 73 | 74 | return { 75 | get_default = function() return apps end, 76 | } 77 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/appmenu.lua: -------------------------------------------------------------------------------- 1 | local AppMenu = require('lua.services.appmenu.init') 2 | 3 | return { 4 | get_default = function() return AppMenu.get_default() end, 5 | } 6 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/appmenu/com.canonical.AppMenu.Registrar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/appmenu/init.lua: -------------------------------------------------------------------------------- 1 | local DbusService = require('lua.subclasses.dbusservice') 2 | local src = require('lua.utils').src 3 | 4 | local xmlpath = src('com.canonical.AppMenu.Registrar.xml') 5 | 6 | ---@class AppMenu: DbusService 7 | local AppMenu = 8 | DbusService.new(xmlpath, 'com.canonical.AppMenu.Registrar', '/com/canonical/AppMenu/Registrar') 9 | 10 | local _instance = nil 11 | 12 | function AppMenu:get_actions(c, fn) 13 | self:get_raw_actions(c, function(variant) fn(variant) end) 14 | end 15 | 16 | function AppMenu:call_action(c, action_id, fn) 17 | local name = c:get_xproperty('_GTK_APPLICATION_ID') 18 | local path = c:get_xproperty('_GTK_APPLICATION_OBJECT_PATH') 19 | 20 | local bus_name, bus_path, iface, method, args, ret 21 | 22 | if name and #name > 0 and path and #path > 0 then 23 | bus_name = name 24 | bus_path = path 25 | iface, method, args, ret = 'org.gtk.Actions', 'Activate', { '()' }, '(sava{sv})' 26 | else 27 | local variant = self._registered_windows[c.window] 28 | 29 | if not (variant and variant[2]) then 30 | return 31 | end 32 | 33 | bus_name = variant[1] 34 | bus_path = variant[2] 35 | iface, method, args, ret = 36 | 'com.canonical.dbusmenu', 'GetLayout', { '(iias)', { 0, -1, {} } }, '(u(ia{sv}av))' 37 | end 38 | 39 | local v, vtype = GLib.Variant(table.unpack(args)), GLib.VariantType(ret) 40 | 41 | self:bus_call(bus_name, bus_path, iface, method, v, vtype, fn) 42 | end 43 | 44 | ---@private 45 | function AppMenu:get_raw_actions(c, fn) 46 | local name = c:get_xproperty('_GTK_APPLICATION_ID') 47 | local path = c:get_xproperty('_GTK_APPLICATION_OBJECT_PATH') 48 | 49 | local bus_name, bus_path, iface, method, args, ret 50 | 51 | if name and #name > 0 and path and #path > 0 then 52 | bus_name = name 53 | bus_path = path 54 | iface, method, args, ret = 'org.gtk.Actions', 'DescribeAll', { '()' }, '(a{s(bgav)})' 55 | else 56 | local variant = self._registered_windows[c.window] 57 | 58 | if not (variant and variant[2]) then 59 | return 60 | end 61 | 62 | bus_name = variant[1] 63 | bus_path = variant[2] 64 | iface, method, args, ret = 65 | 'com.canonical.dbusmenu', 'GetLayout', { '(iias)', { 0, -1, {} } }, '(u(ia{sv}av))' 66 | end 67 | 68 | local v, vtype = GLib.Variant(table.unpack(args)), GLib.VariantType(ret) 69 | 70 | self:bus_call(bus_name, bus_path, iface, method, v, vtype, fn) 71 | end 72 | 73 | ---@return AppMenu 74 | AppMenu.get_default = function() 75 | if _instance then 76 | return _instance 77 | end 78 | 79 | local i = AppMenu() 80 | i:register() 81 | 82 | _instance = i 83 | 84 | return _instance 85 | end 86 | 87 | function AppMenu:_init() self._registered_windows = {} end 88 | 89 | function AppMenu:register() 90 | capi.client.connect_signal('manage', function(c) 91 | local name, path = 92 | c:get_xproperty('_GTK_APPLICATION_ID'), c:get_xproperty('_GTK_APPLICATION_OBJECT_PATH') 93 | 94 | if #name > 0 and #path > 0 then 95 | self:register_window { 96 | name = name, 97 | variant = { value = { c.window, path } }, 98 | } 99 | end 100 | end) 101 | 102 | capi.client.connect_signal( 103 | 'unmanage', 104 | function(c) self:unregister_window { variant = { value = { c.window } } } end 105 | ) 106 | end 107 | 108 | ---@private 109 | ---@param tbl table 110 | function AppMenu:register_window(tbl, fn) 111 | local window_id, path = table.unpack(tbl.variant.value) 112 | 113 | if not self._registered_windows then 114 | self._registered_windows = {} 115 | end 116 | 117 | self._registered_windows[window_id] = { tbl.name, path } 118 | 119 | if fn then 120 | return fn(GLib.Variant('()')) 121 | end 122 | end 123 | 124 | ---@private 125 | ---@param tbl table 126 | function AppMenu:unregister_window(tbl, fn) 127 | local window_id = table.unpack(tbl.variant.value) 128 | 129 | self._registered_windows[window_id] = nil 130 | 131 | if fn then 132 | return fn(GLib.Variant('()')) 133 | end 134 | end 135 | 136 | ---@private 137 | ---@param tbl table 138 | function AppMenu:get_menu_for_window(tbl, fn) 139 | local window_id = table.unpack(tbl.variant.value) 140 | 141 | local data = self._registered_windows[window_id] 142 | 143 | if data then 144 | return fn(GLib.Variant('(so)', data)) 145 | end 146 | 147 | return fn(GLib.Variant('()')) 148 | end 149 | 150 | return { 151 | get_default = function() return AppMenu.get_default() end, 152 | } 153 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/brightness.lua: -------------------------------------------------------------------------------- 1 | --- ToDo: Fix Shitty Code 2 | 3 | local Service = require('lua.core.service') 4 | 5 | local SCREEN = 'intel_backlight' 6 | local SCREEN_FOLDER = '/sys/class/backlight/' .. SCREEN .. '/' 7 | 8 | local BRIGHTNESS_FILE = SCREEN_FOLDER .. 'brightness' 9 | local BRIGHTNESS_MAX_FILE = SCREEN_FOLDER .. 'max_brightness' 10 | 11 | local sender, path, iface = 12 | 'org.freedesktop.UPower', 13 | '/org/freedesktop/UPower/KbdBacklight', 14 | 'org.freedesktop.UPower.KbdBacklight' 15 | 16 | ---@class Brightness: Service 17 | ---@field screen_max number 18 | ---@field screen number 19 | ---@field kbd_max number 20 | ---@field kbd number 21 | local Brightness = Service.new() 22 | 23 | local _instance = nil 24 | 25 | function Brightness:get_screen_max() return self._private.screen_max end 26 | 27 | function Brightness:get_screen() return self._private.screen end 28 | 29 | function Brightness:set_screen(n) 30 | if n < 0 then 31 | n = 0 32 | elseif n > 1 then 33 | n = 1 34 | end 35 | 36 | if n ~= self.screen then 37 | self._private.screen = n 38 | 39 | io.exec(string.format('brightnessctl -d %s s %d -q', SCREEN, n * self.screen_max)) 40 | end 41 | end 42 | 43 | ---@return Brightness 44 | Brightness.get_default = function() 45 | if _instance then 46 | return _instance 47 | end 48 | 49 | local i = Brightness() 50 | i:register_screen() 51 | --i:register_kbd() 52 | 53 | _instance = i 54 | 55 | return i 56 | end 57 | 58 | function Brightness:register_screen() 59 | if not io.dir_exists(SCREEN_FOLDER) then 60 | return 61 | end 62 | 63 | io.read_file(BRIGHTNESS_MAX_FILE, function(content) 64 | self._private.screen_max = tonumber(content) 65 | self:notify('screen-max') 66 | 67 | io.read_file(BRIGHTNESS_FILE, function(c) 68 | self._private.screen = tonumber(c) / self.screen_max 69 | self:notify('screen') 70 | end) 71 | end) 72 | 73 | ---@param event Gio.FileMonitorEvent 74 | io.monitor_file(BRIGHTNESS_FILE, function(file, event) 75 | if event == 'CHANGED' then 76 | io.read_file(file, function(content) 77 | local new_br = tonumber(content) / self.screen_max 78 | 79 | if new_br ~= self.screen then 80 | self._private.screen = new_br 81 | self:notify('screen') 82 | end 83 | end) 84 | end 85 | end) 86 | end 87 | 88 | function Brightness:_init() 89 | self._private.screen = 0 90 | self._private.screen_max = 0 91 | end 92 | 93 | return { 94 | get_default = function() return Brightness.get_default() end, 95 | } 96 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/top.lua: -------------------------------------------------------------------------------- 1 | local GTop = lgi.require('GTop') 2 | local Service = require('lua.core.service') 3 | local gtimer = require('gears.timer') 4 | 5 | local POLLING = 3 6 | 7 | ---@class Top: Service 8 | ---@field cpu integer 9 | ---@field cpu_total integer 10 | ---@field cpu_used integer 11 | ---@field memory integer 12 | ---@field memory_total integer 13 | ---@field memory_used integer 14 | local Top = Service.new() 15 | local _instance = nil 16 | 17 | ---@return Top 18 | Top.get_default = function() 19 | if _instance then 20 | return _instance 21 | end 22 | 23 | local i = Top() 24 | 25 | _instance = i 26 | 27 | return _instance 28 | end 29 | 30 | function Top:get_memory_total() return self._private.memory_total end 31 | 32 | function Top:get_memory_used() return self._private.memory_used end 33 | 34 | function Top:get_memory() 35 | if self.memory_total == 0 then 36 | return 0 37 | end 38 | return self.memory_used / self.memory_total 39 | end 40 | 41 | function Top:get_cpu_total() return self._private.cpu_total end 42 | function Top:get_cpu_used() return self._private.cpu_used end 43 | 44 | function Top:get_cpu() 45 | if self.cpu_total == 0 then 46 | return 0 47 | end 48 | 49 | return self.cpu_used / self.cpu_total 50 | end 51 | 52 | function Top:_init() 53 | self._private.cpu = GTop.glibtop_cpu() 54 | self._private.cpu_used = 0 55 | self._private.cpu_total = 0 56 | 57 | self._private.cpu_timer = gtimer.start_new(POLLING, function() 58 | local data = { 'user', 'nice', 'sys', 'irq', 'softirq', 'idle', 'iowait' } 59 | local cpu = self._private.cpu 60 | 61 | local old_info = table.pick(cpu, data) 62 | GTop.glibtop_get_cpu(cpu) 63 | local new_info = table.pick(cpu, data) 64 | 65 | if not old_info or not new_info then 66 | return 0 67 | end 68 | 69 | local used = new_info.user + new_info.nice + new_info.sys + new_info.irq + new_info.softirq 70 | local total = used + new_info.idle + new_info.iowait 71 | 72 | self._private.cpu_used = used - self.cpu_used 73 | self._private.cpu_total = total - self.cpu_total 74 | 75 | self:notify('cpu-used') 76 | self:notify('cpu') 77 | 78 | return true 79 | end) 80 | 81 | self._private.memory = GTop.glibtop_mem() 82 | self._private.memory_total = 0 83 | self._private.memory_used = 0 84 | 85 | self._private.memory_timer = gtimer.start_new(POLLING, function() 86 | local mem = self._private.memory 87 | 88 | GTop.glibtop_get_mem(mem) 89 | 90 | if mem.total == 0 then 91 | return 92 | end 93 | 94 | local total = mem.total 95 | local used = total - (mem.free + mem.buffer + mem.cached) 96 | 97 | if total ~= self.memory_total then 98 | self._private.memory_total = total 99 | self:notify('memory-total') 100 | end 101 | 102 | if used ~= self.memory_used then 103 | self._private.memory_used = used 104 | self:notify('memory-used') 105 | end 106 | 107 | self:notify('memory') 108 | 109 | return true 110 | end) 111 | end 112 | 113 | return { 114 | get_default = function() return Top.get_default() end, 115 | } 116 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/wallpaper.lua: -------------------------------------------------------------------------------- 1 | local Wallpaper = require('lua.services.wallpaper.init') 2 | 3 | return { 4 | get_default = Wallpaper.get_default, 5 | } 6 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/wallpaper/init.lua: -------------------------------------------------------------------------------- 1 | local DbusService = require('lua.subclasses.dbusservice') 2 | local gfs = require('gears.filesystem') 3 | local src = require('lua.utils').src 4 | 5 | local BACKGROUND_FILE = gfs.get_xdg_config_home() .. 'background' 6 | local LOCKSCREEN_FILE = gfs.get_xdg_config_home() .. 'lockscreen' 7 | 8 | local xmlpath = src('org.freedesktop.portal.Wallpaper.xml') 9 | 10 | ---@class Wallpaper: DbusService 11 | ---@field background string 12 | ---@field lockscreen string 13 | local Wallpaper = DbusService.new( 14 | xmlpath, 15 | 'org.freedesktop.impl.portal.desktop.luajit', 16 | '/org/freedesktop/portal/desktop' 17 | ) 18 | 19 | local _instance = nil 20 | 21 | function Wallpaper:set_background(file_path) 22 | if io.file_exists(file_path) then 23 | io.read_file(file_path, function(content) 24 | io.write_file(BACKGROUND_FILE, content, function() self:notify('background') end) 25 | end) 26 | end 27 | end 28 | 29 | function Wallpaper:get_background() return self._background end 30 | 31 | function Wallpaper:set_lockscreen(file_path) 32 | if io.file_exists(file_path) then 33 | io.read_file(file_path, function(content) 34 | io.write_file(LOCKSCREEN_FILE, content, function() self:notify('lockscreen') end) 35 | end) 36 | end 37 | end 38 | 39 | ---@return Wallpaper 40 | Wallpaper.get_default = function() 41 | if _instance then 42 | return _instance 43 | end 44 | 45 | local i = Wallpaper() 46 | i:register() 47 | 48 | _instance = i 49 | 50 | return _instance 51 | end 52 | 53 | ---@private 54 | ---@param tbl table 55 | function Wallpaper:set_wallpaper_uri(tbl, fn) 56 | local handle, app_id, parent_window, uri = table.unpack(tbl.variant.value) ---@diagnostic disable-line 57 | 58 | ---@type { ["show-preview"]: boolean, ["set-on"]: "background"|"lockscreen"|"both"} 59 | local options = variant:get_child_value(4).value ---@diagnostic disable-line 60 | 61 | local file_path = GLib.Uri.parse(uri, 'ENCODED_PATH'):get_path() 62 | 63 | if not io.file_exists(file_path) then 64 | return fn(GLib.Variant('(u)', { 0 })) 65 | end 66 | 67 | if options['set-on'] == 'background' then 68 | self:set_background(file_path) 69 | elseif options['set-on'] == 'lockscreen' then 70 | self:set_lockscreen(file_path) 71 | elseif options['set-on'] == 'both' then 72 | self:set_lockscreen(file_path) 73 | self:set_background(file_path) 74 | end 75 | 76 | return fn(GLib.Variant('(u)', { 1 })) 77 | end 78 | 79 | ---@private 80 | function Wallpaper:register() 81 | io.monitor_file(BACKGROUND_FILE, function(_, event) 82 | if event ~= 'RENAMED' then 83 | return 84 | end 85 | 86 | self:notify('background') 87 | end) 88 | 89 | io.monitor_file(LOCKSCREEN_FILE, function(_, event) 90 | if event ~= 'RENAMED' then 91 | return 92 | end 93 | 94 | self:notify('lockscreen') 95 | end) 96 | end 97 | 98 | ---@private 99 | function Wallpaper:_init() 100 | self._background = BACKGROUND_FILE 101 | self._lockscreen = LOCKSCREEN_FILE 102 | 103 | if io.file_exists(BACKGROUND_FILE) then 104 | self:notify('background') 105 | end 106 | 107 | if io.file_exists(LOCKSCREEN_FILE) then 108 | self:notify('lockscreen') 109 | end 110 | end 111 | 112 | return { 113 | get_default = function() return Wallpaper.get_default() end, 114 | } 115 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/services/wallpaper/org.freedesktop.portal.Wallpaper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/signal/client.lua: -------------------------------------------------------------------------------- 1 | local set_titlebar = require('lua.widgets.titlebar') 2 | 3 | capi.client.connect_signal( 4 | 'mouse::enter', 5 | function(c) c:emit_signal('request::activate', 'mouse_enter', { raise = false }) end 6 | ) 7 | 8 | capi.client.connect_signal('request::titlebars', function(c) 9 | if not c.titlebar then 10 | c.titlebar = set_titlebar(c) 11 | end 12 | end) 13 | 14 | capi.client.connect_signal('manage', function(c) 15 | c.floating = true 16 | c.border_color = bful.border_color_normal 17 | end) 18 | 19 | capi.client.connect_signal('focus', function(c) 20 | if #c.first_tag:clients() == 1 then 21 | return 22 | end 23 | c.border_color = bful.border_color_active 24 | end) 25 | 26 | capi.client.connect_signal('unfocus', function(c) c.border_color = bful.border_color_normal end) 27 | 28 | capi.client.connect_signal('property::floating', function(c) c.ontop = c.floating end) 29 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/signal/init.lua: -------------------------------------------------------------------------------- 1 | require(... .. '.tag') 2 | require(... .. '.screen') 3 | require(... .. '.client') 4 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/signal/screen.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local new_bar = require('lua.widgets.bar') 3 | local new_ccenter = require('lua.widgets.controlcenter') 4 | local new_dock = require('lua.widgets.dock') 5 | local new_notifpopups = require('lua.widgets.notifications') 6 | local new_overview = require('lua.widgets.overview') 7 | local new_wallpaper = require('lua.widgets.wallpaper') 8 | local set_launcher = require('lua.widgets.launcher') 9 | local user = require('lua.user') 10 | 11 | capi.screen.connect_signal('request::desktop_decoration', function(s) 12 | s.tags = table.map( 13 | user.tags, 14 | function(value) 15 | return awful.tag.add( 16 | value, 17 | { screen = s, layout = user.layouts[1], layouts = user.layouts } 18 | ) 19 | end 20 | ) 21 | 22 | s.bar = new_bar(s) 23 | s.dock = new_dock(s) 24 | s.overview = new_overview(s) 25 | s.ccenter = new_ccenter(s) 26 | s.launcher = set_launcher() 27 | s.notifications = new_notifpopups(s) 28 | end) 29 | 30 | capi.screen.connect_signal('request::wallpaper', function(s) 31 | if not s.wallpaper then 32 | s.wallpaper = new_wallpaper(s) 33 | end 34 | end) 35 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/signal/tag.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local user = require('lua.user') 3 | 4 | capi.tag.connect_signal( 5 | 'request::default_layouts', 6 | function() awful.layout.append_default_layouts(user.layouts) end 7 | ) 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/subclasses/color.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | local color = require('lib.color') 3 | local gcolor = require('gears.color') 4 | 5 | local STEPS = require('lua.user').fps 6 | 7 | ---@alias ColorConstructor { 8 | ---initial: string, 9 | ---duration: number, 10 | ---} 11 | 12 | ---@class Color: Service 13 | ---@field duration number 14 | ---@field target string 15 | ---@field current string 16 | ---@field previous string 17 | ---@field private _target table 18 | ---@field private _previous table 19 | ---@field private _current table 20 | ---@field private _timer table 21 | ---@field private _duration number 22 | ---@overload fun(args: ColorConstructor): Color 23 | local Color = Service.new() ---@diagnostic disable-line 24 | 25 | Color.parse = function(c) 26 | local r, g, b, a = gcolor.parse_color(c) 27 | r = (r or 1) * 255 28 | g = (g or 1) * 255 29 | b = (b or 1) * 255 30 | a = (a or 0) 31 | return color.color { r = r, g = g, b = b, a = a } 32 | end 33 | 34 | ---@param args ColorConstructor 35 | ---@return Color 36 | Color.new = function(args) return Color(args) end 37 | 38 | function Color:get_duration() return self._duration end 39 | 40 | function Color:get_current() return self._current.hex end 41 | 42 | function Color:get_previous() return self._previous.hex end 43 | 44 | function Color:set_target(new) 45 | local n = color.color { hex = self.current } 46 | 47 | if n.hex ~= self._previous.hex then 48 | self._previous = n 49 | end 50 | 51 | self._target = Color.parse(new) 52 | 53 | local fn = color.transition(n, self._target, color.transition.RGB) 54 | 55 | local i = 0 56 | 57 | GLib.timeout_add(GLib.PRIORITY_DEFAULT, self.duration / STEPS, function() 58 | i = i + 1 59 | self._current = fn(i / STEPS) 60 | self:notify('current') 61 | 62 | return i < STEPS 63 | end) 64 | end 65 | 66 | ---@param args ColorConstructor 67 | function Color:_init(args) 68 | self._current = Color.parse(args.initial) 69 | self._previous = color.color { hex = self.current } 70 | self._target = color.color {} 71 | self._duration = args.duration 72 | end 73 | 74 | return Color 75 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/subclasses/dbusservice.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | local gobject = require('gears.object') 3 | local gtable = require('gears.table') 4 | 5 | local pascal_to_snake = function(str) 6 | local snake = str:gsub('(%u)', function(c) return '_' .. c:lower() end) 7 | if snake:sub(1, 1) == '_' then 8 | snake = snake:sub(2) 9 | end 10 | return snake 11 | end 12 | 13 | ---Shrimple class to allows us to define 14 | ---custom dbus services calling getters/setters/functions automatically 15 | 16 | ---@class DbusService: Service 17 | ---@field protected connection Gio.DbusConnection r 18 | ---@field protected iface_info Gio.DBusNodeInfo r 19 | ---@field protected xmlpath string 20 | ---@field protected xml string 21 | ---@field protected name string 22 | ---@field protected iface string 23 | ---@field protected path string 24 | local DbusService = Service.new() 25 | DbusService.__index = DbusService 26 | 27 | Service.new = function() return setmetatable({}, Service) end 28 | 29 | DbusService.new = function(xmlpath, iface, path) 30 | local ret = setmetatable({ _private = {} }, DbusService) 31 | 32 | ret._private.xmlpath = xmlpath 33 | ret._private.iface = iface 34 | ret._private.path = path 35 | 36 | return ret 37 | end 38 | 39 | function DbusService:get_xmlpath() return self._private.xmlpath end 40 | function DbusService:get_xml() return self._private.xml end 41 | function DbusService:get_name() return self.iface_info.name end 42 | function DbusService:get_iface_info() return self._private.iface_info end 43 | function DbusService:get_iface() return self._private.iface end 44 | function DbusService:get_path() return self._private.path end 45 | 46 | ---@private 47 | function DbusService:__call(...) 48 | local s = gobject { class = self, enable_properties = true } 49 | 50 | s:_init(...) 51 | s:_register() 52 | 53 | return s 54 | end 55 | 56 | ---@private 57 | function DbusService:do_call(method, parameters, fn) 58 | local fname = pascal_to_snake(method) 59 | 60 | if not self[fname] then 61 | if DEBUG then 62 | Logger.critical('%s: %s function not created', self.name, fname) 63 | end 64 | return 65 | end 66 | 67 | if DEBUG then 68 | Logger.info('%s: %s function called', self.name, fname) 69 | end 70 | 71 | return self[fname](self, parameters, fn) 72 | end 73 | 74 | ---@private 75 | function DbusService:do_get_property(property) 76 | local pname = pascal_to_snake(property) 77 | 78 | if not self[pname] then 79 | return Logger.critical('%s: %s property dont exists', self.name, pname) 80 | end 81 | 82 | return self[pname] 83 | end 84 | 85 | ---@private 86 | function DbusService:do_set_property(property, value) 87 | local pname = pascal_to_snake(property) 88 | 89 | if not self[pname] then 90 | return Logger.critical('%s: %s property dont exists', self.name, pname) 91 | end 92 | 93 | self[pname] = value 94 | end 95 | 96 | ---@private 97 | function DbusService:get_connection() return self._connection end 98 | 99 | function DbusService:bus_call(name, path, iface, method, params, returnval, callback) 100 | self.connection:call( 101 | name, 102 | path, 103 | iface, 104 | method, 105 | params, 106 | returnval, 107 | { 'NONE' }, 108 | -1, 109 | nil, 110 | function(_, task) callback(self.connection:call_finish(task)) end 111 | ) 112 | end 113 | 114 | ---@private 115 | function DbusService:_register() 116 | io.read_file(self.xmlpath, function(content) 117 | self._private.xml = content 118 | self._private.iface_info = Gio.DBusNodeInfo.new_for_xml(content).interfaces[1] 119 | 120 | Gio.bus_own_name( 121 | 'SESSION', 122 | self.iface, 123 | { 'NONE' }, 124 | GObject.Closure(function(connection) ---@diagnostic disable-line 125 | self._connection = connection 126 | 127 | self.connection:register_object( 128 | self.path, 129 | self.iface_info, 130 | GObject.Closure( 131 | function(_, name, path, iface, method, parameters, method_invocation) 132 | self:do_call(method, { 133 | name = name, 134 | path = path, 135 | iface = iface, 136 | variant = parameters, 137 | }, function(...) 138 | method_invocation:return_value(...) 139 | end) 140 | end 141 | ), 142 | GObject.Closure( 143 | function(_, _, _, _, propname) return self:do_get_property(propname) end 144 | ), 145 | GObject.Closure( 146 | function(_, _, _, _, propname, new_value) 147 | self:do_set_property(propname, new_value) 148 | end 149 | ) 150 | ) 151 | end), 152 | GObject.Closure(function() Logger.message('Name acquired %s', self.name) end), 153 | GObject.Closure(function() Logger.warning("Couldn't acquire %s", self.name) end) 154 | ) 155 | end) 156 | end 157 | 158 | return DbusService 159 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/subclasses/timed.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | local gtable = require('gears.table') 3 | local rubato = require('lib.rubato') 4 | 5 | ---@alias TimedConstructor { 6 | ---duration: number, 7 | ---rate: number, 8 | ---prop_intro?: boolean, 9 | ---initial?: number, 10 | ---intro: number, 11 | ---outro?: number, 12 | ---easing: table, 13 | ---easing_outro?: table, 14 | ---easing_inter?: table, 15 | ---} 16 | 17 | ---@class Timed: Service 18 | ---@field target number 19 | ---@field current number 20 | ---@field intro number 21 | ---@field outro number 22 | ---@field private _target table 23 | ---@field private _current table 24 | ---@field private _duration number 25 | ---@overload fun(args: TimedConstructor): Timed 26 | local Timed = Service.new() 27 | 28 | ---@param args TimedConstructor 29 | Timed.new = function(args) return Timed(args) end 30 | 31 | function Timed:get_current() return self._current end 32 | 33 | function Timed:get_target() return self._private.timed.target end 34 | 35 | function Timed:set_target(target) 36 | self._private.timed.target = target 37 | self:notify('target') 38 | end 39 | 40 | function Timed:set_pause(pause) 41 | self._private.timed.pause = pause 42 | self:notify('pause') 43 | end 44 | 45 | function Timed:get_pause() return self._private.timed.pause end 46 | 47 | ---@param args TimedConstructor 48 | function Timed:_init(args) 49 | args = gtable.crush(args, { 50 | pos = args.initial, 51 | subscribed = function(p) 52 | self._current = p 53 | self:notify('current') 54 | end, 55 | }) 56 | 57 | args.duration = args.duration / 1000 58 | args.intro = (args.intro or 1000) / 1000 59 | args.outro = (args.outro or args.intro) / 1000 60 | 61 | self._private.timed = rubato.timed(args) 62 | end 63 | 64 | return Timed 65 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/subclasses/varmap.lua: -------------------------------------------------------------------------------- 1 | local Service = require('lua.core.service') 2 | local Widget = require('lua.core.widget') 3 | 4 | ---@class Varmap: Service 5 | ---@field private _values table 6 | ---@overload fun(initial: table): Varmap 7 | local Varmap = Service.new() ---@diagnostic disable-line 8 | Varmap.__index = Varmap 9 | Varmap.__type = 'Varmap' 10 | 11 | ---@return Varmap 12 | Varmap.new = function(value) return Varmap(value) end 13 | 14 | function Varmap:is_type_of(obj) return type(obj) == 'table' and obj.__type == Varmap.__type end 15 | 16 | function Varmap:get(key) return self._values[key] end 17 | 18 | function Varmap:set(key, value) 19 | self._values[key] = value 20 | self:notify('values') 21 | end 22 | 23 | function Varmap:delete(key) 24 | if Widget:is_type_of(self._values[key]) then 25 | self._values[key]:destroy() 26 | end 27 | 28 | self._values[key] = nil 29 | self:notify('values') 30 | end 31 | 32 | function Varmap:values() return table.values(self._values) end 33 | function Varmap:keys() return table.keys(self._values) end 34 | 35 | function Varmap:drop() 36 | for _, value in ipairs(self:values()) do 37 | if Widget:is_type_of(value) then 38 | value:destroy() 39 | end 40 | end 41 | 42 | self._values = {} 43 | end 44 | 45 | function Varmap:_init(initial) 46 | if not initial then 47 | return 48 | end 49 | 50 | self._values = initial 51 | 52 | self:notify('values') 53 | end 54 | 55 | function Varmap:subscribe(callback) 56 | return self:smart_connect('property::values', function() callback(self:values()) end) 57 | end 58 | 59 | return Varmap 60 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/tests.lua: -------------------------------------------------------------------------------- 1 | local gdebug = require('gears.debug') 2 | local newWidget = {} 3 | 4 | local function flatten(tbl) 5 | local copy = {} 6 | for _, value in pairs(tbl) do 7 | if 8 | type(value) == 'table' 9 | and getmetatable(value) == nil 10 | and not (Widget:is_ctor(value) or Widget:is_type_of(value)) 11 | then 12 | for _, inner in pairs(flatten(value)) do 13 | table.insert(copy, inner) 14 | end 15 | else 16 | table.insert(copy, value) 17 | end 18 | end 19 | return copy 20 | end 21 | 22 | local function filter(tbl, fn) 23 | local copy = {} 24 | for key, value in pairs(tbl) do 25 | if fn(value, key) then 26 | if type(key) == 'number' then 27 | table.insert(copy, value) 28 | else 29 | copy[key] = value 30 | end 31 | end 32 | end 33 | return copy 34 | end 35 | 36 | local function merge_bindings(array) 37 | local function get_values(...) 38 | local args = { ... } 39 | local i = 0 40 | return table.map(array, function(value) 41 | if bind:is_type_of(value) then 42 | i = i + 1 43 | return args[i] 44 | end 45 | 46 | return value 47 | end) 48 | end 49 | 50 | local bindings = filter(array, function(v) return bind:is_type_of(v) end) 51 | 52 | if #bindings == 0 then 53 | return array 54 | end 55 | 56 | return bind.merge(bindings, get_values) 57 | end 58 | 59 | newWidget.new = function(args) 60 | local new_widget 61 | 62 | local ctor_args = table.pick(args, { 'widget', 'layout', 'draw', 'fit', 'screen', 'menu' }) 63 | 64 | if args.widget == wibox.widget.base.make_widget then 65 | new_widget = args.widget(nil, nil, { enable_properties = true }) -- getters/setters 66 | 67 | for key, value in pairs(ctor_args) do 68 | rawset(new_widget, key, value) 69 | end 70 | else 71 | new_widget = wibox.widget(ctor_args) 72 | end 73 | 74 | for key in pairs(ctor_args) do 75 | args[key] = nil 76 | end 77 | 78 | local bindings = {} 79 | 80 | local children = 81 | merge_bindings(flatten(filter(args, function(_, key) return type(key) == 'number' end))) 82 | 83 | local gs_etters = filter(args, function(_, key) return string.match(key, '^[gs]et_') ~= nil end) 84 | 85 | local handlers = filter(args, function(_, key) return string.find(key, '^on_') ~= nil end) 86 | 87 | local props = filter(args, function(_, key) return type(key) == 'string' and key ~= 'setup' end) 88 | end 89 | 90 | local ctor = { 91 | layout = wibox.layout.fixed.horizontal, 92 | { 93 | widget = widget.textbox, 94 | text = 'aaa', 95 | }, 96 | { 97 | { 98 | widget = widget.textbox, 99 | text = 'aaa', 100 | }, 101 | { 102 | widget = widget.textbox, 103 | text = 'aaa', 104 | }, 105 | }, 106 | { 107 | { 108 | { 109 | { 110 | { 111 | { 112 | 113 | bind('a', 'a'):as(function(value) return 'ae' end), 114 | }, 115 | }, 116 | }, 117 | }, 118 | }, 119 | }, 120 | } 121 | 122 | local children = 123 | flatten_children(table.filter(ctor, function(_, index) return type(index) == 'number' end)) 124 | 125 | gdebug.dump(children, nil, 1) 126 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/user.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | local module = {} 4 | 5 | module.fps = 144 6 | 7 | module.icon_theme = 'MoreWaita' 8 | 9 | module.web_browser = 'firefox' 10 | module.terminal = 'wezterm start --always-new-process' 11 | module.editor = module.terminal .. ' -e nvim' 12 | module.file_explorer = 'nautilus -w' 13 | 14 | module.launcher = { 15 | apps_limit = 10, 16 | cmds_limit = 7, 17 | } 18 | 19 | module.dock = { 20 | pinned_apps = { 21 | 'firefox.desktop', 22 | 'obsidian.desktop', 23 | 'org.gnome.Nautilus.desktop', 24 | 'page.kramo.Cartridges.desktop', 25 | }, 26 | } 27 | 28 | module.notifications = { 29 | timeout = 5000, 30 | } 31 | 32 | module.tags = { '1', '2', '3', '4', '5', '6' } 33 | module.resize_factor = 10 34 | module.gaps = 5 35 | module.border_width = 3 36 | 37 | local suit = awful.layout.suit 38 | 39 | module.layouts = { 40 | suit.tile, 41 | suit.tile.left, 42 | suit.tile.bottom, 43 | suit.tile.top, 44 | suit.fair, 45 | suit.fair.horizontal, 46 | suit.spiral, 47 | suit.spiral.dwindle, 48 | suit.max, 49 | suit.max.fullscreen, 50 | suit.magnifier, 51 | suit.corner.nw, 52 | suit.corner.ne, 53 | suit.corner.sw, 54 | suit.corner.se, 55 | suit.floating, 56 | } 57 | 58 | module.colors = { 59 | base00 = '#161616', 60 | base01 = '#232323', 61 | base02 = '#393939', 62 | base03 = '#525252', 63 | base04 = '#dde1e6', 64 | base05 = '#f2f4f8', 65 | base06 = '#ffffff', 66 | base07 = '#08bdba', 67 | base08 = '#3ddbd9', 68 | base09 = '#78a9ff', 69 | base0A = '#ee5396', 70 | base0B = '#33b1ff', 71 | base0C = '#ff7eb6', 72 | base0D = '#43b365', 73 | base0E = '#be95ff', 74 | base0F = '#82cfff', 75 | } 76 | 77 | return module 78 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/utils.lua: -------------------------------------------------------------------------------- 1 | local gfs = require('gears.filesystem') 2 | local gshape = require('gears.shape') 3 | 4 | local module = {} 5 | 6 | local dir = gfs.get_configuration_dir() 7 | local THEME = Gtk.IconTheme.get_default() 8 | THEME:prepend_search_path(dir .. 'theme/icons/symbolic') 9 | 10 | ---@param radius number 11 | ---@return function 12 | module.rrect = function(radius) 13 | return function(cr, width, height) gshape.rounded_rect(cr, width, height, radius) end 14 | end 15 | 16 | module.squircle = function(radius) 17 | return function(cr, width, height) gshape.squircle(cr, width, height, radius) end 18 | end 19 | 20 | module.psquircle = function(r1, r2, r3, r4) 21 | return function(cr, width, height) 22 | return gshape.partial_squircle(cr, width, height, r1, r2, r3, r4) 23 | end 24 | end 25 | 26 | module.prrect = function(radius, r1, r2, r3, r4) 27 | return function(cr, width, height) 28 | return gshape.partially_rounded_rect(cr, width, height, r1, r2, r3, r4, radius) 29 | end 30 | end 31 | 32 | local found_icons = {} 33 | 34 | ---@return string? 35 | module.lookup_icon = function(icon_name) 36 | if not icon_name then 37 | return 38 | end 39 | 40 | if found_icons[icon_name] then 41 | return found_icons[icon_name] 42 | end 43 | 44 | local icon_info, path 45 | 46 | for _, name in ipairs { icon_name, icon_name:lower(), icon_name:upper() } do 47 | for _, size in ipairs { 512, 256, 128, 64, 48, 32, 24, 16 } do 48 | icon_info = THEME:lookup_icon(name, size, 'USE_BUILTIN') 49 | 50 | if icon_info then 51 | path = icon_info:get_filename() 52 | 53 | if path then 54 | found_icons[name] = path 55 | 56 | return path 57 | end 58 | end 59 | end 60 | end 61 | end 62 | 63 | module.colorize = function(str, color) 64 | return string.format("%s", color, str) 65 | end 66 | 67 | module.src = function(path) 68 | path = path or '' 69 | local str = debug.getinfo(2, 'S').source:sub(2) 70 | local src = str:match('(.*/)') or str:match('(.*\\)') or './' 71 | return src .. path 72 | end 73 | 74 | return module 75 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/variables.lua: -------------------------------------------------------------------------------- 1 | local module = {} 2 | 3 | module.time = Variable.new(GLib.DateTime.new_now_local()) 4 | :poll(60000, function() return GLib.DateTime.new_now_local() end) 5 | 6 | local layout = function() return capi.awesome.xkb_get_group_names() end 7 | 8 | module.kbdlayout = Variable.new(layout()) 9 | :observe(capi.awesome, 'xkb::map_changed', layout) 10 | :observe(capi.awesome, 'xkb::group_changed', layout) 11 | 12 | return module 13 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/activeclient.lua: -------------------------------------------------------------------------------- 1 | -- local appmenu = require('lua.services.appmenu').get_default() 2 | 3 | return function(s) 4 | local fn = function() 5 | return table.find(s.clients, function(c) return c.active end) --- get active client 6 | end 7 | 8 | local active_client = Variable 9 | .new(fn()) --- dont use property::active cuz its buggy 10 | :observe(capi.client, 'focus', function() return fn() end) 11 | :observe(capi.client, 'unmanage', function() return fn() end) 12 | :observe(capi.tag, 'property::selected', function() return fn() end) 13 | 14 | local active_tag = Variable.new(s.selected_tag) 15 | :observe(capi.tag, 'property::selected', function() 16 | return s.selected_tag -- 17 | end) 18 | 19 | local font = bful.font .. ' semibold 12' 20 | 21 | return { 22 | layout = wibox.layout.flex.horizontal, 23 | on_destroy = function() 24 | active_client:drop() 25 | active_tag:drop() 26 | end, 27 | { 28 | widget = wibox.layout.stack, 29 | { 30 | widget = widget.textbox, 31 | font = font, 32 | visible = bind(active_client), 33 | text = bind(active_client):as(function(value) 34 | if not value then 35 | return '' 36 | end 37 | 38 | local app_id = value:get_xproperty('_GTK_APPLICATION_ID') 39 | app_id = (app_id and #app_id > 1) and app_id 40 | 41 | return app_id or value.class or value.name 42 | end):as(function(value) 43 | if string.match(value, '%u') then 44 | return value 45 | end 46 | return string.title(value) 47 | end), 48 | }, 49 | { 50 | widget = widget.textbox, 51 | font = font, 52 | visible = bind(active_client):as(function(value) return not value end), 53 | text = bind(active_tag):as( 54 | function(value) return string.format('on Tag %s', value and value.name or '') end 55 | ), 56 | }, 57 | }, 58 | -- { 59 | -- layout = wibox.layout.flex.horizontal, 60 | -- setup = function(self) 61 | -- self:hook(active_client, function(_, c) 62 | -- if not c then 63 | -- return 64 | -- end 65 | 66 | -- appmenu:get_actions(c, function(variant) 67 | -- if not variant then 68 | -- return self:set_children {} 69 | -- end 70 | 71 | -- local v = variant:get_child_value(0) 72 | 73 | -- require('gears.debug').print_error(v:print()) 74 | 75 | -- local children = {} 76 | 77 | -- for key in v:pairs() do 78 | -- table.insert( 79 | -- children, 80 | -- Widget.new { 81 | -- widget = widget.textbox, 82 | -- text = key, 83 | -- on_primary_click = function() appmenu:call_action(c, key) end, 84 | -- } 85 | -- ) 86 | -- end 87 | 88 | -- self.children = children 89 | -- end) 90 | -- end) 91 | -- end, 92 | -- }, 93 | } 94 | end 95 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/clock.lua: -------------------------------------------------------------------------------- 1 | local time = require('lua.variables').time 2 | local utils = require('lua.utils') 3 | 4 | return function() 5 | local font = bful.font .. ' medium 13' 6 | 7 | return { 8 | widget = cter.background, 9 | bg = bful.bar_module_bg, 10 | shape = utils.rrect(bful.bar_module_roundness), 11 | forced_height = bful.bar_module_height, 12 | { 13 | widget = cter.margin, 14 | left = bful.bar_module_hpadding, 15 | right = bful.bar_module_hpadding, 16 | { 17 | layout = wibox.layout.fixed.horizontal, 18 | { 19 | widget = widget.textbox, 20 | text = bind(time):as(function(datetime) return datetime:format('%H:%M') end), 21 | font = font, 22 | }, 23 | { 24 | widget = widget.custom.icon, 25 | icon = 'dot-symbolic', 26 | size = dpi(16), 27 | valign = 'center', 28 | }, 29 | { 30 | widget = widget.textbox, 31 | text = bind(time):as(function(datetime) return datetime:format('%a %d %b') end), 32 | font = font, 33 | }, 34 | }, 35 | }, 36 | } 37 | end 38 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/init.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local user = require('lua.user') 3 | 4 | local add_kbdlayout = require(... .. '.kbdlayout') 5 | local add_systray = require(... .. '.systray') 6 | local set_activeclient = require(... .. '.activeclient') 7 | local set_clock = require(... .. '.clock') 8 | local set_layoutbox = require(... .. '.layoutbox') 9 | local set_taglist = require(... .. '.taglist') 10 | 11 | local Battery = lgi.require('AstalBattery') 12 | local Network = lgi.require('AstalNetwork') 13 | local Wp = lgi.require('AstalWp') 14 | 15 | local gearsify = require('lua.core.gearsify') 16 | 17 | local brightness = require('lua.services.brightness').get_default() 18 | 19 | local separator = function() 20 | return { 21 | widget = widget.custom.icon, 22 | icon = 'dot-symbolic', 23 | size = dpi(16), 24 | valign = 'center', 25 | color = user.colors.base02, 26 | } 27 | end 28 | 29 | local battery_icon = function() 30 | local battery = gearsify(Battery.get_default()) 31 | return { 32 | widget = widget.custom.icon, 33 | valign = 'center', 34 | size = dpi(16), 35 | icon = bind(battery, 'battery-icon-name'), 36 | } 37 | end 38 | 39 | local wifi_icon = function() 40 | local network = gearsify(Network.get_default()) 41 | local wifi = gearsify(network.wifi) 42 | 43 | return { 44 | widget = widget.custom.icon, 45 | size = dpi(16), 46 | valign = 'center', 47 | icon = bind(wifi, 'icon-name'), 48 | } 49 | end 50 | 51 | local volume_icon = function() 52 | local wp = gearsify(Wp.get_default()) 53 | local speaker = gearsify(wp.audio.default_speaker) 54 | 55 | return { 56 | widget = widget.custom.icon, 57 | valign = 'center', 58 | size = dpi(16), 59 | icon = bind(speaker, 'volume-icon'), 60 | } 61 | end 62 | 63 | local icons = function() 64 | return { 65 | layout = wibox.layout.flex.horizontal, 66 | spacing = bful.bar_module_spacing * 2, 67 | wifi_icon(), 68 | volume_icon(), 69 | battery_icon(), 70 | } 71 | end 72 | 73 | return function(s) 74 | local taglist = set_taglist(s) 75 | local activeclient = set_activeclient(s) 76 | local layoutbox = set_layoutbox(s) 77 | local systray = add_systray() 78 | local clock = set_clock() 79 | local kbdlayout = add_kbdlayout() 80 | 81 | local left = { 82 | layout = wibox.layout.fixed.horizontal, 83 | spacing = bful.bar_module_spacing, 84 | { 85 | widget = widget.custom.icon, 86 | icon = bful.nixflake_icon, 87 | size = dpi(20), 88 | valign = 'center', 89 | }, 90 | separator(), 91 | activeclient, 92 | } 93 | 94 | local center = { 95 | layout = wibox.layout.fixed.horizontal, 96 | spacing = bful.bar_module_spacing, 97 | taglist, 98 | clock, 99 | kbdlayout, 100 | } 101 | 102 | local right = { 103 | layout = wibox.layout.fixed.horizontal, 104 | spacing = bful.bar_module_spacing, 105 | systray, 106 | separator(), 107 | icons(), 108 | separator(), 109 | layoutbox, 110 | } 111 | 112 | return Window.new { 113 | window = awful.wibar, 114 | screen = s, 115 | position = 'top', 116 | height = bful.bar_height, 117 | widget = Widget.new { 118 | widget = cter.margin, 119 | left = bful.bar_padding_horizontal, 120 | right = bful.bar_padding_horizontal, 121 | { 122 | layout = wibox.layout.align.horizontal, 123 | expand = 'none', 124 | { widget = cter.place, halign = 'left', left }, 125 | { widget = cter.place, halign = 'center', center }, 126 | { widget = cter.place, halign = 'right', right }, 127 | }, 128 | }, 129 | } 130 | end 131 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/kbdlayout.lua: -------------------------------------------------------------------------------- 1 | local utils = require('lua.utils') 2 | local kbdlayout = require('lua.variables').kbdlayout 3 | 4 | return function() 5 | return { 6 | widget = cter.background, 7 | bg = bful.bar_module_bg, 8 | shape = utils.rrect(bful.bar_module_roundness), 9 | forced_height = bful.bar_module_height, 10 | { 11 | widget = cter.margin, 12 | left = bful.bar_module_hpadding, 13 | right = bful.bar_module_hpadding, 14 | { 15 | widget = widget.textbox, 16 | font = bful.font .. ' medium 13', 17 | text = bind(kbdlayout):as(function(value) 18 | local layout, variant = string.match(value, '(%w+)%(([%w-_]+)%)') 19 | 20 | if not layout then 21 | layout = string.match(value, '(%w+)') 22 | end 23 | 24 | -- return string.upper(layout) .. ' : ' .. string.upper(variant) 25 | return string.upper(layout) 26 | end), 27 | }, 28 | }, 29 | } 30 | end 31 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/layoutbox.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | return function(s) 4 | local fn = function() return awful.layout.getname(awful.layout.get(s)) end 5 | 6 | local selected_layout = Variable.new(fn()) 7 | :observe(capi.tag, 'property::selected', fn) 8 | :observe(capi.tag, 'property::layout', fn) 9 | :observe(capi.tag, 'property::screen', fn) 10 | 11 | return { 12 | widget = widget.custom.icon, 13 | icon = bind(selected_layout):as( 14 | function(value) return value and bful['layout_' .. value] end 15 | ), 16 | } 17 | end 18 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/systray.lua: -------------------------------------------------------------------------------- 1 | local Tray = require('lgi').require('AstalTray') 2 | local Varmap = require('lua.subclasses.varmap') 3 | local gearsify = require('lua.core.gearsify') 4 | local tray = gearsify(Tray.get_default()) 5 | 6 | local item = function(id) 7 | local tray_item = gearsify(tray:get_item(id)) 8 | 9 | return Widget.new { 10 | widget = widget.custom.icon, 11 | icon = tray_item.icon_name or bind(tray_item, 'gicon'), 12 | size = dpi(16), 13 | valign = 'center', 14 | on_destroy = function() tray_item:dispose() end, 15 | on_primary_click = function() 16 | local pos = capi.mouse.coords() 17 | 18 | tray_item:activate(pos.x, pos.y) 19 | end, 20 | on_secondary_click = function() 21 | local pos = capi.mouse.coords() 22 | 23 | tray_item:secondary_activate(pos.x, pos.y) 24 | end, 25 | } 26 | end 27 | 28 | return function() 29 | local items = Varmap.new {} 30 | 31 | return { 32 | layout = wibox.layout.fixed.horizontal, 33 | setup = function(self) 34 | self:hook(tray, 'item-added', function(_, id) items:set(id, item(id)) end) 35 | :hook(tray, 'item-removed', function(_, id) items:delete(id) end) 36 | end, 37 | bind(items), 38 | } 39 | end 40 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/taglist.lua: -------------------------------------------------------------------------------- 1 | local Timed = require('lua.subclasses.timed') 2 | local awful = require('awful') 3 | local item = require('lua.widgets.bar.taglist_item') 4 | local utils = require('lua.utils') 5 | 6 | return function(s) 7 | --- ToDo: Use require"lua.variables".clients instead 8 | 9 | local timed = Timed.new { duration = 300, intro = 300, outro = 0 } 10 | local vars = table.map(s.tags, function(t) 11 | return Variable.new(0) 12 | :observe(t, 'tagged', function() return #t:clients() end) 13 | :observe(t, 'untagged', function() return #t:clients() end) 14 | end) 15 | 16 | return { 17 | widget = cter.background, 18 | bg = bful.bar_module_bg, 19 | shape = utils.rrect(bful.bar_module_roundness), 20 | forced_height = bful.bar_module_height, 21 | on_destroy = function() 22 | table.iterate(vars, function(value) value:drop() end) 23 | end, 24 | on_scroll_up = function() awful.tag.viewprev(s) end, 25 | on_scroll_down = function() awful.tag.viewnext(s) end, 26 | { 27 | widget = wibox.layout.stack, 28 | { 29 | layout = wibox.layout.fixed.horizontal, 30 | table.map(s.tags, function(t) return item(t, vars) end), 31 | }, 32 | { 33 | widget = cter.margin, 34 | forced_width = #s.tags * bful.bar_module_height, 35 | forced_height = bful.bar_module_height, 36 | left = bind(timed, 'current'), 37 | right = bind(timed, 'current'):as( 38 | function(value) return bful.bar_module_height * (#s.tags - 1) - value end 39 | ), 40 | setup = function(self) 41 | self:hook(capi.tag, 'property::selected', function() 42 | if s.selected_tag then 43 | timed.target = (s.selected_tag.index - 1) * bful.bar_module_height 44 | end 45 | end) 46 | end, 47 | { 48 | widget = cter.background, 49 | bg = bful.bar_taglist_bubble, 50 | shape = utils.rrect(bful.bar_module_height), 51 | forced_width = bful.bar_module_height, 52 | forced_height = bful.bar_module_height, 53 | }, 54 | }, 55 | }, 56 | } 57 | end 58 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/bar/taglist_item.lua: -------------------------------------------------------------------------------- 1 | local gears = require('gears') 2 | local utils = require('lua.utils') 3 | 4 | ---@param vars GVariable[] 5 | return function(t, vars) 6 | local curr, prev, next = vars[t.index], vars[t.index - 1], vars[t.index + 1] 7 | 8 | local dummy = { 9 | get = function() return 0 end, 10 | subscribe = function() 11 | return function() end 12 | end, 13 | } 14 | 15 | local shape = bind.merge({ 16 | prev and bind(prev) or dummy, 17 | next and bind(next) or dummy, 18 | }, function(pprev, nnext) 19 | local rl, rr = pprev == 0, nnext == 0 20 | 21 | return utils.prrect(bful.bar_module_height, rl, rr, rr, rl) 22 | end) 23 | 24 | return { 25 | widget = cter.background, 26 | forced_width = bful.bar_module_height, 27 | forced_height = bful.bar_module_height, 28 | on_primary_click = function() t:view_only() end, 29 | shape = bind(shape), 30 | bg = bind(curr):as( 31 | function(value) 32 | return value > 0 and bful.bar_taglist_tag_bg_occupied 33 | or bful.bar_taglist_tag_bg_empty 34 | end 35 | ), 36 | { 37 | widget = widget.base.make_widget, 38 | color = bind(curr):as( 39 | function(value) 40 | return value > 0 and bful.bar_taglist_tag_fg_occupied 41 | or bful.bar_taglist_tag_fg_empty 42 | end 43 | ), 44 | set_color = function(self, new_color) self._private.color = new_color end, 45 | get_color = function(self) return self._private.color end, 46 | fit = function() return bful.bar_module_height, bful.bar_module_height end, 47 | draw = function(self, _, cr, width, height) 48 | local radius = (bful.bar_module_height / (bful.bar_module_vpadding / 2) - 4) / 2 49 | 50 | cr:set_source_rgba(gears.color.parse_color(self.color)) 51 | cr:set_line_width(dpi(5)) 52 | cr:arc(width / 2, height / 2, radius, 0, 2 * math.pi) 53 | cr:stroke() 54 | end, 55 | }, 56 | } 57 | end 58 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/controlcenter/init.lua: -------------------------------------------------------------------------------- 1 | return function(s) end 2 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/custom/icon.lua: -------------------------------------------------------------------------------- 1 | local Color = require('lua.subclasses.color') 2 | local base = require('wibox.widget.base') 3 | local gtable = require('gears.table') 4 | local utils = require('lua.utils') 5 | local Gdk = lgi.require('Gdk') 6 | local Rsvg = lgi.require('Rsvg') 7 | local GdkPixbuf = lgi.require('GdkPixbuf') 8 | 9 | local gtk = require('beautiful.gtk') 10 | local vars = gtk.get_theme_variables() or {} 11 | 12 | local icon = { mt = {} } 13 | 14 | icon.success_color = vars.success_color or 'green' 15 | icon.error_color = vars.error_color or 'red' 16 | icon.warning_color = vars.warning_color or 'yellow' 17 | 18 | function icon:set_icon(image) 19 | if type(image) == 'string' then 20 | if string.match(image, '%-symbolic$') then 21 | local path = utils.lookup_icon(image) 22 | 23 | if not path then 24 | return 25 | end 26 | 27 | image = Rsvg.Handle.new_from_file(path) 28 | elseif io.file_exists(image) then 29 | else 30 | image = utils.lookup_icon(image) 31 | end 32 | elseif GdkPixbuf.Pixbuf:is_type_of(image) then 33 | image = Gdk.cairo_surface_create_from_pixbuf(image, 1) 34 | elseif Gio.Icon:is_type_of(image) then 35 | image = image:to_string() 36 | end 37 | 38 | self:set_image(image) 39 | 40 | self:set_color(self.color) 41 | end 42 | 43 | function icon:set_size(size) 44 | self.forced_width = size 45 | self.forced_height = size 46 | end 47 | 48 | function icon:set_color(color) 49 | self._private.color = Color.parse(color) 50 | 51 | if self._private.original_image and Rsvg.Handle:is_type_of(self._private.original_image) then 52 | self._private.original_image:set_stylesheet( 53 | string.format( 54 | '* { fill: %s; } .success { fill: %s; } .error { fill: %s; } .warning { fill: %s; }', 55 | self.color, 56 | self.success_color, 57 | self.error_color, 58 | self.warning_color 59 | ) 60 | ) 61 | self:emit_signal('widget::redraw_needed') 62 | self:emit_signal('property::color') 63 | end 64 | end 65 | 66 | function icon:get_color() return self._private.color.hex end 67 | 68 | local function new(img, color, resize_allowed, clip_shape, ...) 69 | local ret = base.make_widget(nil, nil, { enable_properties = true }) 70 | 71 | gtable.crush(ret, wibox.widget.imagebox, true) 72 | gtable.crush(ret, icon, true) 73 | 74 | ret._private.resize = true 75 | 76 | if color then 77 | ret:set_color(color) 78 | else 79 | ret:set_color('#fff') 80 | end 81 | 82 | if img then 83 | ret:set_icon(img) 84 | end 85 | 86 | if resize_allowed ~= nil then 87 | ret.resize = resize_allowed 88 | end 89 | 90 | ret._private.clip_shape = clip_shape 91 | ret._private.clip_args = { ... } 92 | 93 | return ret 94 | end 95 | 96 | function icon.mt:__call(...) return new(...) end 97 | 98 | return setmetatable(icon, icon.mt) 99 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/custom/init.lua: -------------------------------------------------------------------------------- 1 | return { 2 | revealer = require(... .. '.revealer'), 3 | icon = require(... .. '.icon'), 4 | } 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/custom/revealer.lua: -------------------------------------------------------------------------------- 1 | local base = require('wibox.widget.base') 2 | local gtable = require('gears.table') 3 | 4 | local revealer = { mt = {} } 5 | 6 | revealer.set_widget = base.set_widget_common 7 | 8 | function revealer:get_widget() return self._private.widget end 9 | 10 | function revealer:get_children() return { self._private.widget } end 11 | 12 | function revealer:set_children(children) self:set_widget(children[1]) end 13 | 14 | function revealer:set_reveal_child(reveal) 15 | self._private.reveal_child = reveal 16 | self:animate_transition() 17 | end 18 | 19 | function revealer:get_reveal_child() return self._private.reveal_child end 20 | 21 | function revealer:set_transition_duration(duration) self._private.transition_duration = duration end 22 | function revealer:get_transition_duration() return self._private.transition_duration end 23 | 24 | function revealer:set_transition_type(value) 25 | if value ~= 'slide-vertical' and value ~= 'slide-horizontal' and value ~= 'crossfade' then 26 | return 27 | end 28 | 29 | self._private.transition_type = value 30 | self:emit_signal('widget::layout_changed') 31 | self:emit_signal('property::transition_type', value) 32 | end 33 | function revealer:get_transition_type() return self._private.transition_type end 34 | 35 | function revealer:animate_transition() 36 | if not self._private.widget then 37 | return 38 | end 39 | 40 | local target, fn 41 | 42 | local STEPS = require('lua.user').fps or 60 43 | 44 | if self.transition_type == 'crossfade' then 45 | target = self.reveal_child and 1 or 0 46 | local step_size = (target - self.opacity) / STEPS 47 | 48 | fn = function(step) 49 | self.opacity = self.opacity + step_size 50 | if step == STEPS then 51 | self.opacity = target 52 | end 53 | end 54 | elseif self.transition_type == 'slide-horizontal' then 55 | self._private.real_width = self._private.real_width 56 | or self._private.widget:fit(nil, 9999, 9999) 57 | if not self._private.reveal_child then 58 | self.forced_width = self._private.real_width 59 | else 60 | self.forced_width = 0 61 | end 62 | target = self.reveal_child and self._private.real_width or 0 63 | local step_size = (target - self.forced_width) / STEPS 64 | 65 | fn = function(step) 66 | self.forced_width = self.forced_width + step_size 67 | if step == STEPS then 68 | self.forced_width = target 69 | end 70 | end 71 | elseif self.transition_type == 'slide-vertical' then 72 | self._private.real_height = self._private.real_height 73 | or self._private.widget:fit(nil, 9999, 9999) 74 | if not self._private.reveal_child then 75 | self.forced_height = self._private.real_height 76 | else 77 | self.forced_height = 0 78 | end 79 | target = self.reveal_child and self._private.real_height or 0 80 | local step_size = (target - self.forced_height) / STEPS 81 | 82 | fn = function(step) 83 | self.forced_height = self.forced_height + step_size 84 | if step == STEPS then 85 | self.forced_height = target 86 | end 87 | end 88 | end 89 | 90 | local i = 0 91 | 92 | GLib.timeout_add(GLib.PRIORITY_DEFAULT, self.transition_duration * i, function() 93 | i = i + 1 94 | fn(i) 95 | return i > STEPS 96 | end) 97 | end 98 | 99 | function revealer:fit(cr, width, height) 100 | if self._private.widget then 101 | base.fit_widget(self, cr, self._private.widget, width, height) 102 | end 103 | 104 | return self._private.real_width, self._private.real_height 105 | end 106 | 107 | function revealer:layout(_, width, height) 108 | if self._private.widget then 109 | return { 110 | base.place_widget_at(self._private.widget, 0, 0, width, height), 111 | } 112 | end 113 | end 114 | 115 | local function new(widget, transition_type, transition_duration) 116 | local ret = base.make_widget(nil, nil, { enable_properties = true }) 117 | 118 | gtable.crush(ret, revealer, true) 119 | 120 | ret._private.real_width = 0 121 | ret._private.real_height = 0 122 | ret:set_transition_type(transition_type or 'crossfade') 123 | ret:set_transition_duration(transition_duration or 1) 124 | 125 | if widget then 126 | ret:set_widget(widget) 127 | end 128 | 129 | return ret 130 | end 131 | 132 | function revealer.mt:__call(...) return new(...) end 133 | 134 | return setmetatable(revealer, revealer.mt) 135 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/dock/init.lua: -------------------------------------------------------------------------------- 1 | local Timed = require('lua.subclasses.timed') 2 | local awful = require('awful') 3 | local launcher = require(... .. '.launcher') 4 | local pinned = require(... .. '.pinned') 5 | local tasklist = require(... .. '.tasklist') 6 | local utils = require('lua.utils') 7 | 8 | local is_overlapping = function(c, dock) 9 | local c_x = c.x 10 | local c_y = c.y 11 | local c_w = c.width 12 | local c_h = c.height 13 | 14 | return not ( 15 | c_x + c_w <= dock.x 16 | or c_x >= dock.x + dock.width 17 | or c_y + c_h <= dock.y 18 | or c_y >= dock.y + dock.height 19 | ) 20 | end 21 | 22 | return function(s) 23 | local bottom_gap = bful.useless_gap * 2 24 | local detection_area = { height = bottom_gap + bful.dock_height } 25 | 26 | detection_area.y = s.geometry.height - detection_area.height 27 | 28 | local posY = Timed.new { 29 | intro = 0, 30 | outro = 300, 31 | duration = 300, 32 | initial = detection_area.y, 33 | easing = require('lib.rubato').quadratic, 34 | } 35 | 36 | local should_hide = function() 37 | if not s.selected_tag then 38 | return 39 | end 40 | 41 | local clients = s.selected_tag:clients() 42 | 43 | return table.any( 44 | clients, 45 | function(c) 46 | return (c:isvisible() and not c.minimized) and is_overlapping(c, detection_area) 47 | end 48 | ) 49 | end 50 | 51 | local hide = function() posY.target = s.geometry.height - bottom_gap end 52 | local show = function() posY.target = detection_area.y end 53 | 54 | local update = function() 55 | if should_hide() then 56 | return hide() 57 | end 58 | 59 | return show() 60 | end 61 | 62 | table.iterate({ 63 | 'manage', 64 | 'unmanage', 65 | 'tagged', 66 | 'untagged', 67 | 'property::geometry', 68 | 'property::fullscreen', 69 | 'property::floating', 70 | 'property::minimized', 71 | }, function(value) capi.client.connect_signal(value, update) end) 72 | 73 | capi.tag.connect_signal('property::selected', update) 74 | 75 | return Window.new { 76 | window = awful.popup, 77 | screen = s, 78 | type = 'dock', 79 | ontop = true, 80 | maximum_height = bful.dock_height, 81 | minimum_height = bful.dock_height, 82 | bg = 'transparent', 83 | y = bind(posY, 'current'), 84 | placement = function(self) 85 | awful.placement.center_horizontal(self, { honor_workarea = true }) 86 | detection_area.width = self.width 87 | detection_area.x = self.x 88 | end, 89 | widget = Widget.new { 90 | widget = cter.background, 91 | bg = bful.dock_bg, 92 | shape = utils.rrect(bful.dock_roundness), 93 | on_hover = show, 94 | on_hover_lost = update, 95 | { 96 | widget = cter.margin, 97 | margins = bful.dock_padding, 98 | { 99 | layout = wibox.layout.fixed.horizontal, 100 | spacing = bful.dock_spacing, 101 | setup = function(self) 102 | self.launcher = launcher() 103 | self.pinned = pinned(s) 104 | self.tasklist = tasklist(s) 105 | self.separator = Widget.new { 106 | widget = cter.place, 107 | forced_width = bful.dock_separator_width, 108 | forced_height = bful.dock_separator_height, 109 | { 110 | widget = cter.background, 111 | bg = bful.dock_separator_bg, 112 | forced_width = bful.dock_separator_width, 113 | forced_height = bful.dock_separator_height, 114 | shape = utils.rrect(bful.dock_separator_roundness), 115 | visible = bind(self.tasklist, 'visible'), 116 | }, 117 | } 118 | self.children = { 119 | self.launcher, 120 | self.pinned, 121 | self.separator, 122 | self.tasklist, 123 | } 124 | end, 125 | }, 126 | }, 127 | }, 128 | } 129 | end 130 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/dock/launcher.lua: -------------------------------------------------------------------------------- 1 | local utils = require('lua.utils') 2 | 3 | local launcher = require('lua.widgets.launcher')() 4 | 5 | return function() 6 | return Widget.new { 7 | widget = cter.background, 8 | shape = utils.rrect(bful.dock_tasklist_item_roundness), 9 | bg = bind(launcher.wibox, 'visible'):as( 10 | function(is_visible) 11 | return is_visible and bful.dock_tasklist_item_color_active 12 | or bful.dock_tasklist_item_color_normal 13 | end 14 | ), 15 | { 16 | layout = wibox.layout.stack, 17 | { 18 | widget = cter.margin, 19 | margins = bful.dock_tasklist_item_padding, 20 | { 21 | widget = widget.custom.icon, 22 | icon = 'view-app-grid-symbolic', 23 | }, 24 | }, 25 | }, 26 | } 27 | end 28 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/dock/pinned.lua: -------------------------------------------------------------------------------- 1 | local Varmap = require('lua.subclasses.varmap') 2 | local tasklist_item = require('lua.widgets.dock.tasklist_item') 3 | local pinned = require('lua.user').dock.pinned_apps 4 | 5 | local apps = require('lua.services.applications').get_default() 6 | 7 | local pinned_apps = table.filter(apps.list, function(value) 8 | return table.any(pinned, function(v) return value.entry == v end) 9 | end) 10 | 11 | local add_aliases = function(map, obj, keys) 12 | for _, key in ipairs(keys) do 13 | if key then 14 | map[key] = obj 15 | end 16 | end 17 | end 18 | 19 | return function(s) 20 | local tbl = {} 21 | local copy = {} 22 | 23 | for _, value in ipairs(pinned_apps) do 24 | local class = string.gsub(value.entry, '%.desktop$', '') 25 | local item = tasklist_item(class) 26 | 27 | tbl[class] = item 28 | 29 | add_aliases(copy, item, { 30 | class, 31 | value.wm_class, 32 | value.name, 33 | }) 34 | end 35 | 36 | return Widget.new { 37 | layout = wibox.layout.fixed.horizontal, 38 | spacing = bful.dock_spacing, 39 | setup = function(self) 40 | self:hook(capi.client, 'manage', function(_, c) 41 | if c.screen ~= s or c.skip_taskbar then 42 | return 43 | end 44 | 45 | local app_id = c:get_xproperty('_GTK_APPLICATION_ID') 46 | local is_gtk = app_id and #app_id > 1 47 | 48 | local item = copy[c.class] or (is_gtk and tbl[app_id]) 49 | 50 | if not item then 51 | return 52 | end 53 | 54 | item:add_dot(c) 55 | end):hook(capi.client, 'unmanage', function(_, c) 56 | local app_id = c:get_xproperty('_GTK_APPLICATION_ID') 57 | local is_gtk = app_id and #app_id > 1 58 | 59 | local item = copy[c.class] or (is_gtk and copy[app_id]) 60 | 61 | if not item then 62 | return 63 | end 64 | 65 | item:del_dot(c) 66 | end) 67 | end, 68 | table.values(tbl), 69 | } 70 | end 71 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/dock/tasklist.lua: -------------------------------------------------------------------------------- 1 | local Varmap = require('lua.subclasses.varmap') 2 | local pinned = require('lua.user').dock.pinned_apps 3 | local tasklist_item = require('lua.widgets.dock.tasklist_item') 4 | 5 | return function(s) 6 | local clients = Varmap.new {} 7 | 8 | return Widget.new { 9 | layout = wibox.layout.fixed.horizontal, 10 | spacing = bful.dock_spacing, 11 | visible = bind(clients):as(function(value) return #value > 0 end), 12 | setup = function(self) 13 | self 14 | :hook(capi.client, 'manage', function(_, c) 15 | if c.screen ~= s or c.skip_taskbar then 16 | return 17 | end 18 | 19 | local app_id = c:get_xproperty('_GTK_APPLICATION_ID') 20 | local is_gtk = app_id and #app_id > 1 21 | 22 | local is_pinned = table.find( 23 | pinned, 24 | function(value) 25 | return c.class 26 | and ( 27 | (value:find(c.class, nil, true) ~= nil) 28 | or (is_gtk and value:find(app_id, nil, true) ~= nil) 29 | ) 30 | end 31 | ) 32 | 33 | if is_pinned then 34 | return 35 | end 36 | 37 | local item = clients:get(c.class) 38 | 39 | if not item then 40 | item = tasklist_item(c.class, is_gtk and app_id) 41 | item:add_dot(c) 42 | return clients:set(c.class, item) 43 | end 44 | 45 | item:add_dot(c) 46 | end) 47 | :hook(capi.client, 'unmanage', function(_, c) 48 | local item = clients:get(c.class) 49 | 50 | if not item then 51 | return 52 | end 53 | 54 | item:del_dot(c) 55 | 56 | if item.n_dots == 0 then 57 | clients:delete(c.class) 58 | end 59 | end) 60 | end, 61 | bind(clients), 62 | } 63 | end 64 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/dock/tasklist_item.lua: -------------------------------------------------------------------------------- 1 | local Varmap = require('lua.subclasses.varmap') 2 | local utils = require('lua.utils') 3 | 4 | local dot = function(c) 5 | return Widget.new { 6 | widget = cter.background, 7 | no_implicity_destroy = true, 8 | shape = utils.rrect(bful.dock_tasklist_dot_size), 9 | forced_height = bful.dock_tasklist_dot_size, 10 | forced_width = bind(c, 'active'):as( 11 | function(active) return bful.dock_tasklist_dot_size * (active and 3 or 1) end 12 | ), 13 | bg = bind(c, 'active'):as( 14 | function(active) 15 | return active and bful.dock_tasklist_dot_color_active 16 | or bful.dock_tasklist_dot_color_normal 17 | end 18 | ), 19 | } 20 | end 21 | 22 | ---@param class string 23 | return function(class, gtk_id) 24 | local dots = Varmap.new {} 25 | local active = Variable.new(false):observe(capi.client, 'property::active', function() 26 | return table.any(dots:keys(), function(value) return value.active end) 27 | end) 28 | 29 | return Widget.new { 30 | widget = cter.background, 31 | shape = utils.rrect(bful.dock_tasklist_item_roundness), 32 | bg = bind(active):as( 33 | function(is_active) 34 | return is_active and bful.dock_tasklist_item_color_active 35 | or bful.dock_tasklist_item_color_normal 36 | end 37 | ), 38 | get_n_dots = function() return #dots:values() end, 39 | add_dot = function(_, c) dots:set(c, dot(c)) end, 40 | del_dot = function(_, c) dots:delete(c) end, 41 | on_destroy = function() 42 | active:drop() 43 | dots:drop() 44 | end, 45 | { 46 | layout = wibox.layout.stack, 47 | { 48 | widget = cter.margin, 49 | margins = bful.dock_tasklist_item_padding, 50 | { 51 | widget = widget.custom.icon, 52 | icon = gtk_id or class or 'application-x-executable', 53 | }, 54 | }, 55 | { 56 | widget = cter.place, 57 | valign = 'bottom', 58 | { 59 | layout = wibox.layout.fixed.horizontal, 60 | spacing = bful.dock_tasklist_dot_size, 61 | bind(dots):as( 62 | function(value) return table.slice(value, 1, bful.dock_tasklist_dot_limit) end 63 | ), 64 | }, 65 | }, 66 | }, 67 | } 68 | end 69 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/launcher/apps.lua: -------------------------------------------------------------------------------- 1 | local apps = require('lua.services.applications').get_default() 2 | local item = require('lua.widgets.launcher.launcher_item') 3 | local user = require('lua.user') 4 | 5 | ---@param var GVariable 6 | return function(var) 7 | local module = { limit = 1 } 8 | 9 | local childrens = Variable.new {} 10 | 11 | module.filter = function(query) 12 | if not query or string.sub(query, 1, 1) == ':' then 13 | return module.widget:set_visible(false) 14 | end 15 | 16 | module.widget:set_visible(true) 17 | 18 | local filtered = table.map( 19 | table.slice(apps:query(query), 1, user.launcher.apps_limit), 20 | function(value, index) 21 | return item { 22 | index = index, 23 | variable = var, 24 | name = value.name, 25 | icon_name = value.icon_name, 26 | launch = function() 27 | value:launch() 28 | io.exec(string.format('notify-send "Launched %s"', value.name)) 29 | end, 30 | } 31 | end 32 | ) 33 | 34 | module.limit = #filtered 35 | 36 | childrens:set(filtered) 37 | end 38 | 39 | module.launch = function() 40 | for index, value in ipairs(childrens:get()) do 41 | if index == var:get() then 42 | return value.launch() 43 | end 44 | end 45 | end 46 | 47 | module.widget = Widget.new { 48 | widget = cter.background, 49 | bg = bful.launcher_bg, 50 | { 51 | layout = wibox.layout.fixed.vertical, 52 | bind(childrens), 53 | }, 54 | } 55 | return module 56 | end 57 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/launcher/clients.lua: -------------------------------------------------------------------------------- 1 | local item = require('lua.widgets.launcher.launcher_item') 2 | local utils = require('lua.utils') 3 | 4 | ---@param var GVariable 5 | return function(var) 6 | local module = { 7 | limit = 1, 8 | prefix = ':c', 9 | icon = 'multitasking-windows-symbolic', 10 | desc = 'All clients', 11 | } 12 | 13 | local childrens = Variable.new {} 14 | 15 | module.filter = function(query) 16 | if not query then 17 | return module.widget:set_visible(false) 18 | end 19 | 20 | module.widget:set_visible(true) 21 | 22 | local filtered = table.filter(capi.mouse.screen.all_clients, function(c) 23 | local keywords = table.concat({ c.name, c.class }, ' ') 24 | 25 | return string.find(string.lower(keywords), query) ~= nil 26 | end) 27 | 28 | filtered = table.map(filtered, function(value, index) 29 | return item { 30 | index = index, 31 | variable = var, 32 | name = value.class, 33 | description = value.title, 34 | icon_name = value.class, 35 | launch = function() 36 | value:activate { 37 | switch_to_tag = true, 38 | raise = true, 39 | } 40 | end, 41 | } 42 | end) 43 | 44 | module.limit = #filtered 45 | 46 | childrens:set(filtered) 47 | end 48 | 49 | module.launch = function() 50 | for index, value in ipairs(childrens:get()) do 51 | if index == var:get() then 52 | return value:launch() 53 | end 54 | end 55 | end 56 | 57 | module.widget = Widget.new { 58 | widget = cter.background, 59 | bg = bful.launcher_bg, 60 | shape = utils.prrect(bful.launcher_roundness, false, false, true, true), 61 | { 62 | layout = wibox.layout.fixed.vertical, 63 | bind(childrens), 64 | }, 65 | } 66 | 67 | return module 68 | end 69 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/launcher/launcher_item.lua: -------------------------------------------------------------------------------- 1 | local utils = require('lua.utils') 2 | 3 | ---@param tbl { index: number, variable: GVariable, name: string, description?: string, icon_name: string, launch: function} 4 | ---@return { launch: function } 5 | return function(tbl) 6 | local is_symbolic = string.match(tbl.icon_name, '%-symbolic$') ~= nil 7 | 8 | return Widget.new { 9 | widget = cter.background, 10 | launch = tbl.launch, 11 | forced_height = bful.launcher_item_entry_height, 12 | bg = bind(tbl.variable):as( 13 | function(v) return v == tbl.index and bful.launcher_item_entry_bg_focus or 'transparent' end 14 | ), 15 | { 16 | widget = cter.margin, 17 | left = is_symbolic and 15 or 10, 18 | right = is_symbolic and 15 or 10, 19 | top = 5, 20 | bottom = 5, 21 | { 22 | layout = wibox.layout.fixed.horizontal, 23 | spacing = dpi(10), 24 | { 25 | widget = widget.custom.icon, 26 | icon = tbl.icon_name, 27 | halign = 'center', 28 | valign = 'center', 29 | size = is_symbolic and dpi(16) or dpi(32), 30 | }, 31 | { 32 | widget = widget.textbox, 33 | text = tbl.name, 34 | font = bful.font .. ' medium 12', 35 | forced_height = dpi(20), 36 | }, 37 | tbl.description 38 | and { 39 | widget = widget.textbox, 40 | markup = utils.colorize(tbl.description, require('lua.user').colors.base03), 41 | forced_height = dpi(20), 42 | }, 43 | }, 44 | }, 45 | } 46 | end 47 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/launcher/powermenu.lua: -------------------------------------------------------------------------------- 1 | local item = require('lua.widgets.launcher.launcher_item') 2 | local userprompt = require('lua.services.userprompt').get_default() 3 | local utils = require('lua.utils') 4 | 5 | local confirm = function(title, subtitle, callback, ...) 6 | local args = { ... } 7 | 8 | return userprompt:confirm_dialog(title, subtitle, function(ok, cancel) 9 | if ok then 10 | callback(table.unpack(args)) 11 | end 12 | end) 13 | end 14 | 15 | local choices = { 16 | { 17 | 'Shutdown', 18 | 'system-shutdown-symbolic', 19 | function() confirm('Power Off', 'The system will power off', io.exec, 'shutdown now') end, 20 | }, 21 | { 22 | 'Reboot', 23 | 'system-reboot-symbolic', 24 | function() confirm('Reboot', 'The system will reboot', io.exec, 'systemctl reboot') end, 25 | }, 26 | { 27 | 'Log out', 28 | 'system-log-out-symbolic', 29 | function() 30 | confirm('Log out', 'Exit awesome', function() capi.awesome.quit() end) 31 | end, 32 | }, 33 | { 34 | 'Reload', 35 | 'arrow-circular-top-left-symbolic', 36 | function() capi.awesome.restart() end, 37 | }, 38 | } 39 | 40 | ---@param var GVariable 41 | return function(var) 42 | local module = { 43 | limit = 1, 44 | prefix = ':p', 45 | icon = 'system-shutdown-symbolic', 46 | desc = 'Shutdown and sub-options', 47 | } 48 | 49 | local childrens = Variable.new {} 50 | 51 | module.filter = function(query) 52 | if not query then 53 | return module.widget:set_visible(false) 54 | end 55 | 56 | module.widget:set_visible(true) 57 | 58 | local filtered = table.map( 59 | table.filter( 60 | choices, 61 | function(value) return string.find(string.lower(value[1]), query) ~= nil end 62 | ), 63 | function(value, index) 64 | return item { 65 | index = index, 66 | variable = var, 67 | name = value[1], 68 | icon_name = value[2], 69 | launch = value[3], 70 | } 71 | end 72 | ) 73 | 74 | module.limit = #filtered 75 | 76 | childrens:set(filtered) 77 | end 78 | 79 | module.launch = function() 80 | for index, value in ipairs(childrens:get()) do 81 | if index == var:get() then 82 | return value:launch() 83 | end 84 | end 85 | end 86 | 87 | module.widget = Widget.new { 88 | widget = cter.background, 89 | bg = bful.launcher_bg, 90 | shape = utils.prrect(bful.launcher_roundness, false, false, true, true), 91 | { 92 | layout = wibox.layout.fixed.vertical, 93 | bind(childrens), 94 | }, 95 | } 96 | 97 | return module 98 | end 99 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/menu.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local user = require('lua.user') 3 | 4 | return awful.menu { 5 | items = { 6 | { 7 | 'Awesome', 8 | { 9 | { 10 | 'Hotkeys', 11 | function() require('awful.hotkeys_popup').show_help(nil, capi.mouse.screen) end, 12 | }, 13 | { 14 | 'Manual', 15 | string.format('%s -e man awesome', user.terminal), 16 | }, 17 | { 18 | 'Edit config', 19 | string.format('%s %s', user.editor, capi.awesome.conffile), 20 | }, 21 | { 'Restart', capi.awesome.restart }, 22 | { 23 | 'Quit', 24 | capi.awesome.quit, 25 | }, 26 | }, 27 | bful.awesome_icon, 28 | }, 29 | { 'Open terminal', user.terminal }, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/notifications/init.lua: -------------------------------------------------------------------------------- 1 | local Varmap = require('lua.subclasses.varmap') 2 | local Notifd = lgi.require('AstalNotifd') 3 | local awful = require('awful') 4 | local gearsify = require('lua.core.gearsify') 5 | local gtimer = require('gears.timer') 6 | local popup = require(... .. '.notifpopup') 7 | 8 | local TIMEOUT = require('lua.user').notifications.timeout 9 | 10 | local notifd = gearsify(Notifd.get_default()) 11 | 12 | local notif_varmap = Varmap.new {} 13 | 14 | notifd:connect_signal('notified', function(_, id) 15 | local n = gearsify(notifd:get_notification(id)) 16 | 17 | notif_varmap:set(id, popup(n)) 18 | 19 | if TIMEOUT > 0 then 20 | gtimer.new { 21 | timeout = TIMEOUT / 1000, 22 | autostart = true, 23 | single_shot = true, 24 | callback = function() notif_varmap:delete(id) end, 25 | } 26 | end 27 | end) 28 | 29 | notifd:connect_signal('resolved', function(_, id) notif_varmap:delete(id) end) 30 | 31 | local padding = bful.bar_height + bful.useless_gap * 2 32 | 33 | return function(s) 34 | return Window.new { 35 | window = awful.popup, 36 | screen = s, 37 | type = 'notification', 38 | placement = function(self) awful.placement.top(self, { margins = { top = padding } }) end, 39 | visible = true, 40 | ontop = true, 41 | maximum_width = dpi(400), 42 | minimum_width = dpi(400), 43 | bg = 'transparent', 44 | widget = Widget.new { 45 | layout = wibox.layout.fixed.vertical, 46 | spacing = bful.notification_spacing, 47 | bind(notif_varmap), 48 | }, 49 | } 50 | end 51 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/notifications/notifpopup.lua: -------------------------------------------------------------------------------- 1 | local utils = require('lua.utils') 2 | 3 | return function(n) 4 | local icon = { 5 | widget = widget.custom.icon, 6 | icon = bind(n, 'image'), 7 | clip_shape = utils.rrect(bful.notification_icon_roundness), 8 | } 9 | 10 | local summary = { 11 | widget = widget.textbox, 12 | text = bind(n, 'summary'), 13 | } 14 | 15 | local body = { 16 | widget = widget.textbox, 17 | text = bind(n, 'body'), 18 | } 19 | 20 | return Widget.new { 21 | widget = cter.background, 22 | bg = bful.notification_bg, 23 | shape = utils.rrect(bful.notification_roundness), 24 | { 25 | layout = wibox.layout.fixed.vertical, 26 | spacing = dpi(10), 27 | { 28 | widget = cter.margin, 29 | margins = bful.notification_margins, 30 | { 31 | layout = wibox.layout.fixed.horizontal, 32 | { 33 | widget = cter.constraint, 34 | width = bful.notification_icon_size, 35 | height = bful.notification_icon_size, 36 | icon, 37 | }, 38 | { 39 | layout = wibox.layout.fixed.vertical, 40 | summary, 41 | body, 42 | }, 43 | }, 44 | }, 45 | { 46 | widget = cter.margin, 47 | margins = bful.notification_action_margins, 48 | }, 49 | }, 50 | } 51 | end 52 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/overview/init.lua: -------------------------------------------------------------------------------- 1 | local Timed = require('lua.subclasses.timed') 2 | local awful = require('awful') 3 | local item = require('lua.widgets.overview.overview_item') 4 | local rubato = require('lib.rubato') 5 | local utils = require('lua.utils') 6 | 7 | return function(s) 8 | local hidden = -dpi(350) 9 | local show = dpi(10) 10 | 11 | local posX = Timed.new { intro = 0, outro = 300, duration = 300, initial = hidden } 12 | 13 | return Window.new { 14 | window = awful.popup, 15 | screen = s, 16 | type = 'dock', 17 | ontop = true, 18 | x = bind(posX, 'current'), 19 | bg = 'transparent', 20 | placement = function(self) awful.placement.center_vertical(self, { honor_workarea = true }) end, 21 | run = function() posX.target = posX.target == hidden and show or hidden end, 22 | widget = Widget.new { 23 | widget = cter.background, 24 | bg = bful.overview_bg, 25 | shape = utils.rrect(bful.overview_roundness), 26 | { 27 | widget = cter.margin, 28 | margins = bful.overview_padding, 29 | { 30 | layout = wibox.layout.grid, 31 | expand = true, 32 | orientation = 'vertical', 33 | spacing = dpi(5), 34 | table.map(s.tags, function(value) return item(value) end), 35 | }, 36 | }, 37 | }, 38 | } 39 | end 40 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/overview/overview_item.lua: -------------------------------------------------------------------------------- 1 | local Varmap = require('lua.subclasses.varmap') 2 | local awful = require('awful') 3 | local utils = require('lua.utils') 4 | 5 | local SCALE = bful.overview_scale 6 | 7 | local item = function(c) 8 | local label_visible = bind(c, 'geometry'):as( 9 | function() return math.min(c.width, c.height) * SCALE > 100 end 10 | ) 11 | 12 | return Widget.new { 13 | widget = cter.place, 14 | valign = 'top', 15 | halign = 'left', 16 | { 17 | widget = cter.margin, 18 | left = bind(c, 'geometry'):as(function() return (c.x * SCALE) end), 19 | top = bind(c, 'geometry'):as(function() return (c.y * SCALE) end), 20 | right = bind(c, 'geometry'):as(function() return -((c.x + c.width) * SCALE) end), 21 | bottom = bind(c, 'geometry'):as(function() return -((c.y + c.height) * SCALE) end), 22 | { 23 | widget = cter.background, 24 | bg = bful.overview_client_bg, 25 | border_width = bful.border_width / 2, 26 | border_color = bind(c, 'active'):as( 27 | function(active) 28 | return active and bful.border_color_active or bful.border_color_normal 29 | end 30 | ), 31 | on_click = function() 32 | c:activate { 33 | switch_to_tag = true, 34 | raise = true, 35 | } 36 | capi.mouse.screen.overview:run() 37 | end, 38 | shape = utils.rrect(bful.overview_client_roundness), 39 | { 40 | widget = cter.place, 41 | { 42 | layout = wibox.layout.fixed.vertical, 43 | spacing = label_visible:as( 44 | function(value) return value and dpi(10) or 0 end 45 | ), 46 | { 47 | widget = cter.place, 48 | { 49 | widget = awful.widget.clienticon, 50 | client = c, 51 | set_size = function(self, size) 52 | self.forced_width = size 53 | self.forced_height = size 54 | end, 55 | size = bind(c, 'geometry'):as( 56 | function() return math.min(c.width, c.height) * SCALE / 2.5 end 57 | ), 58 | }, 59 | }, 60 | { 61 | widget = widget.textbox, 62 | halign = 'center', 63 | text = bind(c, 'name'), 64 | font = bful.font .. ' medium 10', 65 | forced_width = bind(c, 'geometry'):as( 66 | function() return math.min(c.width, c.height) * SCALE end 67 | ), 68 | visible = label_visible, 69 | }, 70 | }, 71 | }, 72 | }, 73 | }, 74 | } 75 | end 76 | 77 | return function(t) 78 | local clients = Varmap.new {} 79 | 80 | return Widget.new { 81 | widget = cter.background, 82 | bg = bful.overview_tag_bg, 83 | shape = utils.rrect(bful.overview_tag_roundness), 84 | forced_width = t.screen.geometry.width * SCALE, 85 | forced_height = t.screen.geometry.height * SCALE, 86 | { 87 | layout = wibox.layout.fixed.horizontal, 88 | on_destroy = function() clients:drop() end, 89 | setup = function(self) 90 | self:hook(t, 'tagged', function(_, c) clients:set(c, item(c)) end) 91 | :hook(t, 'untagged', function(_, c) clients:delete(c) end) 92 | end, 93 | bind(clients), 94 | }, 95 | } 96 | end 97 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/titlebar.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | return function(c) 4 | if #c:get_xproperty('_GTK_APPLICATION_ID') > 0 or c.request_no_titlebar then 5 | return 6 | end 7 | 8 | local titlebar = awful.titlebar(c, { 9 | size = bful.titlebar_height, 10 | }) 11 | 12 | titlebar:setup { 13 | widget = cter.margin, 14 | left = bful.titlebar_hpadding, 15 | right = bful.titlebar_hpadding, 16 | top = bful.titlebar_vpadding, 17 | bottom = bful.titlebar_vpadding, 18 | Widget.new { 19 | layout = wibox.layout.align.horizontal, 20 | { 21 | widget = awful.titlebar.widget.iconwidget, 22 | client = c, 23 | }, 24 | { 25 | layout = wibox.layout.flex.horizontal, 26 | on_primary_click = function() 27 | if c.maximized then 28 | c.maximized = false 29 | end 30 | 31 | if not c.floating then 32 | c.floating = true 33 | end 34 | 35 | c:emit_signal('request::activate', 'titlebar', { raise = true }) 36 | awful.mouse.client.move(c) 37 | end, 38 | { 39 | widget = widget.textbox, 40 | halign = 'center', 41 | text = bind(c, 'name'), 42 | }, 43 | }, 44 | { 45 | layout = wibox.layout.fixed.horizontal, 46 | spacing = dpi(16), 47 | { 48 | widget = widget.custom.icon, 49 | size = dpi(16), 50 | icon = 'down-symbolic', 51 | -- on_click = function() c.minimized = not c.minimized end, 52 | on_click = function() c.maximized = not c.maximized end, 53 | }, 54 | -- { 55 | -- widget = widget.custom.icon, 56 | -- size = dpi(16), 57 | -- icon = bind(c, 'maximized') 58 | -- :as(function(value) return value and 'inward' or 'outward' end) 59 | -- :as( 60 | -- function(value) return ('arrows-pointing-%s-symbolic'):format(value) end 61 | -- ), 62 | -- on_click = function() c.maximized = not c.maximized end, 63 | -- }, 64 | -- { 65 | -- widget = widget.custom.icon, 66 | -- size = dpi(16), 67 | -- icon = 'cross-large-symbolic', 68 | -- on_click = function() c:kill() end, 69 | -- }, 70 | }, 71 | }, 72 | } 73 | 74 | return titlebar 75 | end 76 | -------------------------------------------------------------------------------- /dotfiles/awesome/lua/widgets/wallpaper.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local gsurface = require('gears.surface') 3 | local wallpaper = require('lua.services.wallpaper.init').get_default() 4 | 5 | return function(s) 6 | return Window.new { 7 | window = wibox, 8 | screen = s, 9 | type = 'desktop', 10 | visible = true, 11 | below = true, 12 | setup = function(self) awful.placement.maximize(self, { honor_workarea = true }) end, 13 | widget = Widget.new { 14 | image = bind(wallpaper, 'background'):as( 15 | function(value) return gsurface.load_uncached(value) end 16 | ), 17 | widget = widget.imagebox, 18 | halign = 'center', 19 | valign = 'center', 20 | horizontal_fit_policy = 'fill', 21 | -- vertical_fit_policy = 'none', 22 | }, 23 | } 24 | end 25 | -------------------------------------------------------------------------------- /dotfiles/awesome/rc.lua: -------------------------------------------------------------------------------- 1 | pcall(require, 'luarocks.loader') 2 | 3 | require('lua.globals') 4 | require('lua.functions') 5 | 6 | DEBUG = true 7 | 8 | capi.awesome.connect_signal( 9 | 'debug::error', 10 | function(message) 11 | require('naughty').notify { 12 | urgency = 'critical', 13 | app_name = 'Awesome', 14 | title = 'Epic, you fucked up', 15 | message = message, 16 | } 17 | end 18 | ) 19 | 20 | require('lua') 21 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/cornerne.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/cornernw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/cornerse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/cornersw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/dwindle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/fairh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/fairv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/floating.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/magnifier.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/max.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/spiral.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/tile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/tilebottom.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/tileleft.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/layouts/tiletop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/submenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyob0t/dotfiles/0572b66f791620d6d3cd0df9cc1b5f8f8a31907b/dotfiles/awesome/theme/icons/submenu.png -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/arrow-circular-top-left-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/arrows-pointing-inward-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/arrows-pointing-outward-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/cross-large-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/dot-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/down-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/memory-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/moon-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/multitasking-windows-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/process-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/icons/symbolic/system-search-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/init.lua: -------------------------------------------------------------------------------- 1 | local theme_assets = require('beautiful.theme_assets') 2 | local user = require('lua.user') 3 | local scheme = user.colors 4 | 5 | local theme = require('lua.utils').src() 6 | 7 | local function flatten_table(tbl, prefix, result) 8 | result = result or {} 9 | prefix = prefix or '' 10 | 11 | for key, value in pairs(tbl) do 12 | local k = prefix .. key 13 | 14 | if type(value) == 'table' then 15 | flatten_table(value, k .. '_', result) 16 | else 17 | result[k] = value 18 | end 19 | end 20 | 21 | return result 22 | end 23 | 24 | local module = {} 25 | 26 | module.font = 'Cantarell' 27 | module.font_size = dpi(10) 28 | module.icon_theme = user.icon_theme 29 | module.awesome_icon = theme_assets.awesome_icon(dpi(1024), scheme.base01, scheme.base09) 30 | module.nixflake_icon = theme .. 'icons/nixos-snowflake-colours.svg' 31 | 32 | module.bg_normal = scheme.base00 33 | module.bg_focus = scheme.base01 34 | module.bg_urgent = scheme.base08 35 | module.bg_minimize = scheme.base02 36 | module.bg_systray = module.bg_normal 37 | 38 | module.fg_normal = scheme.base05 39 | module.fg_focus = scheme.base07 40 | module.fg_urgent = scheme.base07 41 | module.fg_minimize = scheme.base07 42 | 43 | module.menu_submenu_icon = theme .. 'icons/submenu.png' 44 | module.menu_height = dpi(20) 45 | module.menu_width = dpi(100) 46 | 47 | table.iterate(require('theme.style'), function(value, index, tbl) 48 | for k, v in pairs(flatten_table(value)) do 49 | module[k] = v 50 | end 51 | end) 52 | 53 | return module 54 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/bar.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | local transparentize = require('theme.themeutils').transparentize 3 | 4 | return { 5 | bar = { 6 | bg = scheme.base00, 7 | height = dpi(43), 8 | padding = { 9 | horizontal = dpi(10), 10 | vertical = dpi(3), 11 | }, 12 | module = { 13 | bg = scheme.base01, 14 | roundness = dpi(35), 15 | height = dpi(35), 16 | spacing = dpi(5), 17 | hpadding = dpi(10), 18 | vpadding = dpi(5), 19 | }, 20 | taglist = { 21 | bubble = transparentize(scheme.base09, 0.3), 22 | tag = { 23 | bg_occupied = scheme.base02, 24 | bg_empty = 'transparent', 25 | fg_occupied = scheme.base09, 26 | fg_empty = scheme.base03, 27 | }, 28 | }, 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/client.lua: -------------------------------------------------------------------------------- 1 | local user = require('lua.user') 2 | local scheme = user.colors 3 | 4 | return { 5 | useless_gap = user.gaps, 6 | border = { 7 | width = user.border_width, 8 | color = { 9 | normal = scheme.base01, 10 | marked = scheme.base04, 11 | active = scheme.base09, 12 | }, 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/dock.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | 3 | return { 4 | dock = { 5 | bg = scheme.base00, 6 | height = dpi(70), 7 | roundness = dpi(20), 8 | padding = dpi(5), 9 | spacing = dpi(5), 10 | separator = { 11 | bg = scheme.base02, 12 | width = dpi(3), 13 | height = dpi(40), 14 | roundness = dpi(10), 15 | }, 16 | tasklist = { 17 | item = { 18 | padding = dpi(10), 19 | roundness = dpi(15), 20 | color = { 21 | normal = scheme.base00, 22 | active = scheme.base01, 23 | }, 24 | }, 25 | dot = { 26 | limit = 3, 27 | size = dpi(5), 28 | color = { 29 | normal = scheme.base02, 30 | active = scheme.base09, 31 | }, 32 | }, 33 | }, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/init.lua: -------------------------------------------------------------------------------- 1 | return { 2 | require(... .. '.bar'), 3 | require(... .. '.dock'), 4 | require(... .. '.launcher'), 5 | require(... .. '.titlebar'), 6 | require(... .. '.client'), 7 | require(... .. '.layout'), 8 | require(... .. '.notification'), 9 | require(... .. '.userprompt'), 10 | require(... .. '.overview'), 11 | require(... .. '.widgets'), 12 | } 13 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/launcher.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | 3 | return { 4 | launcher = { 5 | bg = scheme.base00, 6 | cursor_fg = scheme.base02, 7 | roundness = dpi(20), 8 | entry = { 9 | fg_ghost = scheme.base03, 10 | fg_normal = scheme.base04, 11 | }, 12 | item_entry = { 13 | height = dpi(40), 14 | bg_focus = scheme.base01, 15 | }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/layout.lua: -------------------------------------------------------------------------------- 1 | local layouts_dir = require('gears').filesystem.get_configuration_dir() .. 'theme/icons/layouts/' 2 | 3 | local layout = function(str) return layouts_dir .. str .. '.svg' end 4 | 5 | local module = {} 6 | 7 | for _, value in ipairs { 8 | 'fairh', 9 | 'fairv', 10 | 'floating', 11 | 'magnifier', 12 | 'max', 13 | 'fullscreen', 14 | 'tilebottom', 15 | 'tileleft', 16 | 'tile', 17 | 'tiletop', 18 | 'spiral', 19 | 'dwindle', 20 | 'cornernw', 21 | 'cornerne', 22 | 'cornersw', 23 | 'cornerse', 24 | } do 25 | module['layout_' .. value] = layout(value) 26 | end 27 | 28 | return module 29 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/notification.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | 3 | return { 4 | notification = { 5 | spacing = 50, 6 | font = '', 7 | bg = scheme.base00, 8 | border = { width = dpi(0), color = nil }, 9 | roundness = dpi(10), 10 | opacity = 1, 11 | margins = dpi(10), 12 | icon = { 13 | size = dpi(50), 14 | roundness = dpi(10), 15 | }, 16 | action = { 17 | bg = { 18 | normal = scheme.base01, 19 | hover = scheme.base02, 20 | selected = scheme.base03, 21 | }, 22 | margins = dpi(10), 23 | roundness = dpi(5), 24 | spacing = dpi(10), 25 | }, 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/overview.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | local gaps = require('lua.user').gaps 3 | 4 | return { 5 | overview = { 6 | scale = 0.15, 7 | 8 | bg = scheme.base00, 9 | roundness = dpi(20), 10 | padding = dpi(10), 11 | spacing = dpi(5), 12 | tag = { 13 | bg = scheme.base01, 14 | roundness = dpi(15), 15 | }, 16 | client = { 17 | bg = scheme.base02, 18 | roundness = dpi(15) - gaps / 2, 19 | }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/titlebar.lua: -------------------------------------------------------------------------------- 1 | return { 2 | titlebar = { 3 | height = dpi(38), 4 | vpadding = dpi(8), 5 | hpadding = dpi(12), 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/userprompt.lua: -------------------------------------------------------------------------------- 1 | local scheme = require('lua.user').colors 2 | 3 | return { 4 | userprompt = { 5 | roundness = dpi(20), 6 | width = dpi(350), 7 | height = dpi(150), 8 | padding = dpi(20), 9 | bg = scheme.base00, 10 | item = { 11 | padding = dpi(10), 12 | roundness = dpi(5), 13 | color = { 14 | normal = scheme.base01, 15 | active = scheme.base02, 16 | }, 17 | }, 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/style/widgets.lua: -------------------------------------------------------------------------------- 1 | return { 2 | arcchart = { 3 | colors = { 'red' }, 4 | rounded_edge = true, 5 | start_angle = 5, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /dotfiles/awesome/theme/themeutils.lua: -------------------------------------------------------------------------------- 1 | local color = require('lib.color') 2 | 3 | local module = {} 4 | 5 | module.mix = function(col1, col2, f) 6 | local fn = color.transition( 7 | color.transition.HSL, 8 | color.color { hex = col1 }, 9 | color.color { hex = col2 } 10 | ) 11 | return fn(f).hex 12 | end 13 | 14 | module.transparentize = function(col, alpha) 15 | local new_col = color.color { hex = col } 16 | new_col.a = alpha 17 | return new_col.hex 18 | end 19 | 20 | return module 21 | -------------------------------------------------------------------------------- /dotfiles/awesome/xephyr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | Xephyr -screen 1024x768 :5 & sleep 1 ; DISPLAY=:5 awesome 4 | -------------------------------------------------------------------------------- /dotfiles/nvim/.gitignore: -------------------------------------------------------------------------------- 1 | /lazy-lock.json 2 | -------------------------------------------------------------------------------- /dotfiles/nvim/.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 3 | "Lua.diagnostics.globals": ["vim"] 4 | } 5 | -------------------------------------------------------------------------------- /dotfiles/nvim/init.lua: -------------------------------------------------------------------------------- 1 | vim.g.mapleader = ' ' 2 | vim.g.suda_smart_edit = 1 3 | 4 | require('config.lazy') 5 | require('config.keymaps') 6 | require('config.settings') 7 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/config/keymaps.lua: -------------------------------------------------------------------------------- 1 | local keymap = vim.keymap.set 2 | 3 | local cmd = vim.cmd 4 | local opt = { noremap = true, silent = true } 5 | 6 | cmd.BufferClose = cmd.bdelete 7 | cmd.BufferNext = cmd.bnext 8 | cmd.BufferPrev = cmd.bprev 9 | 10 | keymap({ 'n', 'v' }, '', 'b', opt) 11 | keymap({ 'n', 'v' }, '', 'w', opt) 12 | keymap({ 'n' }, '', '', opt) 13 | keymap({ 'n', 'i' }, '', '', opt) 14 | 15 | keymap('v', '', ":m '<-2gv=gv", opt) 16 | keymap('v', '', ":m '>+1gv=gv", opt) 17 | 18 | keymap('n', '', ':let @/ = ""', opt) 19 | keymap('n', 'wq', cmd.wq, opt) 20 | keymap('n', 'q', cmd.q, opt) 21 | 22 | keymap('n', 'i', 'o', opt) 23 | keymap('n', 'I', 'O', opt) 24 | 25 | keymap('n', '[', cmd.BufferPrev, opt) 26 | keymap('n', ']', cmd.BufferNext, opt) 27 | keymap('n', 'd', cmd.BufferClose, opt) 28 | 29 | keymap({ 'n', 'v' }, ';', ':', opt) 30 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | local os_name = vim.loop.os_uname().sysname 2 | local lazypath 3 | 4 | if vim.env.LAZY_PATH then 5 | lazypath = vim.env.LAZY_PATH 6 | else 7 | if string.find(os_name, 'Windows') then 8 | lazypath = vim.fn.stdpath('data') .. '\\lazy\\lazy.nvim' 9 | else 10 | lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' 11 | end 12 | end 13 | 14 | if not vim.loop.fs_stat(lazypath) then 15 | vim.fn.system({ 16 | 'git', 17 | 'clone', 18 | '--filter=blob:none', 19 | 'https://github.com/folke/lazy.nvim.git', 20 | '--branch=stable', 21 | lazypath, 22 | }) 23 | end 24 | 25 | vim.opt.rtp:prepend(lazypath) 26 | 27 | require('lazy').setup({ 28 | spec = { 29 | { import = 'plugins' }, 30 | }, 31 | install = { colorscheme = { 'oxocarbon' } }, 32 | }) 33 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/config/settings.lua: -------------------------------------------------------------------------------- 1 | local globals = vim.g 2 | local cmd = vim.cmd 3 | local options = vim.opt 4 | local diagnostic = vim.diagnostic 5 | local set = cmd.set 6 | local api = vim.api 7 | 8 | diagnostic.config({ 9 | virtual_lines = false, 10 | virtual_text = true, 11 | }) 12 | 13 | globals.loaded_netrw = 1 14 | globals.loaded_netrwPlugin = 1 15 | 16 | options.undofile = true 17 | options.cursorline = true 18 | options.number = true 19 | options.termguicolors = true 20 | options.clipboard = 'unnamedplus' 21 | options.fillchars = { 22 | eob = ' ', 23 | vert = ' ', 24 | horiz = ' ', 25 | diff = '╱', 26 | foldclose = '', 27 | foldopen = '', 28 | fold = ' ', 29 | msgsep = '─', 30 | } 31 | 32 | options.listchars = { 33 | tab = ' ──', 34 | trail = '·', 35 | nbsp = '␣', 36 | precedes = '«', 37 | extends = '»', 38 | } 39 | 40 | options.tabstop = 4 41 | options.shiftwidth = 4 42 | options.softtabstop = 4 43 | options.scrolloff = 4 44 | options.grepprg = 'rg --vimgrep' 45 | options.grepformat = '%f:%l:%c:%m' 46 | options.signcolumn = 'yes:1' 47 | options.updatetime = 250 48 | options.timeoutlen = 400 49 | options.foldcolumn = '1' 50 | options.foldlevel = 99 51 | options.foldlevelstart = 99 52 | options.foldenable = true 53 | 54 | -- api.nvim_set_hl(0, "Normal", { bg = "none" }) 55 | -- api.nvim_set_hl(0, "NormalFloat", { bg = "none" }) 56 | -- api.nvim_set_hl(0, "NormalNC", { bg = "none" }) 57 | 58 | set('expandtab') 59 | set('infercase') 60 | set('ignorecase') 61 | set('smartcase') 62 | set('gdefault') 63 | set('nowrap') 64 | set('number') 65 | set('list') 66 | set('ignorecase') 67 | set('smartcase') 68 | set('gdefault') 69 | 70 | api.nvim_command([[ 71 | autocmd BufEnter * if len(filter(range(1, bufnr('$')), 'buflisted(v:val)')) > 1 | set showtabline=2 | else | set showtabline=0 | endif 72 | ]]) 73 | 74 | KindIcons = { 75 | Method = '  ', 76 | Function = '  ', 77 | Constructor = '  ', 78 | Field = '  ', 79 | Variable = '  ', 80 | Class = '  ', 81 | Interface = '  ', 82 | Module = '  ', 83 | Property = '  ', 84 | Unit = '  ', 85 | Value = '  ', 86 | Enum = '  ', 87 | Keyword = '  ', 88 | Snippet = '  ', 89 | Color = '  ', 90 | File = '  ', 91 | Reference = '  ', 92 | Folder = '  ', 93 | EnumMember = '  ', 94 | Constant = '  ', 95 | Struct = '  ', 96 | Event = '  ', 97 | Operator = '  ', 98 | TypeParameter = '  ', 99 | Namespace = '  ', 100 | Package = '  ', 101 | String = '  ', 102 | Text = '  ', 103 | Number = '  ', 104 | Array = '  ', 105 | Object = '  ', 106 | Key = '  ', 107 | Boolean = '  ', 108 | Null = '  ', 109 | } 110 | 111 | vim.diagnostic.config({ 112 | virtual_text = { 113 | prefix = '#', 114 | }, 115 | signs = { 116 | text = { 117 | [vim.diagnostic.severity.HINT] = '󰌶', 118 | [vim.diagnostic.severity.INFO] = '', 119 | [vim.diagnostic.severity.WARN] = '', 120 | [vim.diagnostic.severity.ERROR] = '', 121 | --[vim.diagnostic.severity.OTHER] = '', 122 | }, 123 | }, 124 | }) 125 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/conform.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'stevearc/conform.nvim', 3 | event = { 'BufWritePre' }, 4 | cmd = { 'ConformInfo' }, 5 | init = function() 6 | vim.api.nvim_create_user_command('ToggleFormat', function() 7 | local global_state = vim.g.disable_autoformat 8 | local buffer_state = vim.b.disable_autoformat 9 | if global_state or buffer_state then 10 | vim.b.disable_autoformat = false 11 | else 12 | vim.b.disable_autoformat = true 13 | end 14 | end, { 15 | desc = 'Toggle autoformat-on-save', 16 | }) 17 | end, 18 | opts = { 19 | formatters_by_ft = { 20 | c = { 'clang-format' }, 21 | ['c++'] = { 'clang-format' }, 22 | lua = { 'stylua' }, 23 | fennel = { 'fnlfmt' }, 24 | python = { 25 | 'isort', 26 | 'ruff_fix', -- To fix auto-fixable lint errors. 27 | 'ruff_format', -- To run the Ruff formatter. 28 | }, 29 | javascript = { 'biome' }, 30 | typescript = { 'biome' }, 31 | json = { 'biome' }, 32 | nix = { 'nixpkgs-fmt', 'nixfmt' }, 33 | }, 34 | format_after_save = function(bufnr) 35 | if vim.b[bufnr].disable_autoformat then 36 | return 37 | end 38 | return { timeout_ms = 1000, lsp_format = 'fallback' } 39 | end, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/gitsigns.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'lewis6991/gitsigns.nvim', 3 | opts = { 4 | signs = { 5 | add = { text = '│' }, 6 | change = { text = '│' }, 7 | delete = { text = '_' }, 8 | topdelete = { text = '‾' }, 9 | changedelete = { text = '~' }, 10 | untracked = { text = '┆' }, 11 | }, 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/mason.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'williamboman/mason.nvim', 3 | dependencies = { 'williamboman/mason-lspconfig.nvim' }, 4 | opts = { 5 | ui = { 6 | icons = { 7 | package_installed = '●', 8 | package_pending = '○', 9 | package_uninstalled = '○', 10 | }, 11 | }, 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/noice.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/noice.nvim", 3 | event = "VeryLazy", 4 | dependencies = { "MunifTanjim/nui.nvim", "rcarriga/nvim-notify" }, 5 | opts = { 6 | popupmenu = { backend = "cmp" }, 7 | cmdline = { 8 | format = { 9 | cmdline = { pattern = "^:", icon = " ", lang = "vim" }, 10 | search_down = { kind = "search", pattern = "^/", icon = " ", lang = "regex" }, 11 | search_up = { kind = "search", pattern = "^%?", icon = " ", lang = "regex" }, 12 | filter = { pattern = "^:%s*!", icon = "$", lang = "bash" }, 13 | lua = { pattern = "^:%s*lua%s+", icon = "", lang = "lua" }, 14 | help = { pattern = "^:%s*help%s+", icon = "󰋖" }, 15 | input = {}, 16 | }, 17 | }, 18 | messages = { 19 | enabled = true, -- enables the Noice messages UI 20 | 21 | view = "notify", -- default view for messages 22 | view_error = "notify", -- view for errors 23 | view_warn = "notify", -- view for warnings 24 | view_history = "messages", -- view for :messages 25 | view_search = "virtualtext", -- view for search count messages. Set to `false` to disable 26 | }, 27 | views = { 28 | cmdline_popup = { 29 | position = { 30 | row = 2, 31 | col = 2, 32 | }, 33 | size = { 34 | width = "98%", 35 | }, 36 | border = { 37 | style = "none", 38 | padding = { 1, 2 }, 39 | }, 40 | filter_options = {}, 41 | win_options = { 42 | winhighlight = "NormalFloat:NormalFloat,FloatBorder:FloatBorder", 43 | }, 44 | }, 45 | }, 46 | routes = { 47 | { 48 | filter = { 49 | event = "msg_show", 50 | kind = "", 51 | find = "written", 52 | }, 53 | opts = { skip = true }, 54 | }, 55 | }, 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-autopairs.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'windwp/nvim-autopairs', 3 | event = "InsertEnter", 4 | config = true 5 | } 6 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'hrsh7th/nvim-cmp', 3 | dependencies = { 4 | 'neovim/nvim-lspconfig', 5 | 'hrsh7th/cmp-nvim-lsp', 6 | 'hrsh7th/cmp-buffer', 7 | 'hrsh7th/cmp-path', 8 | 'hrsh7th/cmp-cmdline', 9 | -- 10 | 'L3MON4D3/LuaSnip', 11 | 'saadparwaiz1/cmp_luasnip', 12 | }, 13 | config = function() 14 | local cmp = require('cmp') 15 | 16 | cmp.setup({ 17 | snippet = { 18 | expand = function(args) 19 | require('luasnip').lsp_expand(args.body) 20 | end, 21 | }, 22 | sources = cmp.config.sources({ 23 | { name = 'nvim_lsp' }, 24 | { name = 'luasnip', option = { show_autosnippets = true } }, 25 | { name = 'buffer' }, 26 | { name = 'path' }, 27 | }), 28 | window = { 29 | completion = { 30 | winhighlight = 'Normal:Pmenu,FloatBorder:Pmenu,Search:None', 31 | col_offset = -3, 32 | side_padding = 0, 33 | }, 34 | }, 35 | formatting = { 36 | fields = { 'kind', 'abbr', 'menu' }, 37 | format = function(entry, vim_item) 38 | vim_item.kind = KindIcons[vim_item.kind] 39 | or KindIcons['Text'] 40 | vim_item.menu = ({ 41 | path = '[Path]', 42 | buffer = '[Buffer]', 43 | nvim_lsp = '[LSP]', 44 | luasnip = '[LuaSnip]', 45 | --nvim_lua = '[Lua]', 46 | latex_symbols = '[LaTeX]', 47 | })[entry.source.name] 48 | 49 | vim_item.menu = vim_item.menu 50 | or string.format( 51 | '[%s]', 52 | string.gsub(entry.source.name, '^%l', string.upper) 53 | ) 54 | 55 | return vim_item 56 | end, 57 | }, 58 | mapping = cmp.mapping.preset.insert({ 59 | --[""] = cmp.mapping.scroll_docs(-4), 60 | --[""] = cmp.mapping.scroll_docs(4), 61 | [''] = cmp.mapping.complete(), 62 | [''] = cmp.mapping.abort(), 63 | [''] = cmp.mapping.confirm({ select = false }), 64 | [''] = cmp.mapping(function(fallback) 65 | if cmp.visible() then 66 | cmp.select_next_item() 67 | else 68 | fallback() 69 | end 70 | end), 71 | [''] = cmp.mapping(function(fallback) 72 | if cmp.visible() then 73 | cmp.select_prev_item() 74 | else 75 | fallback() 76 | end 77 | end), 78 | }), 79 | experimental = { 80 | ghost_text = true, 81 | }, 82 | }) 83 | cmp.setup.cmdline({ '/', '?', ':' }, { 84 | mapping = cmp.mapping.preset.cmdline(), 85 | sources = { 86 | { name = 'buffer' }, 87 | { name = 'path' }, 88 | { name = 'cmdline' }, 89 | }, 90 | }) 91 | end, 92 | } 93 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-colorizer.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "NvChad/nvim-colorizer.lua", 3 | opts = { 4 | filetypes = { "*" }, 5 | user_default_options = { 6 | mode = "background", 7 | virtualtext = "■", 8 | always_update = false, 9 | }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-comment.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'terrortylor/nvim-comment', 3 | --lazy = false, 4 | cmd = { 'CommentToggle' }, 5 | config = function() 6 | require('nvim_comment').setup({ 7 | comment_empty = false, 8 | create_mappings = false, 9 | }) 10 | end, 11 | keys = { 12 | { '\\', 'CommentToggle' }, 13 | { mode = 'v', '\\', ":'<,'>CommentToggle" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-lspconfig.lua: -------------------------------------------------------------------------------- 1 | local servers = { 2 | 'clangd', -- C/C++ 3 | --'ruff', -- Python 4 | 'pylsp', 5 | -- 'basedpyright', 6 | -- TypeScript/JavaScript 7 | 'volar', 8 | 'biome', 9 | 'emmet_language_server', 10 | -- 'cssls', -- CSS/SCSS 11 | -- 'somesass_ls', -- CSS/SCSS 12 | -- 'css_variables', 13 | -- 'cssmodules_ls', 14 | 'eslint', -- eslint 15 | 'bashls', -- Bash 16 | 'lua_ls', -- Lua 17 | 'fennel_language_server', 18 | 'rust_analyzer', -- Rust 19 | 'svelte', -- Svelte 20 | 'perlpls', -- Perl 21 | 'marksman', -- Markdown 22 | 'vala_ls', -- Vala 23 | 'nil_ls', -- Nix 24 | 'lemminx', -- xml 25 | 'mesonlsp', -- meson 26 | } 27 | 28 | return { 29 | 'neovim/nvim-lspconfig', 30 | config = function() 31 | local lspconfig = require('lspconfig') 32 | local capabilities = require('cmp_nvim_lsp').default_capabilities() 33 | capabilities.textDocument.completion.completionItem.snippetSupport = 34 | true 35 | local navic = require('nvim-navic') 36 | 37 | for _, lsp in ipairs(servers) do 38 | local opts = { 39 | capabilities = capabilities, 40 | on_attach = function(client, n) 41 | if client.server_capabilities.documentSymbolProvider then 42 | navic.attach(client, n) 43 | end 44 | end, 45 | } 46 | 47 | if lsp == 'emmet_language_server' then 48 | opts.init_options = { showSuggestionsAsSnippets = true } 49 | elseif lsp == 'volar' then 50 | opts.filetypes = { 51 | 'typescript', 52 | 'javascript', 53 | 'javascriptreact', 54 | 'typescriptreact', 55 | 'vue', 56 | } 57 | opts.init_options = { vue = { hybridMode = false } } 58 | end 59 | 60 | lspconfig[lsp].setup(opts) 61 | end 62 | end, 63 | } 64 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-navic.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "SmiteshP/nvim-navic", 3 | version = "*", 4 | lazy = true, 5 | dependencies = { "neovim/nvim-lspconfig"}, 6 | opts = { 7 | --icons = KindIcons, 8 | lsp = { auto_attach = true, preference = nil }, 9 | highlight = true, 10 | separator = "", 11 | depth_limit = 6, 12 | depth_limit_indicator = "..", 13 | safe_output = true, 14 | lazy_update_context = false, 15 | click = true, 16 | format_text = function(text) 17 | return " " .. text .. " " 18 | end 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-treesitter-context.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'nvim-treesitter/nvim-treesitter-context', 3 | dependencies = { 'nvim-treesitter/nvim-treesitter' }, 4 | } 5 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'nvim-treesitter/nvim-treesitter', 3 | lazy = false, 4 | build = ':TSUpdate', 5 | config = function() 6 | require('nvim-treesitter.configs').setup({ 7 | auto_install = true, 8 | highlight = { 9 | enable = true, 10 | additional_vim_regex_highlighting = false, 11 | disable = function(_, buffer) 12 | local max_filesize = 100 * 1024 13 | local ok, stats = pcall( 14 | vim.loop.fs_stat, 15 | vim.api.nvim_buf_get_name(buffer) 16 | ) 17 | 18 | if ok and stats and stats.size > max_filesize then 19 | return true 20 | end 21 | end, 22 | }, 23 | }) 24 | end, 25 | } 26 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/nvim-ufo.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'kevinhwang91/nvim-ufo', 3 | lazy = false, 4 | dependencies = { 'kevinhwang91/promise-async' }, 5 | opts = { 6 | provider_selector = function() 7 | return { 'treesitter', 'indent' } 8 | end, 9 | }, 10 | keys = { 11 | { 'fc', 'foldclose' }, 12 | { 'ff', 'foldopen' }, 13 | { 14 | mode = 'v', 15 | 'fc', 16 | ":'<,'>foldclose", 17 | }, 18 | { 19 | mode = 'v', 20 | 'ff', 21 | ":'<,'>foldopen", 22 | }, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/oxocarbon.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'nyoom-engineering/oxocarbon.nvim', 3 | lazy = false, 4 | priority = 1000, 5 | config = function() 6 | vim.cmd.colorscheme('oxocarbon') 7 | end, 8 | } 9 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/presence.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'andweeb/presence.nvim', 3 | event = 'VeryLazy', 4 | opts = { 5 | main_image = 'file', 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/tailwind-fold.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'razak17/tailwind-fold.nvim', 3 | dependencies = { 'nvim-treesitter/nvim-treesitter' }, 4 | opts = { symbol = '󰇘' }, 5 | } 6 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/telescope.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'nvim-telescope/telescope.nvim', 3 | version = '*', 4 | dependencies = { 'nvim-lua/plenary.nvim' }, 5 | keys = { 6 | { '', 'Telescope buffers' }, 7 | { '.', 'Telescope find_files' }, 8 | { ',', 'Telescope live_grep' }, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/trouble.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'folke/trouble.nvim', 3 | opts = { 4 | icons = { 5 | kinds = KindIcons, 6 | }, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /dotfiles/nvim/lua/plugins/vim-suda.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'lambdalisue/vim-suda', 3 | lazy = false, 4 | config = function() end, 5 | } 6 | -------------------------------------------------------------------------------- /dotfiles/nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 80 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 4 5 | quote_style = "AutoPreferSingle" 6 | -------------------------------------------------------------------------------- /dotfiles/picom/picom.conf: -------------------------------------------------------------------------------- 1 | active-opacity = 1; 2 | backend = "glx"; 3 | blur: { background = true; kern = "3x3box"; method = "dual_kawase"; strength = 4; }; 4 | blur-background-exclude = [ "window_type = 'dock'" , "window_type = 'desktop'" ]; 5 | corner-radius = 15; 6 | corner-radius-rules = [ "0:QTILE_INTERNAL = 1" ]; 7 | dbus = true; 8 | detect-client-opacity = true; 9 | detect-rounded-corners = true; 10 | detect-transient = true; 11 | fade-delta = 4; 12 | fade-exclude = [ ]; 13 | fade-in-step = 0.020000; 14 | fade-out-step = 0.020000; 15 | fading = true; 16 | frame-opacity = 1; 17 | inactive-opacity = 1; 18 | inactive-opacity-override = false; 19 | log-level = "warn"; 20 | no-fading-openclose = true; 21 | opacity-rule = [ "100:fullscreen" , "100:name *= 'Dunst'" ]; 22 | rounded-corners-exclude = [ "window_type = 'dock'" , "window_type = 'desktop'" ]; 23 | shadow = true; 24 | shadow-color = "#111111"; 25 | shadow-exclude = [ "name *= 'Dunst'" , "window_type = 'desktop'" , "window_type = 'notification'" ]; 26 | shadow-offset-x = -8; 27 | shadow-offset-y = -8; 28 | shadow-opacity = 0.600000; 29 | shadow-radius = 10; 30 | use-damage = true; 31 | use-ewmh-active-win = true; 32 | vsync = true; 33 | wintypes: { dnd = { shadow = false; }; dock = { shadow = false; }; dropdown_menu = { opacity = 0.800000; }; menu = { blur-background = false; shadow = false; }; popup_menu = { opacity = 0.800000; }; tooltip = { fade = true; focus = true; opacity = 0.750000; shadow = false; }; }; 34 | 35 | animations = ( 36 | { 37 | triggers = ["close"]; 38 | opacity = { 39 | curve = "cubic-bezier(0,0,1,-0.28)"; 40 | duration = .2; 41 | start = "window-raw-opacity-before"; 42 | end = 0; 43 | }; 44 | blur-opacity = "opacity"; 45 | shadow-opacity = "opacity"; 46 | offset-x = "(1 - scale-x) / 2 * window-width"; 47 | offset-y = "(1 - scale-y) / 2 * window-height"; 48 | scale-x = { 49 | curve = "cubic-bezier(0,0,1,-0.28)"; 50 | duration = .2; 51 | start = 1; 52 | end = .5; 53 | }; 54 | scale-y = "scale-x"; 55 | shadow-scale-x = "scale-x"; 56 | shadow-scale-y = "scale-y"; 57 | shadow-offset-x = "offset-x"; 58 | shadow-offset-y = "offset-y"; 59 | }, 60 | { 61 | triggers = ["open"]; 62 | opacity = { 63 | curve = "cubic-bezier(0,1.28,1,1)"; 64 | duration = .2; 65 | start = 0; 66 | end = "window-raw-opacity"; 67 | } 68 | blur-opacity = "opacity"; 69 | shadow-opacity = "opacity"; 70 | offset-x = "(1 - scale-x) / 2 * window-width"; 71 | offset-y = "(1 - scale-y) / 2 * window-height"; 72 | scale-x = { 73 | curve = "cubic-bezier(0,1.28,1,1)"; 74 | duration = .2; 75 | start = .5; 76 | end = 1; 77 | }; 78 | scale-y = "scale-x"; 79 | shadow-scale-x = "scale-x"; 80 | shadow-scale-y = "scale-y"; 81 | shadow-offset-x = "offset-x"; 82 | shadow-offset-y = "offset-y"; 83 | }, 84 | { 85 | triggers = ["geometry"] 86 | scale-x = { 87 | curve = "cubic-bezier(0,1.28,1,1)"; 88 | duration = 0.22; 89 | start = "window-width-before / window-width"; 90 | end = 1; 91 | } 92 | scale-y = { 93 | curve = "cubic-bezier(0,1.28,1,1)"; 94 | duration = 0.22; 95 | start = "window-height-before / window-height"; 96 | end = 1; 97 | } 98 | offset-x = { 99 | curve = "cubic-bezier(0,1.28,1,1)"; 100 | duration = 0.22; 101 | start = "window-x-before - window-x"; 102 | end = 0; 103 | } 104 | offset-y = { 105 | curve = "cubic-bezier(0,1.28,1,1)"; 106 | duration = 0.22; 107 | start = "window-y-before - window-y"; 108 | end = 0; 109 | } 110 | 111 | shadow-scale-x = "scale-x"; 112 | shadow-scale-y = "scale-y"; 113 | shadow-offset-x = "offset-x"; 114 | shadow-offset-y = "offset-y"; 115 | } 116 | ) 117 | -------------------------------------------------------------------------------- /dotfiles/wezterm/wezterm.lua: -------------------------------------------------------------------------------- 1 | return { 2 | hide_tab_bar_if_only_one_tab = true, 3 | window_close_confirmation = "NeverPrompt", 4 | default_cursor_style = "BlinkingBlock", 5 | color_scheme = "oxocarbon-dark", 6 | cursor_blink_ease_out = "Constant", 7 | cursor_blink_ease_in = "Linear", 8 | window_decorations = "RESIZE", 9 | use_fancy_tab_bar = false, 10 | tab_bar_at_bottom = true, 11 | animation_fps = 144, 12 | font_size = 11, 13 | window_padding = { 14 | left = "3cell", 15 | right = "3cell", 16 | top = "1cell", 17 | bottom = "1cell", 18 | }, 19 | keys = { 20 | { 21 | key = "w", 22 | mods = "SHIFT|CTRL", 23 | action = wezterm.action.CloseCurrentTab({ confirm = false }), 24 | }, 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /dotfiles/xdg-desktop-portal/none+awesome-portals.conf: -------------------------------------------------------------------------------- 1 | [preferred] 2 | default=luajit;gtk; 3 | org.freedesktop.impl.portal.FileChooser=nautilus; 4 | -------------------------------------------------------------------------------- /dotfiles/xdg-desktop-portal/portals/luajit.portal: -------------------------------------------------------------------------------- 1 | [portal] 2 | DBusName=org.freedesktop.impl.portal.desktop.luajit 3 | Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Settings;org.freedesktop.impl.portal.Wallpaper; 4 | UseIn=none+awesome 5 | -------------------------------------------------------------------------------- /etc/nixos/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | pkgs, 8 | modulesPath, 9 | ... 10 | }: 11 | 12 | { 13 | imports = [ 14 | (modulesPath + "/installer/scan/not-detected.nix") 15 | ]; 16 | 17 | boot.initrd.availableKernelModules = [ 18 | "xhci_pci" 19 | "ahci" 20 | "nvme" 21 | "usb_storage" 22 | "usbhid" 23 | "sd_mod" 24 | ]; 25 | boot.initrd.kernelModules = [ ]; 26 | boot.kernelModules = [ "kvm-intel" ]; 27 | boot.extraModulePackages = [ ]; 28 | 29 | fileSystems."/" = { 30 | device = "/dev/disk/by-label/NIXROOT"; 31 | fsType = "ext4"; 32 | }; 33 | 34 | fileSystems."/boot" = { 35 | device = "/dev/disk/by-label/NIXBOOT"; 36 | fsType = "vfat"; 37 | options = [ 38 | "fmask=0022" 39 | "dmask=0022" 40 | ]; 41 | }; 42 | 43 | swapDevices = [ 44 | { device = "/dev/disk/by-label/NIXSWAP"; } 45 | ]; 46 | 47 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 48 | # (the default) this is the recommended approach. When using systemd-networkd it's 49 | # still possible to use this option, but it's recommended to use it in conjunction 50 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 51 | networking.useDHCP = lib.mkDefault true; 52 | # networking.interfaces.enp4s0.useDHCP = lib.mkDefault true; 53 | # networking.interfaces.wlo1.useDHCP = lib.mkDefault true; 54 | 55 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 56 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 57 | } 58 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Home Manager configuration of tokyob0t"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 6 | home-manager.url = "github:nix-community/home-manager"; 7 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 8 | nix-software-center.url = "github:snowfallorg/nix-software-center"; 9 | spicetify-nix.url = "github:Gerg-L/spicetify-nix"; 10 | }; 11 | 12 | outputs = 13 | { 14 | nixpkgs, 15 | home-manager, 16 | ... 17 | }: 18 | let 19 | system = "x86_64-linux"; 20 | pkgs = nixpkgs.legacyPackages.${system}; 21 | in 22 | { 23 | homeConfigurations.tokyob0t = home-manager.lib.homeManagerConfiguration { 24 | inherit pkgs; 25 | 26 | modules = [ 27 | # nixvim.homeManagerModules.nixvim 28 | ./home.nix 29 | ]; 30 | }; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /home.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | 5 | nixpkgs.config.allowUnfree = true; 6 | nix.package = pkgs.nix; 7 | nix.settings.experimental-features = [ 8 | "nix-command" 9 | "flakes" 10 | ]; 11 | 12 | imports = [ 13 | ./nix/packages.nix 14 | ./nix/bash.nix 15 | ./nix/git.nix 16 | ./nix/wezterm.nix 17 | ./nix/picom.nix 18 | ./nix/gnome.nix 19 | ./nix/spotify.nix 20 | # ./nix/portal.nix 21 | # ./nix/nvim.nix 22 | ./nix/flatpak.nix 23 | ]; 24 | 25 | home.username = "tokyob0t"; 26 | home.homeDirectory = "/home/tokyob0t"; 27 | home.preferXdgDirectories = true; 28 | home.shell.enableShellIntegration = true; 29 | home.sessionVariables = { 30 | EDITOR = "nvim"; 31 | STEAM_EXTRA_COMPAT_TOOLS_PATHS = "\${HOME}/.steam/root/compatibilitytools.d"; 32 | PROTON_PATH = "\${HOME}/.steam/root/compatibilitytools.d/GE-Proton9-27/"; 33 | # GI_TYPELIB_PATH = "/run/current-system/sw/lib/girepository-1.0"; 34 | }; 35 | 36 | programs.home-manager.enable = true; 37 | home.stateVersion = "24.05"; 38 | } 39 | -------------------------------------------------------------------------------- /nix/bash.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | programs.bash.enable = true; 5 | programs.bash.bashrcExtra = builtins.readFile ../dotfiles/.bashrc; 6 | programs.bash.enableVteIntegration = true; 7 | programs.bash.historyFile = "/home/tokyob0t/.bash_history"; 8 | 9 | programs.bash.sessionVariables.LS_COLORS = "di=1;34:ln=1;35:so=32:pi=33:ex=31:bd=35:cd=35:su=1;32:sg=1;32:tw=34:ow=34"; 10 | 11 | programs.bash.shellOptions = [ 12 | "autocd" 13 | "cdspell" 14 | "direxpand" 15 | "dirspell" 16 | "histappend" 17 | "checkwinsize" 18 | ]; 19 | 20 | programs.bash.shellAliases = { 21 | ".." = "cd .."; 22 | ls = "ls --color --group-directories-first --literal"; 23 | l = "ls -a"; 24 | reload = "source ~/.bashrc"; 25 | please = "sudo"; 26 | mkdir = "mkdir -pv"; 27 | cp = "cp -rv"; 28 | # rm = "rm -rfd"; 29 | rm = "gio trash"; 30 | grep = "rg"; 31 | gotop = "gotop --layout=minimal"; 32 | fzf = "fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}'"; 33 | jq = "gojq"; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /nix/flatpak.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | grep = pkgs.gnugrep; 10 | desiredFlatpaks = [ 11 | "io.github.cleomenezesjr.Serigy" 12 | "io.mrarm.mcpelauncher" 13 | ]; 14 | in 15 | { 16 | home.activation.flatpakManagement = lib.hm.dag.entryAfter [ "writeBoundary" ] '' 17 | # 1. Ensure the Flathub repo is added 18 | ${pkgs.flatpak}/bin/flatpak remote-add --if-not-exists flathub \ 19 | https://flathub.org/repo/flathub.flatpakrepo 20 | 21 | # 2. Get currently installed Flatpaks 22 | installedFlatpaks=$(${pkgs.flatpak}/bin/flatpak list --app --columns=application) 23 | 24 | # 3. Remove any Flatpaks that are NOT in the desired list 25 | for installed in $installedFlatpaks; do 26 | if ! echo ${toString desiredFlatpaks} | ${grep}/bin/grep -q $installed; then 27 | echo "Removing $installed because it's not in the desiredFlatpaks list." 28 | ${pkgs.flatpak}/bin/flatpak uninstall -y --noninteractive $installed 29 | fi 30 | done 31 | 32 | # 4. Install or re-install the Flatpaks you DO want 33 | for app in ${toString desiredFlatpaks}; do 34 | echo "Ensuring $app is installed." 35 | ${pkgs.flatpak}/bin/flatpak install -y flathub $app 36 | done 37 | 38 | # 5. Remove unused Flatpaks 39 | ${pkgs.flatpak}/bin/flatpak uninstall --unused -y 40 | 41 | # 6. Update all installed Flatpaks 42 | ${pkgs.flatpak}/bin/flatpak update -y 43 | ''; 44 | } 45 | -------------------------------------------------------------------------------- /nix/git.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | programs.git.enable = true; 5 | programs.git.userName = "tokyob0t"; 6 | programs.git.userEmail = "kparra2023@alu.uct.cl"; 7 | programs.git.extraConfig.core.editor = "re.sonny.Commit"; 8 | } 9 | -------------------------------------------------------------------------------- /nix/gnome.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | let 4 | mkTuple = (s: (lib.hm.gvariant.mkTuple s)); 5 | 6 | gnomeExtensions = with pkgs.gnomeExtensions; [ 7 | caffeine 8 | blur-my-shell 9 | luminus-desktop-y 10 | night-theme-switcher 11 | quick-settings-audio-panel 12 | dash-to-dock 13 | fuzzy-app-search 14 | tiling-assistant 15 | ]; 16 | 17 | gtkIconTheme = { 18 | name = "MoreWaita"; 19 | package = pkgs.morewaita-icon-theme; 20 | }; 21 | gtkTheme = { 22 | name = "adw-gtk3"; 23 | package = pkgs.adw-gtk3; 24 | }; 25 | in 26 | { 27 | 28 | gtk = { 29 | enable = true; 30 | font.name = "Cantarell"; 31 | font.package = pkgs.cantarell-fonts; 32 | iconTheme = gtkIconTheme; 33 | theme = gtkTheme; 34 | gtk4.extraConfig = { 35 | gtk-theme-name = "Adwaita"; 36 | }; 37 | }; 38 | 39 | xdg.configFile."gtk-4.0/gtk.css".enable = false; # Disable adw-gtk3 for gtk4 apps 40 | home.file.".config/gtk-4.0/gtk.css".text = ''''; 41 | 42 | dconf.settings = { 43 | "org/gnome/desktop/interface" = { 44 | show-battery-percentage = true; 45 | # icon-theme = iconTheme.name; 46 | # gtk-theme = gtkTheme.name; 47 | }; 48 | "org/gnome/shell" = { 49 | disable-user-extensions = false; 50 | enabled-extensions = 51 | (map (extension: extension.extensionUuid) gnomeExtensions) 52 | ++ (map (name: name + "@gnome-shell-extensions.gcampax.github.io") [ 53 | "launch-new-instance" 54 | "light-style" 55 | "user-themes" 56 | ]); 57 | favorite-apps = [ 58 | "firefox.desktop" 59 | "org.gnome.Nautilus.desktop" 60 | "cartridges.desktop" 61 | "discord.desktop" 62 | "page.kramo.Cartridges.desktop" 63 | ]; 64 | }; 65 | "org/gnome/shell/app-switcher" = { 66 | current-workspace-only = true; 67 | }; 68 | "org/gnome/desktop/peripherals/touchpad" = { 69 | natural-scroll = true; 70 | tap-to-click = true; 71 | two-finger-scrolling-enabled = true; 72 | }; 73 | "org/gnome/desktop/input-sources" = { 74 | sources = [ 75 | (mkTuple [ 76 | "xkb" 77 | "us+altgr-intl" 78 | ]) 79 | ]; 80 | xkb-options = [ "lv3:ralt_switch" ]; 81 | }; 82 | "org/gnome/mutter" = { 83 | dynamic-workspaces = false; 84 | edge-tiling = true; 85 | num-workspaces = 5; 86 | workspaces-only-on-primary = true; 87 | }; 88 | "org/gnome/desktop/wm/preferences" = { 89 | mouse-button-modifier = ""; 90 | num-workspaces = 5; 91 | resize-with-right-button = true; 92 | focus-mode = "click"; 93 | }; 94 | "org/gnome/desktop/wm/keybindings" = { 95 | close = [ "w" ]; 96 | toggle-maximized = [ "c" ]; 97 | switch-applications = [ "Tab" ]; 98 | switch-to-workspace-1 = [ "1" ]; 99 | switch-to-workspace-2 = [ "2" ]; 100 | switch-to-workspace-3 = [ "3" ]; 101 | switch-to-workspace-4 = [ "4" ]; 102 | switch-to-workspace-5 = [ "5" ]; 103 | }; 104 | "org/gnome/shell/keybindings" = { 105 | show-screenshot-ui = [ "s" ]; 106 | switch-to-application-1 = [ ]; 107 | switch-to-application-2 = [ ]; 108 | switch-to-application-3 = [ ]; 109 | switch-to-application-4 = [ ]; 110 | switch-to-application-5 = [ ]; 111 | }; 112 | "org/gnome/settings-daemon/plugins/media-keys" = { 113 | custom-keybindings = [ 114 | "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/" 115 | "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/" 116 | ]; 117 | }; 118 | 119 | "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = { 120 | name = "Copy to clipboard"; 121 | command = "flatpak run io.github.cleomenezesjr.Serigy --copy"; 122 | binding = "c"; 123 | }; 124 | 125 | "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = { 126 | name = "Open clipboard"; 127 | command = "flatpak run io.github.cleomenezesjr.Serigy"; 128 | binding = "v"; 129 | }; 130 | }; 131 | } 132 | -------------------------------------------------------------------------------- /nix/nvim.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.neovim.enable = true; 4 | # programs.neovim.defaultEditor = true; 5 | # programs.neovim.viAlias = true; 6 | # programs.neovim.vimAlias = true; 7 | # programs.neovim.withNodeJs = true; 8 | # programs.neovim.withPython3 = true; 9 | # programs.neovim.withRuby = true; 10 | # programs.neovim.extraPackages = with pkgs; [ 11 | # nil 12 | # libgcc 13 | # lemminx 14 | # gcc 15 | # stylua 16 | # nixfmt-rfc-style 17 | # nixpkgs-fmt 18 | # biome 19 | # lua-language-server 20 | # bash-language-server 21 | # ]; 22 | } 23 | -------------------------------------------------------------------------------- /nix/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, inputs, ... }: 2 | 3 | let 4 | nix-software-center = inputs.nix-software-center.packages.${pkgs.system}.default; 5 | in 6 | { 7 | home.packages = 8 | (with pkgs.luajitPackages; [ lgi ]) 9 | ++ (with pkgs; [ 10 | nix-software-center 11 | picom 12 | luajit 13 | discord 14 | prismlauncher 15 | spotify 16 | spicetify-cli 17 | 18 | protonup 19 | dconf 20 | obsidian 21 | libnotify 22 | obs-studio 23 | unrar 24 | ripgrep 25 | cloc 26 | gotop 27 | 28 | # nvim 29 | nil 30 | libgcc 31 | lemminx 32 | gcc 33 | stylua 34 | nixfmt-rfc-style 35 | nixpkgs-fmt 36 | biome 37 | lua-language-server 38 | bash-language-server 39 | 40 | # gtk 41 | d-spy 42 | cartridges 43 | resources 44 | monophony 45 | blackbox-terminal 46 | icon-library 47 | showtime 48 | gnome-extension-manager 49 | dconf-editor 50 | commit 51 | kooha 52 | door-knocker 53 | gnome-screenshot 54 | gradience 55 | papers 56 | komikku 57 | varia 58 | ]); 59 | } 60 | -------------------------------------------------------------------------------- /nix/picom.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | home.file.".config/picom/picom.conf".text = builtins.readFile ../dotfiles/picom/picom.conf; 5 | 6 | # services.picom.backend = "glx"; 7 | # services.picom.activeOpacity = 1; 8 | # services.picom.vSync = true; 9 | 10 | # services.picom.opacityRules = [ 11 | # "100:fullscreen" 12 | # "100:name *= 'Dunst'" 13 | # ]; 14 | 15 | # services.picom.shadow = true; 16 | # services.picom.shadowOpacity = 0.6; 17 | # services.picom.shadowOffsets = [ 18 | # (-8) 19 | # (-8) 20 | # ]; 21 | # services.picom.shadowExclude = [ 22 | # "name *= 'Dunst'" 23 | # "window_type = 'desktop'" 24 | # "window_type = 'notification'" 25 | # ]; 26 | 27 | # services.picom.fade = true; 28 | # services.picom.fadeDelta = 4; 29 | # services.picom.fadeSteps = [ 30 | # 0.02 31 | # 0.02 32 | # ]; 33 | 34 | # services.picom.wintypes.tooltip.fade = true; 35 | # services.picom.wintypes.tooltip.shadow = false; 36 | # services.picom.wintypes.tooltip.opacity = 0.75; 37 | # services.picom.wintypes.tooltip.focus = true; 38 | 39 | # services.picom.wintypes.dock.shadow = false; 40 | # services.picom.wintypes.dnd.shadow = false; 41 | 42 | # services.picom.wintypes.popup_menu.opacity = 0.8; 43 | # services.picom.wintypes.dropdown_menu.opacity = 0.8; 44 | 45 | # services.picom.wintypes.menu.blur-background = false; 46 | # services.picom.wintypes.menu.shadow = false; 47 | 48 | # services.picom.settings.dbus = true; 49 | # services.picom.settings.shadow-radius = 10; 50 | # services.picom.settings.shadow-color = "#111111"; 51 | # services.picom.settings.no-fading-openclose = true; 52 | # services.picom.settings.inactive-opacity = 1; 53 | # services.picom.settings.frame-opacity = 1; 54 | # services.picom.settings.inactive-opacity-override = false; 55 | # services.picom.settings.corner-radius = 15; 56 | # services.picom.settings.corner-radius-rules = [ "0:QTILE_INTERNAL = 1" ]; 57 | 58 | # services.picom.settings.rounded-corners-exclude = [ 59 | # "window_type = 'dock'" 60 | # "window_type = 'desktop'" 61 | # ]; 62 | 63 | # services.picom.settings.blur.kern = "3x3box"; 64 | # services.picom.settings.blur.method = "dual_kawase"; 65 | # services.picom.settings.blur.strength = 4; 66 | # services.picom.settings.blur.background = true; 67 | 68 | # services.picom.settings.blur-background-exclude = [ 69 | # "window_type = 'dock'" 70 | # "window_type = 'desktop'" 71 | # "window_type = 'notification'" 72 | # ]; 73 | 74 | # services.picom.settings.detect-rounded-corners = true; 75 | # services.picom.settings.detect-client-opacity = true; 76 | # services.picom.settings.use-ewmh-active-win = true; 77 | # services.picom.settings.detect-transient = true; 78 | # services.picom.settings.use-damage = true; 79 | # services.picom.settings.log-level = "warn"; 80 | } 81 | -------------------------------------------------------------------------------- /nix/portal.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | # home.file.".config/xdg-desktop-portal/portals/luajit.portal".source = 4 | # ../dotfiles/xdg-desktop-portal/portals/luajit.portal; 5 | 6 | home.file.".config/xdg-desktop-portal/portals/luajit.portal".text = '' 7 | [portal] 8 | DBusName=org.freedesktop.impl.portal.desktop.luajit 9 | Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Settings;org.freedesktop.impl.portal.Wallpaper; 10 | UseIn=none+awesome 11 | ''; 12 | # https://apps.gnome.org/en/Junction/ 13 | xdg.portal.enable = true; 14 | xdg.portal.xdgOpenUsePortal = true; 15 | 16 | xdg.portal.extraPortals = with pkgs; [ 17 | xdg-desktop-portal-gtk 18 | xdg-desktop-portal-gnome 19 | ]; 20 | 21 | xdg.portal.config.common = { 22 | default = [ "gtk" ]; 23 | }; 24 | 25 | xdg.portal.config.gnome = { 26 | default = [ 27 | "gnome" 28 | "gtk" 29 | ]; 30 | }; 31 | 32 | xdg.portal.config."nome+awesome" = { 33 | default = [ 34 | "luajit" 35 | "gtk" 36 | ]; 37 | "org.freedesktop.impl.portal.FileChooser" = [ "nautilus" ]; 38 | # "org.freedesktop.impl.portal.Wallpaper" = [ "luajit" ]; 39 | # "org.freedesktop.impl.portal.ScreenCast" = [ "luajit" ]; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /nix/spotify.nix: -------------------------------------------------------------------------------- 1 | { pkgs, inputs, ... }: 2 | 3 | { 4 | 5 | programs.spicetify = 6 | let 7 | sPkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system}; 8 | in 9 | { 10 | enable = true; 11 | theme = sPkgs.themes.catppuccin; 12 | }; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /nix/wezterm.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | programs.wezterm.enable = true; 5 | programs.wezterm.extraConfig = builtins.readFile ../dotfiles/wezterm/wezterm.lua; 6 | 7 | programs.wezterm.colorSchemes.oxocarbon-dark = { 8 | background = "#161616"; 9 | foreground = "#ffffff"; 10 | cursor_bg = "#ffffff"; 11 | cursor_border = "#ffffff"; 12 | cursor_fg = "#161616"; 13 | ansi = [ 14 | "#262626" 15 | "#ee5396" 16 | "#42be65" 17 | "#ffe97b" 18 | "#33b1ff" 19 | "#ff7eb6" 20 | "#3ddbd9" 21 | "#dde1e6" 22 | ]; 23 | brights = [ 24 | "#393939" 25 | "#ee5396" 26 | "#42be65" 27 | "#ffe97b" 28 | "#33b1ff" 29 | "#ff7eb6" 30 | "#3ddbd9" 31 | "#ffffff" 32 | ]; 33 | tab_bar = { 34 | background = "#262626"; 35 | active_tab = { 36 | bg_color = "#161616"; 37 | fg_color = "#ffffff"; 38 | }; 39 | inactive_tab = { 40 | bg_color = "#262626"; 41 | fg_color = "#ffffff"; 42 | }; 43 | new_tab = { 44 | bg_color = "#262626"; 45 | fg_color = "#ffffff"; 46 | }; 47 | }; 48 | }; 49 | } 50 | --------------------------------------------------------------------------------