├── custom ├── file.lua ├── inspect.lua ├── log.lua ├── obsidian.lua ├── plugins │ └── yt-music.lua ├── setup.lua ├── tbl.lua ├── theme.lua ├── theme │ ├── bottombar.lua │ ├── constants.lua │ ├── icons │ │ ├── ac.png │ │ ├── awesome.png │ │ ├── battery.png │ │ ├── battery_empty.png │ │ ├── battery_low.png │ │ ├── brightness.png │ │ ├── cpu.png │ │ ├── floating.png │ │ ├── fwd.png │ │ ├── hdd.png │ │ ├── mail.png │ │ ├── mail_on.png │ │ ├── mem.png │ │ ├── net.png │ │ ├── next.png │ │ ├── note.png │ │ ├── note_on.png │ │ ├── pacman.png │ │ ├── pause.png │ │ ├── phones.png │ │ ├── play.png │ │ ├── prev.png │ │ ├── rwd.png │ │ ├── scissors.png │ │ ├── square_sel.png │ │ ├── square_unsel.png │ │ ├── stop.png │ │ ├── submenu.png │ │ ├── task.png │ │ ├── temp.png │ │ ├── tile.png │ │ ├── tilebottom.png │ │ ├── tileleft.png │ │ ├── tiletop.png │ │ └── titlebar │ │ │ ├── close_focus.png │ │ │ ├── close_normal.png │ │ │ ├── floating_focus_active.png │ │ │ ├── floating_focus_inactive.png │ │ │ ├── floating_normal_active.png │ │ │ ├── floating_normal_inactive.png │ │ │ ├── maximized_focus_active.png │ │ │ ├── maximized_focus_inactive.png │ │ │ ├── maximized_normal_active.png │ │ │ ├── maximized_normal_inactive.png │ │ │ ├── ontop_focus_active.png │ │ │ ├── ontop_focus_inactive.png │ │ │ ├── ontop_normal_active.png │ │ │ ├── ontop_normal_inactive.png │ │ │ ├── sticky_focus_active.png │ │ │ ├── sticky_focus_inactive.png │ │ │ ├── sticky_normal_active.png │ │ │ └── sticky_normal_inactive.png │ └── sidebar.lua ├── types.lua ├── volume.lua └── widgets │ ├── mem.lua │ └── menu.lua ├── rc.lua └── stylua.toml /custom/file.lua: -------------------------------------------------------------------------------- 1 | local lfs = require "lfs" 2 | local file = {} 3 | 4 | file.write = function(name, contents) 5 | local f = assert(io.open(name, "w"), "File must be writable") 6 | f:write(contents) 7 | f:close() 8 | end 9 | 10 | file.exists = function(filepath) 11 | local attr = lfs.attributes(filepath) 12 | return attr ~= nil and attr.mode == "file" 13 | end 14 | 15 | return file 16 | -------------------------------------------------------------------------------- /custom/inspect.lua: -------------------------------------------------------------------------------- 1 | local inspect = { 2 | _VERSION = "inspect.lua 3.1.0", 3 | _URL = "http://github.com/kikito/inspect.lua", 4 | _DESCRIPTION = "human-readable representations of tables", 5 | _LICENSE = [[ 6 | MIT LICENSE 7 | 8 | Copyright (c) 2013 Enrique García Cota 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the 12 | "Software"), to deal in the Software without restriction, including 13 | without limitation the rights to use, copy, modify, merge, publish, 14 | distribute, sublicense, and/or sell copies of the Software, and to 15 | permit persons to whom the Software is furnished to do so, subject to 16 | the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included 19 | in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 25 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | ]], 29 | } 30 | 31 | local tostring = tostring 32 | 33 | inspect.KEY = setmetatable({}, { __tostring = function() 34 | return "inspect.KEY" 35 | end }) 36 | inspect.METATABLE = setmetatable({}, { __tostring = function() 37 | return "inspect.METATABLE" 38 | end }) 39 | 40 | local function rawpairs(t) 41 | return next, t, nil 42 | end 43 | 44 | -- Apostrophizes the string if it has quotes, but not aphostrophes 45 | -- Otherwise, it returns a regular quoted string 46 | local function smartQuote(str) 47 | if str:match '"' and not str:match "'" then 48 | return "'" .. str .. "'" 49 | end 50 | return '"' .. str:gsub('"', '\\"') .. '"' 51 | end 52 | 53 | -- \a => '\\a', \0 => '\\0', 31 => '\31' 54 | local shortControlCharEscapes = { 55 | ["\a"] = "\\a", 56 | ["\b"] = "\\b", 57 | ["\f"] = "\\f", 58 | ["\n"] = "\\n", 59 | ["\r"] = "\\r", 60 | ["\t"] = "\\t", 61 | ["\v"] = "\\v", 62 | } 63 | local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031 64 | for i = 0, 31 do 65 | local ch = string.char(i) 66 | if not shortControlCharEscapes[ch] then 67 | shortControlCharEscapes[ch] = "\\" .. i 68 | longControlCharEscapes[ch] = string.format("\\%03d", i) 69 | end 70 | end 71 | 72 | local function escape(str) 73 | return (str:gsub("\\", "\\\\"):gsub("(%c)%f[0-9]", longControlCharEscapes):gsub("%c", shortControlCharEscapes)) 74 | end 75 | 76 | local function isIdentifier(str) 77 | return type(str) == "string" and str:match "^[_%a][_%a%d]*$" 78 | end 79 | 80 | local function isSequenceKey(k, sequenceLength) 81 | return type(k) == "number" and 1 <= k and k <= sequenceLength and math.floor(k) == k 82 | end 83 | 84 | local defaultTypeOrders = { 85 | ["number"] = 1, 86 | ["boolean"] = 2, 87 | ["string"] = 3, 88 | ["table"] = 4, 89 | ["function"] = 5, 90 | ["userdata"] = 6, 91 | ["thread"] = 7, 92 | } 93 | 94 | local function sortKeys(a, b) 95 | local ta, tb = type(a), type(b) 96 | 97 | -- strings and numbers are sorted numerically/alphabetically 98 | if ta == tb and (ta == "string" or ta == "number") then 99 | return a < b 100 | end 101 | 102 | local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb] 103 | -- Two default types are compared according to the defaultTypeOrders table 104 | if dta and dtb then 105 | return defaultTypeOrders[ta] < defaultTypeOrders[tb] 106 | elseif dta then 107 | return true -- default types before custom ones 108 | elseif dtb then 109 | return false -- custom types after default ones 110 | end 111 | 112 | -- custom types are sorted out alphabetically 113 | return ta < tb 114 | end 115 | 116 | -- For implementation reasons, the behavior of rawlen & # is "undefined" when 117 | -- tables aren't pure sequences. So we implement our own # operator. 118 | local function getSequenceLength(t) 119 | local len = 1 120 | local v = rawget(t, len) 121 | while v ~= nil do 122 | len = len + 1 123 | v = rawget(t, len) 124 | end 125 | return len - 1 126 | end 127 | 128 | local function getNonSequentialKeys(t) 129 | local keys, keysLength = {}, 0 130 | local sequenceLength = getSequenceLength(t) 131 | for k, _ in rawpairs(t) do 132 | if not isSequenceKey(k, sequenceLength) then 133 | keysLength = keysLength + 1 134 | keys[keysLength] = k 135 | end 136 | end 137 | table.sort(keys, sortKeys) 138 | return keys, keysLength, sequenceLength 139 | end 140 | 141 | local function countTableAppearances(t, tableAppearances) 142 | tableAppearances = tableAppearances or {} 143 | 144 | if type(t) == "table" then 145 | if not tableAppearances[t] then 146 | tableAppearances[t] = 1 147 | for k, v in rawpairs(t) do 148 | countTableAppearances(k, tableAppearances) 149 | countTableAppearances(v, tableAppearances) 150 | end 151 | countTableAppearances(getmetatable(t), tableAppearances) 152 | else 153 | tableAppearances[t] = tableAppearances[t] + 1 154 | end 155 | end 156 | 157 | return tableAppearances 158 | end 159 | 160 | local copySequence = function(s) 161 | local copy, len = {}, #s 162 | for i = 1, len do 163 | copy[i] = s[i] 164 | end 165 | return copy, len 166 | end 167 | 168 | local function makePath(path, ...) 169 | local keys = { ... } 170 | local newPath, len = copySequence(path) 171 | for i = 1, #keys do 172 | newPath[len + i] = keys[i] 173 | end 174 | return newPath 175 | end 176 | 177 | local function processRecursive(process, item, path, visited) 178 | if item == nil then 179 | return nil 180 | end 181 | if visited[item] then 182 | return visited[item] 183 | end 184 | 185 | local processed = process(item, path) 186 | if type(processed) == "table" then 187 | local processedCopy = {} 188 | visited[item] = processedCopy 189 | local processedKey 190 | 191 | for k, v in rawpairs(processed) do 192 | processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) 193 | if processedKey ~= nil then 194 | processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) 195 | end 196 | end 197 | 198 | local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) 199 | if type(mt) ~= "table" then 200 | mt = nil 201 | end -- ignore not nil/table __metatable field 202 | setmetatable(processedCopy, mt) 203 | processed = processedCopy 204 | end 205 | return processed 206 | end 207 | 208 | ------------------------------------------------------------------- 209 | 210 | local Inspector = {} 211 | local Inspector_mt = { __index = Inspector } 212 | 213 | function Inspector:puts(...) 214 | local args = { ... } 215 | local buffer = self.buffer 216 | local len = #buffer 217 | for i = 1, #args do 218 | len = len + 1 219 | buffer[len] = args[i] 220 | end 221 | end 222 | 223 | function Inspector:down(f) 224 | self.level = self.level + 1 225 | f() 226 | self.level = self.level - 1 227 | end 228 | 229 | function Inspector:tabify() 230 | self:puts(self.newline, string.rep(self.indent, self.level)) 231 | end 232 | 233 | function Inspector:alreadyVisited(v) 234 | return self.ids[v] ~= nil 235 | end 236 | 237 | function Inspector:getId(v) 238 | local id = self.ids[v] 239 | if not id then 240 | local tv = type(v) 241 | id = (self.maxIds[tv] or 0) + 1 242 | self.maxIds[tv] = id 243 | self.ids[v] = id 244 | end 245 | return tostring(id) 246 | end 247 | 248 | function Inspector:putKey(k) 249 | if isIdentifier(k) then 250 | return self:puts(k) 251 | end 252 | self:puts "[" 253 | self:putValue(k) 254 | self:puts "]" 255 | end 256 | 257 | function Inspector:putTable(t) 258 | if t == inspect.KEY or t == inspect.METATABLE then 259 | self:puts(tostring(t)) 260 | elseif self:alreadyVisited(t) then 261 | self:puts("") 262 | elseif self.level >= self.depth then 263 | self:puts "{...}" 264 | else 265 | if self.tableAppearances[t] > 1 then 266 | self:puts("<", self:getId(t), ">") 267 | end 268 | 269 | local nonSequentialKeys, nonSequentialKeysLength, sequenceLength = getNonSequentialKeys(t) 270 | local mt = getmetatable(t) 271 | if vim and sequenceLength == 0 and nonSequentialKeysLength == 0 and mt == vim._empty_dict_mt then 272 | self:puts(tostring(t)) 273 | return 274 | end 275 | 276 | self:puts "{" 277 | self:down(function() 278 | local count = 0 279 | for i = 1, sequenceLength do 280 | if count > 0 then 281 | self:puts "," 282 | end 283 | self:puts " " 284 | self:putValue(t[i]) 285 | count = count + 1 286 | end 287 | 288 | for i = 1, nonSequentialKeysLength do 289 | local k = nonSequentialKeys[i] 290 | if count > 0 then 291 | self:puts "," 292 | end 293 | self:tabify() 294 | self:putKey(k) 295 | self:puts " = " 296 | self:putValue(t[k]) 297 | count = count + 1 298 | end 299 | 300 | if type(mt) == "table" then 301 | if count > 0 then 302 | self:puts "," 303 | end 304 | self:tabify() 305 | self:puts " = " 306 | self:putValue(mt) 307 | end 308 | end) 309 | 310 | if nonSequentialKeysLength > 0 or type(mt) == "table" then -- result is multi-lined. Justify closing } 311 | self:tabify() 312 | elseif sequenceLength > 0 then -- array tables have one extra space before closing } 313 | self:puts " " 314 | end 315 | 316 | self:puts "}" 317 | end 318 | end 319 | 320 | function Inspector:putValue(v) 321 | local tv = type(v) 322 | 323 | if tv == "string" then 324 | self:puts(smartQuote(escape(v))) 325 | elseif 326 | tv == "number" 327 | or tv == "boolean" 328 | or tv == "nil" 329 | or tv == "cdata" 330 | or tv == "ctype" 331 | or (vim and v == vim.NIL) 332 | then 333 | self:puts(tostring(v)) 334 | elseif tv == "table" then 335 | self:putTable(v) 336 | else 337 | self:puts("<", tv, " ", self:getId(v), ">") 338 | end 339 | end 340 | 341 | ------------------------------------------------------------------- 342 | 343 | function inspect.inspect(root, options) 344 | options = options or {} 345 | 346 | local depth = options.depth or math.huge 347 | local newline = options.newline or "\n" 348 | local indent = options.indent or " " 349 | local process = options.process 350 | 351 | if process then 352 | root = processRecursive(process, root, {}, {}) 353 | end 354 | 355 | local inspector = setmetatable({ 356 | depth = depth, 357 | level = 0, 358 | buffer = {}, 359 | ids = {}, 360 | maxIds = {}, 361 | newline = newline, 362 | indent = indent, 363 | tableAppearances = countTableAppearances(root), 364 | }, Inspector_mt) 365 | 366 | inspector:putValue(root) 367 | 368 | return table.concat(inspector.buffer) 369 | end 370 | 371 | setmetatable(inspect, { __call = function(_, ...) 372 | return inspect.inspect(...) 373 | end }) 374 | 375 | return inspect 376 | -------------------------------------------------------------------------------- /custom/log.lua: -------------------------------------------------------------------------------- 1 | -- log.lua 2 | -- 3 | -- Inspired by rxi/log.lua 4 | -- Modified by tjdevries and can be found at github.com/tjdevries/vlog.nvim 5 | -- 6 | -- Copied from plenary as well. 7 | -- 8 | -- This library is free software; you can redistribute it and/or modify it 9 | -- under the terms of the MIT license. See LICENSE for details. 10 | 11 | local tbl = require "custom.tbl" 12 | local inspect = require "custom.inspect" 13 | 14 | -- User configuration section 15 | local default_config = { 16 | -- Name of the plugin. Prepended to log messages 17 | plugin = "plenary", 18 | 19 | -- Should highlighting be used in console (using echohl) 20 | highlights = true, 21 | 22 | -- Should write to a file 23 | use_file = true, 24 | 25 | -- Any messages above this level will be logged. 26 | level = "info", 27 | 28 | -- Level configuration 29 | modes = { 30 | { name = "trace", hl = "Comment" }, 31 | { name = "debug", hl = "Comment" }, 32 | { name = "info", hl = "None" }, 33 | { name = "warn", hl = "WarningMsg" }, 34 | { name = "error", hl = "ErrorMsg" }, 35 | { name = "fatal", hl = "ErrorMsg" }, 36 | }, 37 | 38 | -- Can limit the number of decimals displayed for floats 39 | float_precision = 0.01, 40 | } 41 | 42 | -- {{{ NO NEED TO CHANGE 43 | local log = {} 44 | 45 | local unpack = unpack or table.unpack 46 | 47 | log.new = function(config, standalone) 48 | config = tbl.tbl_deep_extend("force", default_config, config) 49 | 50 | local outfile = "/home/tjdevries/.cache/awesome.log" 51 | 52 | local obj 53 | if standalone then 54 | obj = log 55 | else 56 | obj = config 57 | end 58 | 59 | local levels = {} 60 | for i, v in ipairs(config.modes) do 61 | levels[v.name] = i 62 | end 63 | 64 | local round = function(x, increment) 65 | increment = increment or 1 66 | x = x / increment 67 | return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment 68 | end 69 | 70 | local make_string = function(...) 71 | local t = {} 72 | for i = 1, select("#", ...) do 73 | local x = select(i, ...) 74 | 75 | if type(x) == "number" and config.float_precision then 76 | x = tostring(round(x, config.float_precision)) 77 | elseif type(x) == "table" then 78 | x = inspect(x) 79 | else 80 | x = tostring(x) 81 | end 82 | 83 | t[#t + 1] = x 84 | end 85 | return table.concat(t, " ") 86 | end 87 | 88 | local log_at_level = function(level, level_config, message_maker, ...) 89 | -- Return early if we're below the config.level 90 | if level < levels[config.level] then 91 | return 92 | end 93 | local nameupper = level_config.name:upper() 94 | 95 | local msg = message_maker(...) 96 | local info = debug.getinfo(config.info_level or 2, "Sl") 97 | local lineinfo = info.short_src .. ":" .. info.currentline 98 | 99 | -- Output to log file 100 | if config.use_file then 101 | local fp = assert(io.open(outfile, "a")) 102 | local str = string.format("[%-6s%s] %s: %s\n", nameupper, os.date(), lineinfo, msg) 103 | fp:write(str) 104 | fp:close() 105 | end 106 | end 107 | 108 | for i, x in ipairs(config.modes) do 109 | -- log.info("these", "are", "separated") 110 | obj[x.name] = function(...) 111 | return log_at_level(i, x, make_string, ...) 112 | end 113 | 114 | -- log.fmt_info("These are %s strings", "formatted") 115 | obj[("fmt_%s"):format(x.name)] = function(...) 116 | return log_at_level(i, x, function(...) 117 | local passed = { ... } 118 | local fmt = table.remove(passed, 1) 119 | local inspected = {} 120 | for _, v in ipairs(passed) do 121 | table.insert(inspected, inspect(v)) 122 | end 123 | return string.format(fmt, unpack(inspected)) 124 | end, ...) 125 | end 126 | 127 | -- log.lazy_info(expensive_to_calculate) 128 | obj[("lazy_%s"):format(x.name)] = function() 129 | return log_at_level(i, x, function(f) 130 | return f() 131 | end) 132 | end 133 | end 134 | 135 | return obj 136 | end 137 | 138 | log.new(default_config, true) 139 | -- }}} 140 | 141 | return log 142 | -------------------------------------------------------------------------------- /custom/obsidian.lua: -------------------------------------------------------------------------------- 1 | local awful = require "awful" 2 | 3 | local M = {} 4 | 5 | M.setup = function() 6 | client.connect_signal("property::name", function(c) 7 | if c.name == "edit-obisidian" then 8 | c.floating = true 9 | -- vertical monitor to the left, 0,0 10 | -- 3840 by 2160 11 | -- 2160 x 3840 12 | -- local screen_geometry = c.screen.geometry 13 | local width = 2500 14 | local height = 1800 15 | -- local x = 2160 + ((3840 - width) / 2) 16 | -- local y = (3840 - (2160 / 2)) + ((2160 - height) / 2) 17 | c:geometry { width = width, height = height } 18 | awful.placement.centered(c) 19 | end 20 | end) 21 | end 22 | 23 | --- Focus The Obsidian Client 24 | ---@param c Awesome.client 25 | M.focus = function(c) 26 | -- Move to the current screen/tag 27 | c:move_to_screen(awful.screen.focused()) 28 | c:move_to_tag(awful.screen.focused().selected_tag) 29 | 30 | -- Make floating/on top, not maximized/fullscreen 31 | c.floating = true 32 | c.ontop = true 33 | c.minimized = false 34 | c.maximized = false 35 | c.fullscreen = false 36 | 37 | -- Calculate 80% geometry and center it 38 | local s = awful.screen.focused() 39 | local wa = s.workarea 40 | local new_width = math.floor(wa.width * 0.8) 41 | local new_height = math.floor(wa.height * 0.8) 42 | local new_x = wa.x + (wa.width - new_width) / 2 43 | local new_y = wa.y + (wa.height - new_height) / 2 44 | 45 | c:geometry { 46 | x = new_x, 47 | y = new_y, 48 | width = new_width, 49 | height = new_height, 50 | } 51 | 52 | -- Raise and focus 53 | c:raise() 54 | client.focus = c 55 | end 56 | 57 | M.spawn = function(vault) 58 | awful.spawn(("obsidian %s"):format(vault)) 59 | end 60 | 61 | return M 62 | -------------------------------------------------------------------------------- /custom/plugins/yt-music.lua: -------------------------------------------------------------------------------- 1 | -- I have a YT Music thing installed from here, could be fun to create some shortcuts for this. 2 | -- https://github.com/th-ch/youtube-music/blob/master/src/plugins/api-server/backend/routes/control.ts 3 | -------------------------------------------------------------------------------- /custom/setup.lua: -------------------------------------------------------------------------------- 1 | local awesome = awesome or {} 2 | local naughty = require "naughty" 3 | 4 | -- Check if awesome encountered an error during startup and fell back to 5 | -- another config (This code will only ever execute for the fallback config) 6 | if awesome.startup_errors then 7 | naughty.notify { 8 | preset = naughty.config.presets.critical, 9 | title = "Oops, there were errors during startup!", 10 | text = awesome.startup_errors, 11 | } 12 | end 13 | 14 | do 15 | local in_error = false 16 | awesome.connect_signal("debug::error", function(err) 17 | if in_error then 18 | return 19 | end 20 | in_error = true 21 | 22 | naughty.notify { 23 | preset = naughty.config.presets.critical, 24 | title = "Oops, an error happened!", 25 | text = tostring(err), 26 | } 27 | in_error = false 28 | end) 29 | end 30 | -------------------------------------------------------------------------------- /custom/tbl.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.tbl_islist(t) 4 | if type(t) ~= "table" then 5 | return false 6 | end 7 | 8 | local count = 0 9 | 10 | for k, _ in pairs(t) do 11 | if type(k) == "number" then 12 | count = count + 1 13 | else 14 | return false 15 | end 16 | end 17 | 18 | if count > 0 then 19 | return true 20 | else 21 | return false 22 | end 23 | end 24 | 25 | local function tbl_extend(behavior, deep_extend, ...) 26 | if behavior ~= "error" and behavior ~= "keep" and behavior ~= "force" then 27 | error('invalid "behavior": ' .. tostring(behavior)) 28 | end 29 | 30 | if select("#", ...) < 2 then 31 | error("wrong number of arguments (given " .. tostring(1 + select("#", ...)) .. ", expected at least 3)") 32 | end 33 | 34 | local ret = {} 35 | for i = 1, select("#", ...) do 36 | local tbl = select(i, ...) 37 | if tbl then 38 | for k, v in pairs(tbl) do 39 | if type(v) == "table" and deep_extend and not M.tbl_islist(v) then 40 | ret[k] = tbl_extend(behavior, true, ret[k] or {}, v) 41 | elseif behavior ~= "force" and ret[k] ~= nil then 42 | if behavior == "error" then 43 | error("key found in more than one map: " .. k) 44 | end -- Else behavior is "keep". 45 | else 46 | ret[k] = v 47 | end 48 | end 49 | end 50 | end 51 | return ret 52 | end 53 | 54 | --- Merges two or more map-like tables. 55 | --- 56 | --@see |extend()| 57 | --- 58 | --@param behavior Decides what to do if a key is found in more than one map: 59 | --- - "error": raise an error 60 | --- - "keep": use value from the leftmost map 61 | --- - "force": use value from the rightmost map 62 | --@param ... Two or more map-like tables. 63 | function M.tbl_extend(behavior, ...) 64 | return tbl_extend(behavior, false, ...) 65 | end 66 | 67 | --- Merges recursively two or more map-like tables. 68 | --- 69 | --@see |tbl_extend()| 70 | --- 71 | --@param behavior Decides what to do if a key is found in more than one map: 72 | --- - "error": raise an error 73 | --- - "keep": use value from the leftmost map 74 | --- - "force": use value from the rightmost map 75 | --@param ... Two or more map-like tables. 76 | function M.tbl_deep_extend(behavior, ...) 77 | return tbl_extend(behavior, true, ...) 78 | end 79 | 80 | return M 81 | -------------------------------------------------------------------------------- /custom/theme.lua: -------------------------------------------------------------------------------- 1 | local log = require "custom.log" 2 | 3 | local beautiful = require "beautiful" 4 | local gears = require "gears" 5 | local awful = require "awful" 6 | local wibox = require "wibox" 7 | local dpi = require("beautiful.xresources").apply_dpi 8 | local mouse = require("custom.theme.constants").mouse 9 | local mods = require("custom.theme.constants").mods 10 | 11 | local theme = {} 12 | theme.dir = os.getenv "HOME" .. "/.config/awesome/custom/theme" 13 | theme.wallpaper = theme.dir .. "/wall.png" 14 | theme.font = "Fira Sans 9" 15 | theme.useless_gap = 0 16 | 17 | local gray = { 18 | "#111111", 19 | "#282a2e", 20 | "#373b41", 21 | "#969896", 22 | "#b4b7b4", 23 | "#c5c8c6", 24 | "#e0e0e0", 25 | "#ffffff", 26 | } 27 | 28 | -- theme.bg_normal = "#111111" 29 | -- theme.fg_normal = "#FEFEFE" 30 | -- theme.bg_normal = "#222222" 31 | -- theme.bg_focus = "#535d6c" 32 | theme.bg_normal = "#222222" 33 | theme.bg_focus = "#535d6c" 34 | theme.bg_urgent = "#ff0000" 35 | theme.bg_minimize = "#444444" 36 | theme.bg_systray = theme.bg_normal 37 | 38 | theme.bg_urgent = "#FF0000" 39 | theme.fg_urgent = "#000000" 40 | 41 | theme.bg_focus = "#FFFFFF" 42 | theme.fg_focus = "#111111" 43 | 44 | theme.taglist_fg_focus = gray[3] 45 | -- theme.taglist_bg_focus = "#00CCFF" 46 | 47 | theme.bg_normal = "#222222" 48 | theme.bg_focus = "#535d6c" 49 | -- theme.tasklist_bg_normal = "#000000" 50 | theme.tasklist_fg_normal = gray[4] 51 | -- theme.tasklist_bg_focus = gray[2] 52 | theme.tasklist_fg_focus = gray[7] 53 | -- theme.tasklist_bg_urgent = "#282a2e" 54 | theme.tasklist_fg_urgent = "#00CCFF" 55 | 56 | theme.titlebar_bg_focus = "#3F3F3F" 57 | theme.titlebar_bg_normal = "#3F3F3F" 58 | theme.titlebar_bg_focus = theme.bg_focus 59 | theme.titlebar_bg_normal = theme.bg_normal 60 | theme.titlebar_fg_focus = theme.fg_focus 61 | 62 | theme.border_width = dpi(2) 63 | theme.border_normal = "#3F3F3F" 64 | theme.border_focus = "#6F6F6F" 65 | theme.border_marked = "#CC9393" 66 | 67 | theme.menu_height = dpi(16) 68 | theme.menu_width = dpi(140) 69 | theme.menu_submenu_icon = theme.dir .. "/icons/submenu.png" 70 | 71 | theme.awesome_icon = theme.dir .. "/icons/awesome.png" 72 | theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png" 73 | theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png" 74 | theme.layout_tile = theme.dir .. "/icons/tile.png" 75 | theme.layout_tileleft = theme.dir .. "/icons/tileleft.png" 76 | theme.layout_tilebottom = theme.dir .. "/icons/tilebottom.png" 77 | theme.layout_tiletop = theme.dir .. "/icons/tiletop.png" 78 | theme.layout_fairv = theme.dir .. "/icons/fairv.png" 79 | theme.layout_fairh = theme.dir .. "/icons/fairh.png" 80 | theme.layout_spiral = theme.dir .. "/icons/spiral.png" 81 | theme.layout_dwindle = theme.dir .. "/icons/dwindle.png" 82 | theme.layout_max = theme.dir .. "/icons/max.png" 83 | theme.layout_fullscreen = theme.dir .. "/icons/fullscreen.png" 84 | theme.layout_magnifier = theme.dir .. "/icons/magnifier.png" 85 | theme.layout_floating = theme.dir .. "/icons/floating.png" 86 | theme.widget_ac = theme.dir .. "/icons/ac.png" 87 | theme.widget_battery = theme.dir .. "/icons/battery.png" 88 | theme.widget_battery_low = theme.dir .. "/icons/battery_low.png" 89 | theme.widget_battery_empty = theme.dir .. "/icons/battery_empty.png" 90 | theme.widget_brightness = theme.dir .. "/icons/brightness.png" 91 | theme.widget_mem = theme.dir .. "/icons/mem.png" 92 | theme.widget_cpu = theme.dir .. "/icons/cpu.png" 93 | theme.widget_temp = theme.dir .. "/icons/temp.png" 94 | theme.widget_net = theme.dir .. "/icons/net.png" 95 | theme.widget_hdd = theme.dir .. "/icons/hdd.png" 96 | theme.widget_music = theme.dir .. "/icons/note.png" 97 | theme.widget_music_on = theme.dir .. "/icons/note_on.png" 98 | theme.widget_music_pause = theme.dir .. "/icons/pause.png" 99 | theme.widget_music_stop = theme.dir .. "/icons/stop.png" 100 | theme.widget_vol = theme.dir .. "/icons/vol.png" 101 | theme.widget_vol_low = theme.dir .. "/icons/vol_low.png" 102 | theme.widget_vol_no = theme.dir .. "/icons/vol_no.png" 103 | theme.widget_vol_mute = theme.dir .. "/icons/vol_mute.png" 104 | theme.widget_mail = theme.dir .. "/icons/mail.png" 105 | theme.widget_mail_on = theme.dir .. "/icons/mail_on.png" 106 | theme.widget_task = theme.dir .. "/icons/task.png" 107 | theme.widget_scissors = theme.dir .. "/icons/scissors.png" 108 | theme.tasklist_plain_task_name = false 109 | theme.tasklist_disable_icon = false 110 | theme.titlebar_close_button_focus = theme.dir .. "/icons/titlebar/close_focus.png" 111 | theme.titlebar_close_button_normal = theme.dir .. "/icons/titlebar/close_normal.png" 112 | theme.titlebar_ontop_button_focus_active = theme.dir .. "/icons/titlebar/ontop_focus_active.png" 113 | theme.titlebar_ontop_button_normal_active = theme.dir .. "/icons/titlebar/ontop_normal_active.png" 114 | theme.titlebar_ontop_button_focus_inactive = theme.dir .. "/icons/titlebar/ontop_focus_inactive.png" 115 | theme.titlebar_ontop_button_normal_inactive = theme.dir .. "/icons/titlebar/ontop_normal_inactive.png" 116 | theme.titlebar_sticky_button_focus_active = theme.dir .. "/icons/titlebar/sticky_focus_active.png" 117 | theme.titlebar_sticky_button_normal_active = theme.dir .. "/icons/titlebar/sticky_normal_active.png" 118 | theme.titlebar_sticky_button_focus_inactive = theme.dir .. "/icons/titlebar/sticky_focus_inactive.png" 119 | theme.titlebar_sticky_button_normal_inactive = theme.dir .. "/icons/titlebar/sticky_normal_inactive.png" 120 | theme.titlebar_floating_button_focus_active = theme.dir .. "/icons/titlebar/floating_focus_active.png" 121 | theme.titlebar_floating_button_normal_active = theme.dir .. "/icons/titlebar/floating_normal_active.png" 122 | theme.titlebar_floating_button_focus_inactive = theme.dir .. "/icons/titlebar/floating_focus_inactive.png" 123 | theme.titlebar_floating_button_normal_inactive = theme.dir .. "/icons/titlebar/floating_normal_inactive.png" 124 | theme.titlebar_maximized_button_focus_active = theme.dir .. "/icons/titlebar/maximized_focus_active.png" 125 | theme.titlebar_maximized_button_normal_active = theme.dir .. "/icons/titlebar/maximized_normal_active.png" 126 | theme.titlebar_maximized_button_focus_inactive = theme.dir .. "/icons/titlebar/maximized_focus_inactive.png" 127 | theme.titlebar_maximized_button_normal_inactive = theme.dir .. "/icons/titlebar/maximized_normal_inactive.png" 128 | 129 | -- local mylauncher = awful.widget.launcher { image = beautiful.awesome_icon, menu = my_main_menu } 130 | local text_clock = wibox.widget.textclock " %I:%M %p " 131 | -- mytextclock:set_font "Berkeley Mono" 132 | 133 | -- local markup = lain.util.markup 134 | -- local separators = lain.util.separators 135 | 136 | -- -- ALSA volume 137 | -- theme.volume = lain.widget.alsabar { 138 | -- --togglechannel = "IEC958,3", 139 | -- notification_preset = { font = "sans 10", fg = theme.fg_normal }, 140 | -- } 141 | 142 | -- -- MPD 143 | -- local musicplr = (awful.util.terminal or "ghostty") .. " -title Music -g 130x34-320+16 -e ncmpcpp" 144 | -- local mpdicon = wibox.widget.imagebox(theme.widget_music) 145 | -- mpdicon:buttons(gears.table.join( 146 | -- awful.button({ modkey }, 1, function() 147 | -- awful.spawn.with_shell(musicplr) 148 | -- end), 149 | -- awful.button({}, 1, function() 150 | -- os.execute "mpc prev" 151 | -- theme.mpd.update() 152 | -- end), 153 | -- awful.button({}, 2, function() 154 | -- os.execute "mpc toggle" 155 | -- theme.mpd.update() 156 | -- end), 157 | -- awful.button({}, 3, function() 158 | -- os.execute "mpc next" 159 | -- theme.mpd.update() 160 | -- end) 161 | -- )) 162 | -- theme.mpd = lain.widget.mpd { 163 | -- settings = function() 164 | -- if mpd_now.state == "play" then 165 | -- local artist = " " .. mpd_now.artist .. " " 166 | -- local title = mpd_now.title .. " " 167 | -- mpdicon:set_image(theme.widget_music_on) 168 | -- widget:set_markup(markup.font(theme.font, markup("#FF8466", artist) .. " " .. title)) 169 | -- elseif mpd_now.state == "pause" then 170 | -- widget:set_markup(markup.font(theme.font, " mpd paused ")) 171 | -- mpdicon:set_image(theme.widget_music_pause) 172 | -- else 173 | -- widget:set_text "" 174 | -- mpdicon:set_image(theme.widget_music) 175 | -- end 176 | -- end, 177 | -- } 178 | 179 | local function set_wallpaper(s) 180 | if beautiful.wallpaper then 181 | local wallpaper = beautiful.wallpaper 182 | if type(wallpaper) == "function" then 183 | wallpaper = wallpaper(s) 184 | end 185 | gears.wallpaper.maximized(wallpaper, s, true) 186 | end 187 | end 188 | 189 | -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution) 190 | screen.connect_signal("property::geometry", set_wallpaper) 191 | 192 | function theme.at_screen_connect(s) 193 | -- Quake application 194 | -- s.quake = lain.util.quake { app = awful.util.terminal } 195 | 196 | set_wallpaper(s) 197 | 198 | -- Each screen has its own tag table. 199 | local screen_layout = awful.layout.layouts[1] 200 | if s.index == 1 then 201 | screen_layout = awful.layout.suit.tile.bottom 202 | end 203 | 204 | awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, screen_layout) 205 | 206 | -- Create an imagebox widget which will contains an icon indicating which layout we're using. 207 | -- We need one layoutbox per screen. 208 | s.mylayoutbox = awful.widget.layoutbox(s) 209 | s.mylayoutbox:buttons(gears.table.join( 210 | awful.button({}, 1, function() 211 | awful.layout.inc(1) 212 | end), 213 | awful.button({}, 2, function() 214 | awful.layout.set(awful.layout.layouts[1]) 215 | end), 216 | awful.button({}, 3, function() 217 | awful.layout.inc(-1) 218 | end), 219 | awful.button({}, 4, function() 220 | awful.layout.inc(1) 221 | end), 222 | awful.button({}, 5, function() 223 | awful.layout.inc(-1) 224 | end) 225 | )) 226 | -- Create a taglist widget 227 | local taglist_buttons = gears.table.join( 228 | awful.button({}, mouse.left, function(t) 229 | t:view_only() 230 | end), 231 | awful.button({ mods.super }, mouse.left, function(t) 232 | if client.focus then 233 | client.focus:move_to_tag(t) 234 | end 235 | end), 236 | awful.button({}, mouse.right, awful.tag.viewtoggle), 237 | awful.button({ mods.super }, mouse.right, function(t) 238 | if client.focus then 239 | client.focus:toggle_tag(t) 240 | end 241 | end) 242 | ) 243 | s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons) 244 | 245 | -- Create a tasklist widget 246 | local tasklist_buttons = gears.table.join( 247 | awful.button({}, 1, function(c) 248 | if c == client.focus then 249 | c.minimized = true 250 | else 251 | c:emit_signal("request::activate", "tasklist", { raise = true }) 252 | end 253 | end), 254 | awful.button({}, 3, function() 255 | awful.menu.client_list { theme = { width = 250 } } 256 | end), 257 | awful.button({}, 4, function() 258 | awful.client.focus.byidx(1) 259 | end), 260 | awful.button({}, 5, function() 261 | awful.client.focus.byidx(-1) 262 | end) 263 | ) 264 | 265 | s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons) 266 | 267 | -- Create the wibox 268 | s.mywibox = awful.wibar { position = "top", screen = s, height = dpi(16), bg = theme.bg_normal, fg = theme.fg_normal } 269 | 270 | -- Add widgets to the wibox 271 | s.mywibox:setup { 272 | layout = wibox.layout.align.horizontal, 273 | { -- Left widgets 274 | layout = wibox.layout.fixed.horizontal, 275 | --spr, 276 | s.mytaglist, 277 | s.mypromptbox, 278 | }, 279 | s.mytasklist, -- Middle widget 280 | { -- Right widgets 281 | layout = wibox.layout.fixed.horizontal, 282 | wibox.widget.systray(), 283 | -- using separators 284 | -- arrow("#343434", theme.bg_normal), 285 | -- wibox.container.background( 286 | -- wibox.container.margin( 287 | -- wibox.widget { 288 | -- mpdicon, 289 | -- theme.mpd.widget, 290 | -- layout = wibox.layout.align.horizontal, 291 | -- }, 292 | -- dpi(3), 293 | -- dpi(6) 294 | -- ), 295 | -- theme.bg_focus 296 | -- ), 297 | -- arrow(theme.bg_normal, "#777E76"), 298 | -- wibox.container.background( 299 | -- wibox.container.margin( 300 | -- wibox.widget { 301 | -- memicon, 302 | -- mem.widget, 303 | -- layout = wibox.layout.align.horizontal, 304 | -- }, 305 | -- dpi(2), 306 | -- dpi(3) 307 | -- ), 308 | -- "#777E76" 309 | -- ), 310 | -- arrow("#777E76", "#4B696D"), 311 | -- wibox.container.background( 312 | -- wibox.container.margin( 313 | -- wibox.widget { 314 | -- cpuicon, 315 | -- cpu.widget, 316 | -- layout = wibox.layout.align.horizontal, 317 | -- }, 318 | -- dpi(3), 319 | -- dpi(4) 320 | -- ), 321 | -- "#4B696D" 322 | -- ), 323 | -- arrow("#8DAA9A", "#C0C0A2"), 324 | -- wibox.container.background( 325 | -- wibox.container.margin( 326 | -- wibox.widget { 327 | -- nil, 328 | -- neticon, 329 | -- net.widget, 330 | -- layout = wibox.layout.align.horizontal, 331 | -- }, 332 | -- dpi(3), 333 | -- dpi(3) 334 | -- ), 335 | -- "#C0C0A2" 336 | -- ), 337 | text_clock, 338 | --]] 339 | s.mylayoutbox, 340 | }, 341 | } 342 | end 343 | 344 | return theme 345 | -------------------------------------------------------------------------------- /custom/theme/bottombar.lua: -------------------------------------------------------------------------------- 1 | local awful = require "awful" 2 | local dpi = require("beautiful.xresources").apply_dpi 3 | local wibox = require "wibox" 4 | 5 | local M = {} 6 | 7 | --- On Screen Connect 8 | ---@param s Awesome.screen 9 | M.at_screen_connect = function(s) 10 | -- Create the bottom wibox 11 | local mybottomwibox = awful.wibar { 12 | position = "bottom", 13 | screen = s, 14 | border_width = dpi(0), 15 | height = dpi(32), 16 | } 17 | 18 | local borderwibox = 19 | awful.wibar { position = "bottom", screen = s, height = dpi(1), bg = theme.fg_focus, x = dpi(0), y = dpi(33) } 20 | 21 | -- Add widgets to the bottom wibox 22 | mybottomwibox:setup { 23 | layout = wibox.layout.align.horizontal, 24 | { -- Left widgets 25 | layout = wibox.layout.fixed.horizontal, 26 | mylauncher, 27 | }, 28 | s.mytasklist, -- Middle widget 29 | { -- Right widgets 30 | layout = wibox.layout.fixed.horizontal, 31 | spr_bottom_right, 32 | netdown_icon, 33 | networkwidget, 34 | netup_icon, 35 | bottom_bar, 36 | cpu_icon, 37 | cpuwidget, 38 | bottom_bar, 39 | calendar_icon, 40 | calendarwidget, 41 | bottom_bar, 42 | clock_icon, 43 | clockwidget, 44 | }, 45 | } 46 | end 47 | 48 | return M 49 | -------------------------------------------------------------------------------- /custom/theme/constants.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.mouse = {} 4 | M.mouse.left = 1 5 | M.mouse.right = 3 6 | M.mouse.wheel = 2 7 | M.mouse.up = 4 8 | M.mouse.down = 5 9 | 10 | M.mods = {} 11 | M.mods.super = "Mod4" 12 | M.mods.shift = "Shift" 13 | M.mods.control = "Control" 14 | 15 | return M 16 | -------------------------------------------------------------------------------- /custom/theme/icons/ac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/ac.png -------------------------------------------------------------------------------- /custom/theme/icons/awesome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/awesome.png -------------------------------------------------------------------------------- /custom/theme/icons/battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/battery.png -------------------------------------------------------------------------------- /custom/theme/icons/battery_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/battery_empty.png -------------------------------------------------------------------------------- /custom/theme/icons/battery_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/battery_low.png -------------------------------------------------------------------------------- /custom/theme/icons/brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/brightness.png -------------------------------------------------------------------------------- /custom/theme/icons/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/cpu.png -------------------------------------------------------------------------------- /custom/theme/icons/floating.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/floating.png -------------------------------------------------------------------------------- /custom/theme/icons/fwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/fwd.png -------------------------------------------------------------------------------- /custom/theme/icons/hdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/hdd.png -------------------------------------------------------------------------------- /custom/theme/icons/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/mail.png -------------------------------------------------------------------------------- /custom/theme/icons/mail_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/mail_on.png -------------------------------------------------------------------------------- /custom/theme/icons/mem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/mem.png -------------------------------------------------------------------------------- /custom/theme/icons/net.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/net.png -------------------------------------------------------------------------------- /custom/theme/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/next.png -------------------------------------------------------------------------------- /custom/theme/icons/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/note.png -------------------------------------------------------------------------------- /custom/theme/icons/note_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/note_on.png -------------------------------------------------------------------------------- /custom/theme/icons/pacman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/pacman.png -------------------------------------------------------------------------------- /custom/theme/icons/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/pause.png -------------------------------------------------------------------------------- /custom/theme/icons/phones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/phones.png -------------------------------------------------------------------------------- /custom/theme/icons/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/play.png -------------------------------------------------------------------------------- /custom/theme/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/prev.png -------------------------------------------------------------------------------- /custom/theme/icons/rwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/rwd.png -------------------------------------------------------------------------------- /custom/theme/icons/scissors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/scissors.png -------------------------------------------------------------------------------- /custom/theme/icons/square_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/square_sel.png -------------------------------------------------------------------------------- /custom/theme/icons/square_unsel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/square_unsel.png -------------------------------------------------------------------------------- /custom/theme/icons/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/stop.png -------------------------------------------------------------------------------- /custom/theme/icons/submenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/submenu.png -------------------------------------------------------------------------------- /custom/theme/icons/task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/task.png -------------------------------------------------------------------------------- /custom/theme/icons/temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/temp.png -------------------------------------------------------------------------------- /custom/theme/icons/tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/tile.png -------------------------------------------------------------------------------- /custom/theme/icons/tilebottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/tilebottom.png -------------------------------------------------------------------------------- /custom/theme/icons/tileleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/tileleft.png -------------------------------------------------------------------------------- /custom/theme/icons/tiletop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/tiletop.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/close_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/close_focus.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/close_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/close_normal.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/floating_focus_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/floating_focus_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/floating_focus_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/floating_focus_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/floating_normal_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/floating_normal_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/floating_normal_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/floating_normal_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/maximized_focus_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/maximized_focus_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/maximized_focus_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/maximized_focus_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/maximized_normal_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/maximized_normal_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/maximized_normal_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/maximized_normal_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/ontop_focus_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/ontop_focus_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/ontop_focus_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/ontop_focus_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/ontop_normal_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/ontop_normal_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/ontop_normal_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/ontop_normal_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/sticky_focus_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/sticky_focus_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/sticky_focus_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/sticky_focus_inactive.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/sticky_normal_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/sticky_normal_active.png -------------------------------------------------------------------------------- /custom/theme/icons/titlebar/sticky_normal_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjdevries/config.awesomewm/9f9ebbb7294f7487f0719669f552fe8633d647cf/custom/theme/icons/titlebar/sticky_normal_inactive.png -------------------------------------------------------------------------------- /custom/theme/sidebar.lua: -------------------------------------------------------------------------------- 1 | local gears = require "gears" 2 | 3 | local xresources = require "beautiful.xresources" 4 | local dpi = xresources.apply_dpi 5 | 6 | local barcolor = gears.color { 7 | type = "linear", 8 | from = { 0, dpi(46) }, 9 | to = { dpi(46), dpi(46) }, 10 | stops = { { 0, theme.bg_focus }, { 0.9, theme.bg_focus2 } }, 11 | } 12 | 13 | local barcolor2 = gears.color { 14 | type = "linear", 15 | from = { 0, dpi(46) }, 16 | to = { dpi(46), dpi(46) }, 17 | stops = { { 0, "#323232" }, { 1, theme.bg_normal } }, 18 | } 19 | 20 | local dockshape = function(cr, width, height) 21 | gears.shape.partially_rounded_rect(cr, width, height, false, true, true, false, 6) 22 | end 23 | 24 | function theme.vertical_wibox(s) 25 | -- Create the vertical wibox 26 | s.dockheight = (35 * s.workarea.height) / 100 27 | 28 | s.myleftwibox = wibox { 29 | screen = s, 30 | x = 0, 31 | y = s.workarea.height / 2 - s.dockheight / 2, 32 | width = dpi(6), 33 | height = s.dockheight, 34 | fg = theme.fg_normal, 35 | bg = barcolor2, 36 | ontop = true, 37 | visible = true, 38 | type = "dock", 39 | } 40 | 41 | if s.index > 1 and s.myleftwibox.y == 0 then 42 | s.myleftwibox.y = screen[1].myleftwibox.y 43 | end 44 | 45 | -- Add widgets to the vertical wibox 46 | s.myleftwibox:setup { 47 | layout = wibox.layout.align.vertical, 48 | { 49 | layout = wibox.layout.fixed.vertical, 50 | lspace1, 51 | s.mytaglist, 52 | lspace2, 53 | s.layoutb, 54 | wibox.container.margin(mylauncher, dpi(5), dpi(8), dpi(13), dpi(0)), 55 | }, 56 | } 57 | 58 | -- Add toggling functionalities 59 | s.docktimer = gears.timer { timeout = 2 } 60 | s.docktimer:connect_signal("timeout", function() 61 | local s = awful.screen.focused() 62 | s.myleftwibox.width = dpi(9) 63 | s.layoutb.visible = false 64 | mylauncher.visible = false 65 | if s.docktimer.started then 66 | s.docktimer:stop() 67 | end 68 | end) 69 | tag.connect_signal("property::selected", function(t) 70 | local s = t.screen or awful.screen.focused() 71 | s.myleftwibox.width = dpi(38) 72 | s.layoutb.visible = true 73 | mylauncher.visible = true 74 | gears.surface.apply_shape_bounding(s.myleftwibox, dockshape) 75 | if not s.docktimer.started then 76 | s.docktimer:start() 77 | end 78 | end) 79 | 80 | s.myleftwibox:connect_signal("mouse::leave", function() 81 | local s = awful.screen.focused() 82 | s.myleftwibox.width = dpi(9) 83 | s.layoutb.visible = false 84 | mylauncher.visible = false 85 | end) 86 | 87 | s.myleftwibox:connect_signal("mouse::enter", function() 88 | local s = awful.screen.focused() 89 | s.myleftwibox.width = dpi(38) 90 | s.layoutb.visible = true 91 | mylauncher.visible = true 92 | gears.surface.apply_shape_bounding(s.myleftwibox, dockshape) 93 | end) 94 | end 95 | -------------------------------------------------------------------------------- /custom/types.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | If it's obvious from the documentation that the table returns an array of a particular type, use the style of TYPE[], for example: 3 | 4 | ---@field clients fun(self: Awesome.tag): table 5 | 6 | Should instead be: 7 | 8 | ---@field clients fun(self: Awesome.tag): Awesome.client[] 9 | 10 | --]] 11 | 12 | ---@meta 13 | 14 | ---@class Awesome.screen 15 | ---@field geometry table: The screen coordinates. 16 | ---@field index integer: The internal screen number. 17 | ---@field outputs table: A list of outputs for this screen and their size in mm. 18 | ---@field workarea table: The screen workarea. 19 | ---@field padding table: The screen padding. 20 | ---@field clients Awesome.client[]: The list of visible clients for the screen. 21 | ---@field hidden_clients Awesome.client[]: The list of clients assigned to the screen but not currently visible. 22 | ---@field all_clients Awesome.client[]: All clients assigned to the screen. 23 | ---@field tiled_clients Awesome.client[]: Tiled clients for the screen. 24 | ---@field tags Awesome.tag[]: A list of all tags on the screen. 25 | ---@field selected_tags Awesome.tag[]: A list of all selected tags on the screen. 26 | ---@field selected_tag Awesome.tag: The first selected tag. 27 | ---@field dpi number: The number of pixels per inch of the screen. 28 | ---@field get_clients fun(self: Awesome.screen, stacked: boolean|nil): Awesome.client[] 29 | ---@field get_all_clients fun(self: Awesome.screen, stacked: boolean|nil): Awesome.client[] 30 | ---@field get_tiled_clients fun(self: Awesome.screen, stacked: boolean|nil): Awesome.client[] 31 | ---@field set_auto_dpi_enabled fun(self: Awesome.screen, enabled: boolean): nil 32 | ---@field connect_signal fun(self: Awesome.screen, name: string, func: fun()): nil 33 | ---@field disconnect_signal fun(self: Awesome.screen, name: string, func: fun()): nil 34 | ---@field emit_signal fun(self: Awesome.screen, name: string, ...): nil 35 | 36 | -- Signals (TODO) 37 | -- ["primary_changed"] fun(self: Awesome.screen): nil 38 | -- ["added"] fun(self: Awesome.screen): nil 39 | -- ["removed"] fun(self: Awesome.screen): nil 40 | -- ["list"] fun(self: Awesome.screen): nil 41 | -- ["swapped"] fun(self: Awesome.screen): nil 42 | -- ["tag::history::update"] fun(self: Awesome.screen): nil 43 | 44 | ---@class Awesome.tag 45 | ---@field name string: Tag name. 46 | ---@field selected boolean: True if the tag is selected to be viewed. 47 | ---@field activated boolean: True if the tag is active and can be used. 48 | ---@field index integer: The tag index. 49 | ---@field screen Awesome.screen: The tag screen. 50 | ---@field master_width_factor number: The tag master width factor. 51 | ---@field layout any: The tag client layout. 52 | ---@field layouts any[]: The list of available layouts for this tag. 53 | ---@field volatile boolean: Define if the tag must be deleted when the last client is untagged. 54 | ---@field gap number: The gap (spacing, also called useless_gap) between clients. 55 | ---@field gap_single_client boolean: Enable gaps for a single client. 56 | ---@field master_fill_policy string: Set size fill policy for the master client(s). 57 | ---@field master_count integer: Set the number of master windows. 58 | ---@field icon any: Set the tag icon. 59 | ---@field column_count integer: Set the number of columns. 60 | ---@field clients fun(self: Awesome.tag): Awesome.client[] 61 | ---@field delete fun(self: Awesome.tag, fallback_tag: Awesome.tag|nil, force: boolean|nil): nil 62 | ---@field find_by_name fun(screen: Awesome.screen, name: string): Awesome.tag|nil 63 | ---@field view_only fun(self: Awesome.tag): nil 64 | ---@field connect_signal fun(self: Awesome.tag, signal: string, func: fun()): nil 65 | ---@field disconnect_signal fun(self: Awesome.tag, signal: string, func: fun()): nil 66 | ---@field emit_signal fun(self: Awesome.tag, signal: string, ...): nil 67 | 68 | -- Signals (TODO) 69 | -- ["request::select"] fun(self: Awesome.tag): nil 70 | -- ["tagged"] fun(self: Awesome.tag, client: Awesome.client): nil 71 | -- ["untagged"] fun(self: Awesome.tag, client: Awesome.client): nil 72 | -- ["property::urgent"] fun(self: Awesome.tag): nil 73 | -- ["property::urgent_count"] fun(self: Awesome.tag): nil 74 | -- ["request::screen"] fun(self: Awesome.tag): nil 75 | -- ["removal-pending"] fun(self: Awesome.tag): nil 76 | 77 | ---@type Awesome.tag 78 | 79 | ---@class Awesome.client 80 | ---@field window integer: The X Window ID. (Read-only) 81 | ---@field name string: The client title. 82 | ---@field skip_taskbar boolean: True if the client does not want to be in the taskbar. 83 | ---@field type string: The window type. (Read-only) 84 | ---@field class string: The client class. (Read-only) 85 | ---@field instance string: The client instance. (Read-only) 86 | ---@field pid integer|nil: The client PID, if available. (Read-only) 87 | ---@field role string|nil: The window role, if available. (Read-only) 88 | ---@field machine string|nil: The machine client is running on. (Read-only) 89 | ---@field icon_name string|nil: The client name when iconified. (Read-only) 90 | ---@field icon any|nil: The client icon as a surface. (Read-only) 91 | ---@field icon_sizes table|nil: The available sizes of client icons. (Read-only) 92 | ---@field screen Awesome.screen: Client screen. 93 | ---@field hidden boolean: Define if the client must be hidden, i.e., minimized. 94 | ---@field minimized boolean: Define if the client must be iconified, i.e., minimized. 95 | ---@field size_hints_honor boolean: Honor size hints, e.g., 'aspect_ratio'. 96 | ---@field border_width integer: The client border width. 97 | ---@field border_color string: The client border color. 98 | ---@field urgent boolean: The client urgent state. 99 | ---@field content any: A cairo surface for the client window content. (Read-only) 100 | ---@field opacity number: The client opacity. 101 | ---@field ontop boolean: The client is on top of every other window. 102 | ---@field above boolean: The client is above normal windows. 103 | ---@field below boolean: The client is below normal windows. 104 | ---@field fullscreen boolean: The client is fullscreen or not. 105 | ---@field maximized boolean: The client is maximized (horizontally and vertically) or not. 106 | ---@field maximized_horizontal boolean: The client is maximized horizontally or not. 107 | ---@field maximized_vertical boolean: The client is maximized vertically or not. 108 | ---@field transient_for Awesome.client|nil: The client the window is transient for. 109 | ---@field group_window integer|nil: Window identification unique to a group of windows. (Read-only) 110 | ---@field leader_window integer|nil: Identification unique to windows spawned by the same command. (Read-only) 111 | ---@field size_hints table: A table with size hints of the client. (Read-only) 112 | ---@field motif_wm_hints table: The motif WM hints of the client. (Read-only) 113 | ---@field sticky boolean: Set the client sticky, i.e., visible on all tags. 114 | ---@field modal boolean: Indicate if the client is modal. 115 | ---@field focusable boolean: True if the client can receive the input focus. 116 | ---@field shape_bounding any: The client’s bounding shape as set by awesome as a (native) cairo surface. 117 | ---@field shape_clip any: The client’s clip shape as set by awesome as a (native) cairo surface. 118 | ---@field shape_input any: The client’s input shape as set by awesome as a (native) cairo surface. 119 | ---@field client_shape_bounding any: The client’s bounding shape as set by the program as a (native) cairo surface. (Read-only) 120 | ---@field client_shape_clip any: The client’s clip shape as set by the program as a (native) cairo surface. (Read-only) 121 | ---@field startup_id string|nil: The FreeDesktop StartId. (Read-only) 122 | ---@field valid boolean: If the client that this object refers to is still managed by awesome. (Read-only) 123 | ---@field first_tag Awesome.tag|nil: The first tag of the client. (Read-only) 124 | ---@field marked boolean: If a client is marked or not. 125 | ---@field is_fixed boolean: Return if a client has a fixed size or not. (Read-only) 126 | ---@field immobilized_horizontal boolean: Is the client immobilized horizontally? (Read-only) 127 | ---@field immobilized_vertical boolean: Is the client immobilized vertically? (Read-only) 128 | ---@field floating boolean: The client floating state. 129 | ---@field x integer: The x coordinate. 130 | ---@field y integer: The y coordinate. 131 | ---@field width integer: The width of the client. 132 | ---@field height integer: The height of the client. 133 | ---@field dockable boolean: If the client is dockable. (Read-only) 134 | ---@field requests_no_titlebar boolean: If the client requests not to be decorated with a titlebar. (Read-only) 135 | ---@field shape any: Set the client shape. 136 | ---@field struts fun(self: Awesome.client, struts: table|nil): table 137 | ---@field buttons fun(self: Awesome.client, buttons_table: table|nil): table 138 | ---@field instances fun(): integer 139 | ---@field get fun(screen: Awesome.screen|nil, stacked: boolean|nil): Awesome.client[] 140 | ---@field isvisible fun(self: Awesome.client): boolean 141 | ---@field kill fun(self: Awesome.client): nil 142 | ---@field swap fun(self: Awesome.client, c: Awesome.client): nil 143 | ---@field tags fun(self: Awesome.client, tags_table: Awesome.tag[]|nil): Awesome.tag[] 144 | ---@field raise fun(self: Awesome.client): nil 145 | ---@field lower fun(self: Awesome.client): nil 146 | ---@field unmanage fun(self: Awesome.client): nil 147 | ---@field geometry fun(self: Awesome.client, geo: table|nil): table 148 | ---@field apply_size_hints fun(self: Awesome.client, width: integer, height: integer): integer, integer 149 | ---@field get_icon fun(self: Awesome.client, index: integer): any 150 | ---@field jump_to fun(self: Awesome.client, merge: boolean|nil): nil 151 | ---@field append_keybinding fun(self: Awesome.client, key: any): nil 152 | ---@field remove_keybinding fun(self: Awesome.client, key: any): nil 153 | ---@field append_mousebinding fun(self: Awesome.client, button: any): nil 154 | ---@field remove_mousebinding fun(self: Awesome.client, button: any): nil 155 | ---@field to_primary_section fun(self: Awesome.client): nil 156 | ---@field to_secondary_section fun(self: Awesome.client): nil 157 | ---@field relative_move fun(self: Awesome.client, x: integer, y: integer, w: integer, h: integer): nil 158 | ---@field move_to_tag fun(self: Awesome.client, target: Awesome.tag): nil 159 | ---@field toggle_tag fun(self: Awesome.client, target: Awesome.tag): nil 160 | ---@field move_to_screen fun(self: Awesome.client, s: Awesome.screen|nil): nil 161 | ---@field to_selected_tags fun(self: Awesome.client): nil 162 | ---@field get_transient_for_matching fun(self: Awesome.client, matcher: fun(c: Awesome.client): boolean): Awesome.client|nil 163 | ---@field is_transient_for fun(self: Awesome.client, c2: Awesome.client): boolean 164 | ---@field activate fun(self: Awesome.client, args: table|nil): nil 165 | -------------------------------------------------------------------------------- /custom/volume.lua: -------------------------------------------------------------------------------- 1 | local naughty = require "naughty" 2 | local spawn = require "awful.spawn" 3 | 4 | local GET_VOLUME_CMD = "amixer -D pulse sget Master" 5 | local INC_VOLUME_CMD = "amixer -D pulse sset Master 5%+" 6 | local DEC_VOLUME_CMD = "amixer -D pulse sset Master 5%-" 7 | 8 | local bind = function(text, cmd) 9 | return function() 10 | spawn.easy_async(cmd, function() 11 | spawn.easy_async(GET_VOLUME_CMD, function(stdout) 12 | local volume_level = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) 13 | 14 | naughty.notify { 15 | text = string.format("%s: %s", text, volume_level), 16 | title = "Volume", 17 | timeout = 1, 18 | } 19 | end) 20 | end) 21 | end 22 | end 23 | 24 | return { 25 | inc = bind("Up", INC_VOLUME_CMD), 26 | dec = bind("Down", DEC_VOLUME_CMD), 27 | } 28 | -------------------------------------------------------------------------------- /custom/widgets/mem.lua: -------------------------------------------------------------------------------- 1 | local wibox = require "wibox" 2 | local gears = require "gears" 3 | local awful = require "awful" 4 | 5 | -- Create memory widget 6 | local mem_widget = wibox.widget { 7 | { 8 | id = "text", 9 | text = "Mem: 0", 10 | widget = wibox.widget.textbox, 11 | }, 12 | widget = wibox.container.margin, 13 | margins = 5, 14 | } 15 | 16 | -- Function to update memory usage 17 | local function update_mem_usage(widget) 18 | awful.spawn.easy_async_with_shell("free -m | awk '/Mem:/ {printf(\"%.1f%%\", $3/$2 * 100)}'", function(stdout) 19 | widget.text = "Mem: " .. stdout 20 | end) 21 | end 22 | 23 | -- Periodically update memory usage 24 | gears.timer { 25 | call_now = true, 26 | timeout = 5, -- Update every 5 seconds 27 | autostart = true, 28 | callback = function() 29 | update_mem_usage(mem_widget:get_children_by_id("text")[1]) 30 | end, 31 | } 32 | 33 | -- Return widget for inclusion in topbar 34 | return mem_widget 35 | -------------------------------------------------------------------------------- /custom/widgets/menu.lua: -------------------------------------------------------------------------------- 1 | local awful = require "awful" 2 | local beautiful = require "beautiful" 3 | local hotkeys_popup = require "awful.hotkeys_popup" 4 | 5 | -- Load Debian menu entries 6 | local debian = require "debian.menu" 7 | local has_fdo, freedesktop = pcall(require, "freedesktop") 8 | 9 | -- Create a launcher widget and a main menu 10 | local my_awesome_menu = { 11 | { 12 | "hotkeys", 13 | function() 14 | hotkeys_popup.show_help(nil, awful.screen.focused()) 15 | end, 16 | }, 17 | { "edit config", "nvim " .. awesome.conffile }, 18 | { "restart", awesome.restart }, 19 | { 20 | "quit", 21 | function() 22 | awesome.quit() 23 | end, 24 | }, 25 | } 26 | 27 | local menu_awesome = { "awesome", my_awesome_menu, beautiful.awesome_icon } 28 | 29 | local my_main_menu 30 | if has_fdo then 31 | my_main_menu = freedesktop.menu.build { before = { menu_awesome } } 32 | else 33 | my_main_menu = awful.menu { 34 | items = { 35 | menu_awesome, 36 | { "Debian", debian.menu.Debian_menu.Debian }, 37 | }, 38 | } 39 | end 40 | 41 | return my_main_menu 42 | -------------------------------------------------------------------------------- /rc.lua: -------------------------------------------------------------------------------- 1 | local _ = require "custom.setup" -- Error handling 2 | local _ = require "custom.types" -- Awesome WM Types 3 | 4 | local terminal = "ghostty" 5 | 6 | local log = require "custom.log" 7 | local mods = require("custom.theme.constants").mods 8 | 9 | local awful = require "awful" 10 | local beautiful = require "beautiful" 11 | local gears = require "gears" 12 | local hotkeys_popup = require "awful.hotkeys_popup" 13 | local wibox = require "wibox" 14 | 15 | beautiful.init(string.format("%s/.config/awesome/custom/theme.lua", os.getenv "HOME")) 16 | require "awful.autofocus" 17 | 18 | local obsidian = require "custom.obsidian" 19 | obsidian.setup() 20 | 21 | awful.layout.layouts = { 22 | awful.layout.suit.tile, 23 | awful.layout.suit.tile.left, 24 | awful.layout.suit.tile.bottom, 25 | awful.layout.suit.tile.top, 26 | awful.layout.suit.fair.horizontal, 27 | awful.layout.suit.spiral.dwindle, 28 | awful.layout.suit.magnifier, 29 | } 30 | 31 | -- Setup Theme 32 | awful.screen.connect_for_each_screen(require("custom.theme").at_screen_connect) 33 | 34 | root.buttons(gears.table.join( 35 | awful.button({}, 3, function() 36 | require("custom.widgets.menu"):toggle() 37 | end), 38 | awful.button({}, 4, awful.tag.viewnext), 39 | awful.button({}, 5, awful.tag.viewprev) 40 | )) 41 | 42 | local global_keys = gears.table.join( 43 | awful.key({ mods.super }, "s", hotkeys_popup.show_help, { 44 | description = "show help", 45 | group = "awesome", 46 | }), 47 | awful.key({ mods.super }, "c", function() 48 | if beautiful.cal then 49 | beautiful.cal.show(7) 50 | end 51 | end, { description = "show calendar", group = "widgets" }), 52 | awful.key({ mods.super }, "s", hotkeys_popup.show_help, { 53 | description = "show help", 54 | group = "awesome", 55 | }), 56 | awful.key({ mods.super }, "Escape", awful.tag.history.restore, { 57 | description = "go back", 58 | group = "tag", 59 | }), 60 | awful.key({ mods.super }, "j", function() 61 | awful.client.focus.byidx(1) 62 | end, { 63 | description = "focus next by index", 64 | group = "client", 65 | }), 66 | awful.key({ mods.super }, "k", function() 67 | awful.client.focus.byidx(-1) 68 | end, { 69 | description = "focus previous by index", 70 | group = "client", 71 | }), 72 | awful.key({ mods.super }, "w", function() 73 | require("custom.widgets.menu"):show() 74 | end, { 75 | description = "show main menu", 76 | group = "awesome", 77 | }), -- Layout manipulation 78 | awful.key({ mods.super, mods.shift }, "j", function() 79 | awful.client.swap.byidx(1) 80 | end, { 81 | description = "swap with next client by index", 82 | group = "client", 83 | }), 84 | awful.key({ mods.super, mods.shift }, "k", function() 85 | awful.client.swap.byidx(-1) 86 | end, { 87 | description = "swap with previous client by index", 88 | group = "client", 89 | }), 90 | awful.key({ mods.super, mods.control }, "j", function() 91 | awful.screen.focus_relative(1) 92 | end, { 93 | description = "focus the next screen", 94 | group = "screen", 95 | }), 96 | awful.key({ mods.super, mods.control }, "k", function() 97 | awful.screen.focus_relative(-1) 98 | end, { 99 | description = "focus the previous screen", 100 | group = "screen", 101 | }), 102 | awful.key({ mods.super }, "u", awful.client.urgent.jumpto, { 103 | description = "jump to urgent client", 104 | group = "client", 105 | }), 106 | awful.key({ mods.super }, "Tab", function() 107 | awful.client.focus.history.previous() 108 | if client.focus then 109 | client.focus:raise() 110 | end 111 | end, { 112 | description = "go back", 113 | group = "client", 114 | }), -- Standard program 115 | awful.key({ mods.super }, "Return", function() 116 | awful.spawn(terminal) 117 | end, { 118 | description = "open a terminal", 119 | group = "launcher", 120 | }), 121 | awful.key({ mods.super, mods.control }, "r", awesome.restart, { 122 | description = "reload awesome", 123 | group = "awesome", 124 | }), 125 | awful.key({ mods.super, mods.shift }, "q", awesome.quit, { 126 | description = "quit awesome", 127 | group = "awesome", 128 | }), 129 | awful.key({ mods.super }, "l", function() 130 | awful.tag.incmwfact(0.05) 131 | end, { 132 | description = "increase master width factor", 133 | group = "layout", 134 | }), 135 | awful.key({ mods.super }, "h", function() 136 | awful.tag.incmwfact(-0.05) 137 | end, { 138 | description = "decrease master width factor", 139 | group = "layout", 140 | }), 141 | awful.key({ mods.super, mods.shift }, "h", function() 142 | awful.tag.incnmaster(1, nil, true) 143 | end, { 144 | description = "increase the number of master clients", 145 | group = "layout", 146 | }), 147 | awful.key({ mods.super, mods.shift }, "l", function() 148 | awful.tag.incnmaster(-1, nil, true) 149 | end, { 150 | description = "decrease the number of master clients", 151 | group = "layout", 152 | }), 153 | awful.key({ mods.super, mods.control }, "h", function() 154 | awful.tag.incncol(1, nil, true) 155 | end, { 156 | description = "increase the number of columns", 157 | group = "layout", 158 | }), 159 | awful.key({ mods.super, mods.control }, "l", function() 160 | awful.tag.incncol(-1, nil, true) 161 | end, { 162 | description = "decrease the number of columns", 163 | group = "layout", 164 | }), 165 | awful.key({ mods.super }, "space", function() 166 | awful.layout.inc(1) 167 | end, { 168 | description = "select next", 169 | group = "layout", 170 | }), 171 | awful.key({ mods.super, mods.shift }, "space", function() 172 | awful.layout.inc(-1) 173 | end, { 174 | description = "select previous", 175 | group = "layout", 176 | }), 177 | awful.key({ mods.super, mods.control }, "n", function() 178 | local c = awful.client.restore() 179 | -- Focus restored client 180 | if c then 181 | c:emit_signal("request::activate", "key.unminimize", { raise = true }) 182 | end 183 | end, { 184 | description = "restore minimized", 185 | group = "client", 186 | }), -- Prompt 187 | awful.key({ mods.super }, "r", function() 188 | -- TODO: I have stuff like ghostty installed without Desktop stuff... 189 | -- I guess I could add that and it would show up in drun, but ... idk 190 | awful.spawn "rofi -show run" 191 | end, { 192 | description = "run prompt", 193 | group = "launcher", 194 | }), 195 | awful.key({ mods.super }, "x", function() 196 | awful.prompt.run { 197 | prompt = "Run Lua code: ", 198 | textbox = awful.screen.focused().mypromptbox.widget, 199 | exe_callback = awful.util.eval, 200 | history_path = awful.util.get_cache_dir() .. "/history_eval", 201 | } 202 | end, { 203 | description = "lua execute prompt", 204 | group = "awesome", 205 | }), 206 | 207 | -- Client Manipulation 208 | awful.key({ mods.super, mods.control }, "o", function() 209 | for c in 210 | awful.client.iterate(function(cl) 211 | return cl.class == "obsidian" and cl.name and cl.name:lower():find "public" 212 | end) 213 | do 214 | if client.focus == c then 215 | c:move_to_tag(awful.screen.focused().tags[9]) 216 | return 217 | end 218 | 219 | return obsidian.focus(c) 220 | end 221 | 222 | -- We didn't find obsidian, so let's launch one. 223 | awful.spawn "obsidian /home/tjdevries/Documents/public" 224 | gears.timer.start_new(2, function() 225 | for c in 226 | awful.client.iterate(function(cl) 227 | return cl.class == "obsidian" and cl.name and cl.name:lower():find "public" 228 | end) 229 | do 230 | obsidian.focus(c) 231 | break 232 | end 233 | 234 | return false 235 | end) 236 | end), 237 | 238 | -- Volume control 239 | awful.key({ mods.super }, "]", require("custom.volume").inc), 240 | awful.key({ mods.super }, "[", require("custom.volume").dec), 241 | awful.key({ mods.super, mods.shift }, "t", function() 242 | awful.titlebar.toggle(client.focus) 243 | end) 244 | ) 245 | 246 | local client_keys = gears.table.join( 247 | awful.key({ mods.super }, "f", function(c) 248 | c.fullscreen = not c.fullscreen 249 | c:raise() 250 | end, { 251 | description = "toggle fullscreen", 252 | group = "client", 253 | }), 254 | awful.key({ mods.super, mods.shift }, "c", function(c) 255 | c:kill() 256 | end, { 257 | description = "close", 258 | group = "client", 259 | }), 260 | awful.key({ mods.super, mods.control }, "space", awful.client.floating.toggle, { 261 | description = "toggle floating", 262 | group = "client", 263 | }), 264 | awful.key({ mods.super, mods.control }, "Return", function(c) 265 | c:swap(awful.client.getmaster()) 266 | end, { 267 | description = "move to master", 268 | group = "client", 269 | }), 270 | awful.key({ mods.super }, "o", function(c) 271 | c:move_to_screen() 272 | end, { 273 | description = "move to screen", 274 | group = "client", 275 | }), 276 | awful.key({ mods.super }, "t", function(c) 277 | c.ontop = not c.ontop 278 | end, { 279 | description = "toggle keep on top", 280 | group = "client", 281 | }), 282 | awful.key({ mods.super }, "n", function(c) 283 | -- The client currently has the input focus, so it cannot be 284 | -- minimized, since minimized clients can't have the focus. 285 | c.minimized = true 286 | end, { 287 | description = "minimize", 288 | group = "client", 289 | }), 290 | awful.key({ mods.super }, "m", function(c) 291 | c.maximized = not c.maximized 292 | c:raise() 293 | end, { 294 | description = "(un)maximize", 295 | group = "client", 296 | }), 297 | awful.key({ mods.super, mods.control }, "m", function(c) 298 | c.maximized_vertical = not c.maximized_vertical 299 | c:raise() 300 | end, { 301 | description = "(un)maximize vertically", 302 | group = "client", 303 | }), 304 | awful.key({ mods.super, mods.shift }, "m", function(c) 305 | c.maximized_horizontal = not c.maximized_horizontal 306 | c:raise() 307 | end, { 308 | description = "(un)maximize horizontally", 309 | group = "client", 310 | }), 311 | -- TODO: Gotta figure out why this just opens 8 things? 312 | awful.key({ mods.super, mods.control }, "Return", function() 313 | awful.spawn("kitty", { floating = true }) 314 | end, { description = "spawn floating terminal", group = "launcher" }) 315 | ) 316 | 317 | -- Bind all key numbers to tags. 318 | -- Be careful: we use keycodes to make it work on any keyboard layout. 319 | -- This should map on the top row of your keyboard, usually 1 to 9. 320 | for i = 1, 9 do 321 | global_keys = gears.table.join( 322 | global_keys, -- View tag only. 323 | awful.key({ mods.super }, "#" .. i + 9, function() 324 | local screen = awful.screen.focused() 325 | local tag = screen.tags[i] 326 | if tag then 327 | tag:view_only() 328 | end 329 | end, { 330 | description = "view tag #" .. i, 331 | group = "tag", 332 | }), 333 | -- Move client to tag. 334 | awful.key({ mods.super, mods.shift }, "#" .. i + 9, function() 335 | if client.focus then 336 | local tag = client.focus.screen.tags[i] 337 | if tag then 338 | client.focus:move_to_tag(tag) 339 | end 340 | end 341 | end, { 342 | description = "move focused client to tag #" .. i, 343 | group = "tag", 344 | }), -- Toggle tag on focused client. 345 | awful.key({ mods.super, mods.control, mods.shift }, "#" .. i + 9, function() 346 | if client.focus then 347 | local tag = client.focus.screen.tags[i] 348 | if tag then 349 | client.focus:toggle_tag(tag) 350 | end 351 | end 352 | end, { 353 | description = "toggle focused client on tag #" .. i, 354 | group = "tag", 355 | }) 356 | ) 357 | end 358 | 359 | local client_buttons = gears.table.join( 360 | awful.button({}, 1, function(c) 361 | c:emit_signal("request::activate", "mouse_click", { raise = true }) 362 | end), 363 | awful.button({ mods.super }, 1, function(c) 364 | c:emit_signal("request::activate", "mouse_click", { raise = true }) 365 | awful.mouse.client.move(c) 366 | end), 367 | awful.button({ mods.super }, 3, function(c) 368 | c:emit_signal("request::activate", "mouse_click", { raise = true }) 369 | awful.mouse.client.resize(c) 370 | end) 371 | ) 372 | 373 | root.keys(global_keys) 374 | 375 | -- Rules to apply to new clients (through the "manage" signal). 376 | awful.rules.rules = { 377 | -- All clients will match this rule. 378 | { 379 | rule = {}, 380 | properties = { 381 | border_width = beautiful.border_width, 382 | border_color = beautiful.border_normal, 383 | focus = awful.client.focus.filter, 384 | raise = true, 385 | keys = client_keys, 386 | buttons = client_buttons, 387 | screen = awful.screen.preferred, 388 | placement = awful.placement.no_overlap + awful.placement.no_offscreen, 389 | }, 390 | }, 391 | { 392 | rule_any = { 393 | instance = { "pinentry" }, 394 | class = {}, 395 | 396 | name = {}, 397 | role = { 398 | "pop-up", -- e.g. Google Chrome's (detached) Developer Tools. 399 | }, 400 | }, 401 | properties = { floating = true }, 402 | }, 403 | { 404 | rule_any = { type = { "normal", "dialog" } }, 405 | properties = { titlebars_enabled = true }, 406 | }, 407 | } 408 | 409 | -- Signal function to execute when a new client appears. 410 | client.connect_signal("manage", function(c) 411 | awful.titlebar.hide(c) 412 | 413 | -- Prevent clients from being unreachable after screen count changes. 414 | if awesome.startup and not c.size_hints.user_position and not c.size_hints.program_position then 415 | awful.placement.no_offscreen(c) 416 | end 417 | end) 418 | 419 | -- Add a titlebar if titlebars_enabled is set to true in the rules. 420 | client.connect_signal("request::titlebars", function(c) 421 | -- buttons for the titlebar 422 | local buttons = gears.table.join( 423 | awful.button({}, 1, function() 424 | c:emit_signal("request::activate", "titlebar", { raise = true }) 425 | awful.mouse.client.move(c) 426 | end), 427 | awful.button({}, 3, function() 428 | c:emit_signal("request::activate", "titlebar", { raise = true }) 429 | awful.mouse.client.resize(c) 430 | end) 431 | ) 432 | 433 | awful.titlebar(c):setup { 434 | { -- Left 435 | awful.titlebar.widget.iconwidget(c), 436 | buttons = buttons, 437 | layout = wibox.layout.fixed.horizontal, 438 | }, 439 | { -- Middle 440 | { -- Title 441 | align = "center", 442 | widget = awful.titlebar.widget.titlewidget(c), 443 | }, 444 | buttons = buttons, 445 | layout = wibox.layout.flex.horizontal, 446 | }, 447 | { -- Right 448 | awful.titlebar.widget.floatingbutton(c), 449 | awful.titlebar.widget.maximizedbutton(c), 450 | awful.titlebar.widget.stickybutton(c), 451 | awful.titlebar.widget.ontopbutton(c), 452 | awful.titlebar.widget.closebutton(c), 453 | layout = wibox.layout.fixed.horizontal(), 454 | }, 455 | layout = wibox.layout.align.horizontal, 456 | } 457 | end) 458 | 459 | -- Enable sloppy focus, so that focus follows mouse. 460 | client.connect_signal("mouse::enter", function(c) 461 | c:emit_signal("request::activate", "mouse_enter", { raise = false }) 462 | end) 463 | 464 | client.connect_signal("focus", function(c) 465 | c.border_color = beautiful.border_focus or "" 466 | end) 467 | 468 | client.connect_signal("unfocus", function(c) 469 | c.border_color = beautiful.border_normal or "" 470 | end) 471 | -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 2 3 | no_call_parentheses = true 4 | --------------------------------------------------------------------------------