NixOS config

This commit is contained in:
lanxu 2022-08-30 22:24:49 +03:00
parent d039abbd0d
commit a48d49cffb
120 changed files with 7445 additions and 0 deletions

View File

@ -0,0 +1,24 @@
-- {{{ Grab environment
local setmetatable = setmetatable
-- }}}
local temp = {};
-- {{{ Date widget type
local function worker(format, warg)
local f = io.popen("xset q | grep 'DPMS is' | awk '/ / {print $3}'")
temp[0] = "";
for line in f:lines() do
temp[0] = temp[0] .. line
end
io.close(f)
return temp
end
-- }}}
return setmetatable(temp, { __call = function(_, ...) return worker(...) end })

View File

@ -0,0 +1,23 @@
-- {{{ Grab environment
local setmetatable = setmetatable
-- }}}
local temp = {};
-- {{{ Date widget type
local function worker(format, warg)
local f = io.popen("gputemp.py")
temp[0] = "";
for line in f:lines() do
temp[0] = temp[0] .. line
end
io.close(f)
return temp
end
-- }}}
return setmetatable(temp, { __call = function(_, ...) return worker(...) end })

23
config/awesome/hubic.lua Normal file
View File

@ -0,0 +1,23 @@
-- {{{ Grab environment
local setmetatable = setmetatable
-- }}}
local temp = {};
-- {{{ Date widget type
local function worker(format, warg)
local f = io.popen("hubic.py")
temp[0] = "";
for line in f:lines() do
temp[0] = temp[0] .. line
end
io.close(f)
return temp
end
-- }}}
return setmetatable(temp, { __call = function(_, ...) return worker(...) end })

View File

@ -0,0 +1,35 @@
lanxu awesome scripts
=====================
Requirements
------------
- dkjson (for parsing json. Available with this widget)
How to use
----------
You may create your widget like this:
~~~lua
local mcstatus = require("lanxu/mcstatus")
myserverstatus = mcstatus({
settings = function()
widget.markup = "PLAYERS <b>" .. totalplayers .. "</b>"
end
})
~~~
After this you can use "myserverstatus" like any other textbox widget
full list of available settings below
~~~lua
myserverstatus = mcstatus({
hideempty = false,
hideoffline = true,
calluri = "https://page.not.found/mc_stats.php?type=server_status",
settings = function()
widget.markup = "PLAYERS <b>" .. totalplayers .. "</b>"
end
})
~~~

View File

@ -0,0 +1,80 @@
local naughty = require("naughty")
local wibox = require("wibox")
local gears = require("gears")
local focused = require("awful.screen").focused
local easy_async = require("awful.spawn").easy_async
local function factory(args)
local args = args or {}
local timeout = args.timeout or 5
local status_cmd = args.status_cmd or "hubic status"
local full_cmd = args.full_cmd or "hubic status"
local cloud = { widget = wibox.widget.textbox() }
local settings = args.settings or function() end
local followtag = args.followtag or true
local notification_preset = args.notification_preset or { font = "Monospace 10" }
cloud.widget:set_markup("N/A")
function cloud.show(tout)
cloud.hide()
if followtag then
notification_preset.screen = focused()
end
cloud.notification = naughty.notify({
text = cloud.notification_text,
-- icon = cloud.icon
timeout = 0,
preset = notification_preset,
})
end
function cloud.hide()
if cloud.notification then
naughty.destroy(cloud.notification)
end
end
function cloud.attach(obj)
obj:connect_signal("mouse::enter", function()
cloud.show()
end)
obj:connect_signal("mouse::leave", function()
cloud.hide()
end)
obj:connect_signal("button::press", function()
cloud.update()
cloud.show()
end)
end
function cloud.update()
local cmd = string.format(full_cmd)
easy_async(cmd, function(response, stderr, reason, exit_code)
local res = string.match(response, 'State: (.-)Up')
res = res:gsub("%s+", "")
res = string.gsub(res, "%s+", "")
currentstatus = res or "No"
cloud.notification_text = response
widget = cloud.widget
settings()
end)
end
cloud.attach(cloud.widget)
gears.timer {
timeout = timeout,
autostart = true,
callback = cloud.update
}
cloud.update()
return cloud
end
return factory

View File

@ -0,0 +1,714 @@
-- Module options:
local always_try_using_lpeg = true
local register_global_module_table = false
local global_module_name = 'json'
--[==[
David Kolf's JSON module for Lua 5.1/5.2
Version 2.5
For the documentation see the corresponding readme.txt or visit
<http://dkolf.de/src/dkjson-lua.fsl/>.
You can contact the author by sending an e-mail to 'david' at the
domain 'dkolf.de'.
Copyright (C) 2010-2013 David Heiko Kolf
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--]==]
-- global dependencies:
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
local error, require, pcall, select = error, require, pcall, select
local floor, huge = math.floor, math.huge
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
string.rep, string.gsub, string.sub, string.byte, string.char,
string.find, string.len, string.format
local strmatch = string.match
local concat = table.concat
local json = { version = "dkjson 2.5" }
if register_global_module_table then
_G[global_module_name] = json
end
local _ENV = nil -- blocking globals in Lua 5.2
pcall (function()
-- Enable access to blocked metatables.
-- Don't worry, this module doesn't change anything in them.
local debmeta = require "debug".getmetatable
if debmeta then getmetatable = debmeta end
end)
json.null = setmetatable ({}, {
__tojson = function () return "null" end
})
local function isarray (tbl)
local max, n, arraylen = 0, 0, 0
for k,v in pairs (tbl) do
if k == 'n' and type(v) == 'number' then
arraylen = v
if v > max then
max = v
end
else
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
return false
end
if k > max then
max = k
end
n = n + 1
end
end
if max > 10 and max > arraylen and max > n * 2 then
return false -- don't create an array with too many holes
end
return true, max
end
local escapecodes = {
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
}
local function escapeutf8 (uchar)
local value = escapecodes[uchar]
if value then
return value
end
local a, b, c, d = strbyte (uchar, 1, 4)
a, b, c, d = a or 0, b or 0, c or 0, d or 0
if a <= 0x7f then
value = a
elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
value = (a - 0xc0) * 0x40 + b - 0x80
elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
else
return ""
end
if value <= 0xffff then
return strformat ("\\u%.4x", value)
elseif value <= 0x10ffff then
-- encode as UTF-16 surrogate pair
value = value - 0x10000
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
else
return ""
end
end
local function fsub (str, pattern, repl)
-- gsub always builds a new string in a buffer, even when no match
-- exists. First using find should be more efficient when most strings
-- don't contain the pattern.
if strfind (str, pattern) then
return gsub (str, pattern, repl)
else
return str
end
end
local function quotestring (value)
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
if strfind (value, "[\194\216\220\225\226\239]") then
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
value = fsub (value, "\216[\128-\132]", escapeutf8)
value = fsub (value, "\220\143", escapeutf8)
value = fsub (value, "\225\158[\180\181]", escapeutf8)
value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8)
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
value = fsub (value, "\239\187\191", escapeutf8)
value = fsub (value, "\239\191[\176-\191]", escapeutf8)
end
return "\"" .. value .. "\""
end
json.quotestring = quotestring
local function replace(str, o, n)
local i, j = strfind (str, o, 1, true)
if i then
return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1)
else
return str
end
end
-- locale independent num2str and str2num functions
local decpoint, numfilter
local function updatedecpoint ()
decpoint = strmatch(tostring(0.5), "([^05+])")
-- build a filter that can be used to remove group separators
numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
end
updatedecpoint()
local function num2str (num)
return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
end
local function str2num (str)
local num = tonumber(replace(str, ".", decpoint))
if not num then
updatedecpoint()
num = tonumber(replace(str, ".", decpoint))
end
return num
end
local function addnewline2 (level, buffer, buflen)
buffer[buflen+1] = "\n"
buffer[buflen+2] = strrep (" ", level)
buflen = buflen + 2
return buflen
end
function json.addnewline (state)
if state.indent then
state.bufferlen = addnewline2 (state.level or 0,
state.buffer, state.bufferlen or #(state.buffer))
end
end
local encode2 -- forward declaration
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state)
local kt = type (key)
if kt ~= 'string' and kt ~= 'number' then
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
end
if prev then
buflen = buflen + 1
buffer[buflen] = ","
end
if indent then
buflen = addnewline2 (level, buffer, buflen)
end
buffer[buflen+1] = quotestring (key)
buffer[buflen+2] = ":"
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state)
end
local function appendcustom(res, buffer, state)
local buflen = state.bufferlen
if type (res) == 'string' then
buflen = buflen + 1
buffer[buflen] = res
end
return buflen
end
local function exception(reason, value, state, buffer, buflen, defaultmessage)
defaultmessage = defaultmessage or reason
local handler = state.exception
if not handler then
return nil, defaultmessage
else
state.bufferlen = buflen
local ret, msg = handler (reason, value, state, defaultmessage)
if not ret then return nil, msg or defaultmessage end
return appendcustom(ret, buffer, state)
end
end
function json.encodeexception(reason, value, state, defaultmessage)
return quotestring("<" .. defaultmessage .. ">")
end
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state)
local valtype = type (value)
local valmeta = getmetatable (value)
valmeta = type (valmeta) == 'table' and valmeta -- only tables
local valtojson = valmeta and valmeta.__tojson
if valtojson then
if tables[value] then
return exception('reference cycle', value, state, buffer, buflen)
end
tables[value] = true
state.bufferlen = buflen
local ret, msg = valtojson (value, state)
if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end
tables[value] = nil
buflen = appendcustom(ret, buffer, state)
elseif value == nil then
buflen = buflen + 1
buffer[buflen] = "null"
elseif valtype == 'number' then
local s
if value ~= value or value >= huge or -value >= huge then
-- This is the behaviour of the original JSON implementation.
s = "null"
else
s = num2str (value)
end
buflen = buflen + 1
buffer[buflen] = s
elseif valtype == 'boolean' then
buflen = buflen + 1
buffer[buflen] = value and "true" or "false"
elseif valtype == 'string' then
buflen = buflen + 1
buffer[buflen] = quotestring (value)
elseif valtype == 'table' then
if tables[value] then
return exception('reference cycle', value, state, buffer, buflen)
end
tables[value] = true
level = level + 1
local isa, n = isarray (value)
if n == 0 and valmeta and valmeta.__jsontype == 'object' then
isa = false
end
local msg
if isa then -- JSON array
buflen = buflen + 1
buffer[buflen] = "["
for i = 1, n do
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end
if i < n then
buflen = buflen + 1
buffer[buflen] = ","
end
end
buflen = buflen + 1
buffer[buflen] = "]"
else -- JSON object
local prev = false
buflen = buflen + 1
buffer[buflen] = "{"
local order = valmeta and valmeta.__jsonorder or globalorder
if order then
local used = {}
n = #order
for i = 1, n do
local k = order[i]
local v = value[k]
if v then
used[k] = true
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
prev = true -- add a seperator before the next element
end
end
for k,v in pairs (value) do
if not used[k] then
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
else -- unordered
for k,v in pairs (value) do
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
if indent then
buflen = addnewline2 (level - 1, buffer, buflen)
end
buflen = buflen + 1
buffer[buflen] = "}"
end
tables[value] = nil
else
return exception ('unsupported type', value, state, buffer, buflen,
"type '" .. valtype .. "' is not supported by JSON.")
end
return buflen
end
function json.encode (value, state)
state = state or {}
local oldbuffer = state.buffer
local buffer = oldbuffer or {}
state.buffer = buffer
updatedecpoint()
local ret, msg = encode2 (value, state.indent, state.level or 0,
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state)
if not ret then
error (msg, 2)
elseif oldbuffer == buffer then
state.bufferlen = ret
return true
else
state.bufferlen = nil
state.buffer = nil
return concat (buffer)
end
end
local function loc (str, where)
local line, pos, linepos = 1, 1, 0
while true do
pos = strfind (str, "\n", pos, true)
if pos and pos < where then
line = line + 1
linepos = pos
pos = pos + 1
else
break
end
end
return "line " .. line .. ", column " .. (where - linepos)
end
local function unterminated (str, what, where)
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
end
local function scanwhite (str, pos)
while true do
pos = strfind (str, "%S", pos)
if not pos then return nil end
local sub2 = strsub (str, pos, pos + 1)
if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then
-- UTF-8 Byte Order Mark
pos = pos + 3
elseif sub2 == "//" then
pos = strfind (str, "[\n\r]", pos + 2)
if not pos then return nil end
elseif sub2 == "/*" then
pos = strfind (str, "*/", pos + 2)
if not pos then return nil end
pos = pos + 2
else
return pos
end
end
end
local escapechars = {
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
}
local function unichar (value)
if value < 0 then
return nil
elseif value <= 0x007f then
return strchar (value)
elseif value <= 0x07ff then
return strchar (0xc0 + floor(value/0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0xffff then
return strchar (0xe0 + floor(value/0x1000),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0x10ffff then
return strchar (0xf0 + floor(value/0x40000),
0x80 + (floor(value/0x1000) % 0x40),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
else
return nil
end
end
local function scanstring (str, pos)
local lastpos = pos + 1
local buffer, n = {}, 0
while true do
local nextpos = strfind (str, "[\"\\]", lastpos)
if not nextpos then
return unterminated (str, "string", pos)
end
if nextpos > lastpos then
n = n + 1
buffer[n] = strsub (str, lastpos, nextpos - 1)
end
if strsub (str, nextpos, nextpos) == "\"" then
lastpos = nextpos + 1
break
else
local escchar = strsub (str, nextpos + 1, nextpos + 1)
local value
if escchar == "u" then
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
if value then
local value2
if 0xD800 <= value and value <= 0xDBff then
-- we have the high surrogate of UTF-16. Check if there is a
-- low surrogate escaped nearby to combine them.
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
else
value2 = nil -- in case it was out of range for a low surrogate
end
end
end
value = value and unichar (value)
if value then
if value2 then
lastpos = nextpos + 12
else
lastpos = nextpos + 6
end
end
end
end
if not value then
value = escapechars[escchar] or escchar
lastpos = nextpos + 2
end
n = n + 1
buffer[n] = value
end
end
if n == 1 then
return buffer[1], lastpos
elseif n > 1 then
return concat (buffer), lastpos
else
return "", lastpos
end
end
local scanvalue -- forward declaration
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
local len = strlen (str)
local tbl, n = {}, 0
local pos = startpos + 1
if what == 'object' then
setmetatable (tbl, objectmeta)
else
setmetatable (tbl, arraymeta)
end
while true do
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
local char = strsub (str, pos, pos)
if char == closechar then
return tbl, pos + 1
end
local val1, err
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
if char == ":" then
if val1 == nil then
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
end
pos = scanwhite (str, pos + 1)
if not pos then return unterminated (str, what, startpos) end
local val2
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
tbl[val1] = val2
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
else
n = n + 1
tbl[n] = val1
end
if char == "," then
pos = pos + 1
end
end
end
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
pos = pos or 1
pos = scanwhite (str, pos)
if not pos then
return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
end
local char = strsub (str, pos, pos)
if char == "{" then
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
elseif char == "[" then
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
elseif char == "\"" then
return scanstring (str, pos)
else
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
if pstart then
local number = str2num (strsub (str, pstart, pend))
if number then
return number, pend + 1
end
end
pstart, pend = strfind (str, "^%a%w*", pos)
if pstart then
local name = strsub (str, pstart, pend)
if name == "true" then
return true, pend + 1
elseif name == "false" then
return false, pend + 1
elseif name == "null" then
return nullval, pend + 1
end
end
return nil, pos, "no valid JSON value at " .. loc (str, pos)
end
end
local function optionalmetatables(...)
if select("#", ...) > 0 then
return ...
else
return {__jsontype = 'object'}, {__jsontype = 'array'}
end
end
function json.decode (str, pos, nullval, ...)
local objectmeta, arraymeta = optionalmetatables(...)
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
end
function json.use_lpeg ()
local g = require ("lpeg")
if g.version() == "0.11" then
error "due to a bug in LPeg 0.11, it cannot be used for JSON matching"
end
local pegmatch = g.match
local P, S, R = g.P, g.S, g.R
local function ErrorCall (str, pos, msg, state)
if not state.msg then
state.msg = msg .. " at " .. loc (str, pos)
state.pos = pos
end
return false
end
local function Err (msg)
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
end
local SingleLineComment = P"//" * (1 - S"\n\r")^0
local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/"
local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0
local PlainChar = 1 - S"\"\\\n\r"
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
local HexDigit = R("09", "af", "AF")
local function UTF16Surrogate (match, pos, high, low)
high, low = tonumber (high, 16), tonumber (low, 16)
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
else
return false
end
end
local function UTF16BMP (hex)
return unichar (tonumber (hex, 16))
end
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
local Char = UnicodeEscape + EscapeSequence + PlainChar
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
local Fractal = P"." * R"09"^0
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
local SimpleValue = Number + String + Constant
local ArrayContent, ObjectContent
-- The functions parsearray and parseobject parse only a single value/pair
-- at a time and store them directly to avoid hitting the LPeg limits.
local function parsearray (str, pos, nullval, state)
local obj, cont
local npos
local t, nt = {}, 0
repeat
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
if not npos then break end
pos = npos
nt = nt + 1
t[nt] = obj
until cont == 'last'
return pos, setmetatable (t, state.arraymeta)
end
local function parseobject (str, pos, nullval, state)
local obj, key, cont
local npos
local t = {}
repeat
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
if not npos then break end
pos = npos
t[key] = obj
until cont == 'last'
return pos, setmetatable (t, state.objectmeta)
end
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
local Value = Space * (Array + Object + SimpleValue)
local ExpectedValue = Value + Space * Err "value expected"
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local DecodeValue = ExpectedValue * g.Cp ()
function json.decode (str, pos, nullval, ...)
local state = {}
state.objectmeta, state.arraymeta = optionalmetatables(...)
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
if state.msg then
return nil, state.pos, state.msg
else
return obj, retpos
end
end
-- use this function only once:
json.use_lpeg = function () return json end
json.using_lpeg = true
return json -- so you can get the module using json = require "dkjson".use_lpeg()
end
if always_try_using_lpeg then
pcall (json.use_lpeg)
end
return json

View File

@ -0,0 +1,53 @@
local naughty = require("naughty")
local wibox = require("wibox")
local json = require("lanxu/dkjson")
local gears = require("gears")
local focused = require("awful.screen").focused
local easy_async = require("awful.spawn").easy_async
local function factory(args)
local args = args or {}
local calluri = args.uri or "https://api.ipify.org"
local settings = args.settings or function() end
local homeaddress = args.homeaddress or nil
local ip = { widget = wibox.widget.textbox() }
ip.widget:set_markup("N/A")
function ip.attach(obj)
obj:connect_signal("button::press", function()
ip.update()
end)
end
function ip.update()
local cmd = string.format("curl -s " .. "'" .. calluri .. "'")
address = "N/A"
settings()
easy_async(cmd, function(response, stderr, reason, exit_code)
address = response
address = string.gsub(address, "[^0-9.]", "")
if address == homeaddress then
address = "Home"
end
ip.address = address
widget = ip.widget
settings()
end)
end
ip.attach(ip.widget)
address = "N/A"
settings()
ip.update()
return ip
end
return factory

View File

@ -0,0 +1,116 @@
local naughty = require("naughty")
local wibox = require("wibox")
local json = require("lanxu/dkjson")
local gears = require("gears")
local focused = require("awful.screen").focused
local easy_async = require("awful.spawn").easy_async
local function factory(args)
local args = args or {}
local timeout = args.timeout or 600
local calluri = args.uri or "https://masa.dy.fi/api/games/stats/minecraft/?type=server_status"
local minecraft = { widget = wibox.widget.textbox() }
local settings = args.settings or function() end
local hideempty = args.hideempty or false
local hideoffline = args.hideoffline or true
local followtag = args.followtag or true
local notification_preset = args.notification_preset or { font = "Monospace 10" }
minecraft.widget:set_markup("N/A")
function minecraft.show(tout)
minecraft.hide()
if followtag then
notification_preset.screen = focused()
end
minecraft.notification = naughty.notify({
text = minecraft.notification_text,
-- icon = minecraft.icon
timeout = 0,
preset = notification_preset,
})
end
function minecraft.hide()
if minecraft.notification then
naughty.destroy(minecraft.notification)
end
end
function minecraft.attach(obj)
obj:connect_signal("mouse::enter", function()
minecraft.show()
end)
obj:connect_signal("mouse::leave", function()
minecraft.hide()
end)
obj:connect_signal("button::press", function()
minecraft.update()
minecraft.show()
end)
end
function minecraft.update()
local cmd = string.format("curl -s " .. "'" .. calluri .. "'")
easy_async(cmd, function(response, stderr, reason, exit_code)
local obj, pos, err = json.decode(response, 1, nil)
totalplayers = 0
if not err then
-- First get the length of the longest server name, for proper column alignment
local max_len = 6 -- Initialize to the length of "Server"
for k, v in pairs(obj) do
if (tonumber(v.num_players) > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
local tmp = string.len(v.server_name)
if tmp > max_len then
max_len = tmp
end
end
end
local fmt = string.format("%%-%ds %%-8s %%-7s\n", max_len)
local text = string.format(fmt, "Server", "Version", "Players")
for k, v in pairs(obj) do
local players = tonumber(v.num_players)
if (players > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
text = text .. string.format(fmt, v.server_name, v.version, v.num_players)
if v.players then
for i, p in pairs(v.players) do
text = text .. ' > ' .. p .. '\n'
end
end
end
totalplayers = totalplayers + players
end
minecraft.notification_text = text
minecraft.totalplayers = totalplayers;
widget = minecraft.widget
settings()
end
end)
end
minecraft.attach(minecraft.widget)
gears.timer {
timeout = timeout,
autostart = true,
callback = minecraft.update
}
minecraft.update()
return minecraft
end
return factory

View File

@ -0,0 +1,23 @@
local json = require ("dkjson")
local https = require("ssl.https")
local url = "https://masa.dy.fi/~masa/testailu/mc_stats_dev/dev_json.php?type=server_status"
local response, error = https.request(url)
local obj, pos, err = json.decode (response, 1, nil)
local text = ""
for k, v in pairs(obj) do
text = text .. v.status .. "\t"
text = text .. v.version .. "\t"
text = text .. v.num_players .. "\t"
text = text .. v.server_name .. "\t"
text = text .. "\n"
if v.players then
for i, p in pairs(v.players) do
text = text .. '\t\t' .. p .. '\n'
end
end
end
print(text)

774
config/awesome/rc.lua Normal file
View File

@ -0,0 +1,774 @@
-- Standard awesome library
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
-- Widget and layout library
local wibox = require("wibox")
-- Theme handling library
local beautiful = require("beautiful")
-- Notification library
local naughty = require("naughty")
local menubar = require("menubar")
local hotkeys_popup = require("awful.hotkeys_popup").widget
local lain = require("lain")
naughty.config.defaults.timeout = 5
naughty.config.defaults.screen = 1
naughty.config.defaults.position = "top_right"
naughty.config.defaults.margin = 8
naughty.config.defaults.gap = 1
naughty.config.defaults.ontop = true
naughty.config.defaults.font = "sans 8"
naughty.config.defaults.icon = "/usr/share/icons/Adwaita/48x48/status/dialog-information.png"
naughty.config.defaults.icon_size = 48
naughty.config.defaults.fg = beautiful.fg_tooltip
naughty.config.defaults.bg = beautiful.bg_tooltip
naughty.config.defaults.border_color = beautiful.border_tooltip
naughty.config.defaults.border_width = 1
naughty.config.defaults.hover_timeout = nil
-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, there were errors during startup!",
text = awesome.startup_errors })
end
-- Handle runtime errors after startup
do
local in_error = false
awesome.connect_signal("debug::error", function (err)
-- Make sure we don't go into an endless error loop
if in_error then return end
in_error = true
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, an error happened!",
text = tostring(err) })
in_error = false
end)
end
-- }}}
-- {{{ Variable definitions
-- Themes define colours, icons, font and wallpapers.
beautiful.init(awful.util.getdir("config") .. "/themes/lanxu/theme.lua")
local widgets = require("widgets");
-- This is used later as the default terminal and editor to run.
terminal = "termite"
editor = os.getenv("EDITOR") or "vim"
editor_cmd = terminal .. " -e " .. editor
-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"
-- Table of layouts to cover with awful.layout.inc, order matters.
awful.layout.layouts = {
awful.layout.suit.floating,
awful.layout.suit.tile,
awful.layout.suit.tile.left,
awful.layout.suit.tile.bottom,
awful.layout.suit.tile.top,
awful.layout.suit.fair,
awful.layout.suit.fair.horizontal,
awful.layout.suit.spiral,
awful.layout.suit.spiral.dwindle,
awful.layout.suit.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier,
awful.layout.suit.corner.nw,
-- awful.layout.suit.corner.ne,
-- awful.layout.suit.corner.sw,
-- awful.layout.suit.corner.se,
}
-- }}}
-- {{{ Helper functions
local function client_menu_toggle_fn()
local instance = nil
return function ()
if instance and instance.wibox.visible then
instance:hide()
instance = nil
else
instance = awful.menu.clients({ theme = { width = 250 } })
end
end
end
-- }}}
-- {{{ Menu
-- Create a launcher widget and a main menu
myawesomemenu = {
{ "hotkeys", function() return false, hotkeys_popup.show_help end},
{ "manual", terminal .. " -e man awesome" },
{ "edit config", editor_cmd .. " " .. awesome.conffile },
{ "restart", awesome.restart },
{ "quit", function() awesome.quit() end}
}
lock = function()
-- Sync disks before lock (just in case)
awful.util.spawn("sync")
-- Lock screen
awful.util.spawn("xdg-screensaver lock")
--awful.util.spawn("xautolock -locknow")
--awful.util.spawn("xlock")
end
mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
{ "open terminal", terminal },
{ "lock", lock},
{ "suspend", "systemctl suspend"}
}
})
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
menu = mymainmenu })
-- Menubar configuration
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
-- }}}
-- Keyboard map indicator and switcher
mykeyboardlayout = awful.widget.keyboardlayout()
-- {{{ Wibar
-- Create a textclock widget
--mytextclock = wibox.widget.textclock()
-- Create a wibox for each screen and add it
local taglist_buttons = awful.util.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ modkey }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
)
local tasklist_buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
awful.button({ }, 3, client_menu_toggle_fn()),
awful.button({ }, 4, function ()
awful.client.focus.byidx(1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(-1)
end))
local function set_wallpaper(s)
-- Wallpaper
if beautiful.wallpaper then
local wallpaper = beautiful.wallpaper
-- If wallpaper is a function, call it with the screen
if type(wallpaper) == "function" then
wallpaper = wallpaper(s)
end
gears.wallpaper.maximized(wallpaper, s, true)
end
end
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
screen.connect_signal("property::geometry", set_wallpaper)
-- Tags
-- Define a tag table which hold all screen tags.
primary_screen = 1
secondary_screen = screen:count()
tags = {
names = {
'IRC',
'Code',
'Net',
'GFX',
'Other',
},
layout = {
awful.layout.layouts[3], -- 1:IRC
awful.layout.layouts[4], -- 2:Code
awful.layout.layouts[10], -- 3:Net
awful.layout.layouts[10], -- 4:GFX
awful.layout.layouts[1],
}
}
awful.screen.connect_for_each_screen(function(s)
-- Wallpaper
set_wallpaper(s)
-- Each screen has its own tag table.
--awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
tags[s] = awful.tag(tags.names, s, tags.layout)
-- Create a promptbox for each screen
s.mypromptbox = awful.widget.prompt()
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(awful.util.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
-- Create a taglist widget
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
-- Create a tasklist widget
s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
-- Create the wibox
s.mywibox = awful.wibar({ position = "top", screen = s })
local right_widgets = {
layout = wibox.layout.fixed.horizontal,
--mykeyboardlayout,
wibox.widget.systray(),
spacer,
--myserverstatus,
ipaddress,
spacer,
volume,
spacer,
mydpmsstatus,
spacer,
--mycloudstatus,
--spacer,
mycpu,
spacer,
mymem,
spacer,
myweather,
spacer,
mycputemp,
mygputemp,
mytextclock,
s.mylayoutbox,
}
-- Only show everything on the first screen
if s.index > 1 then
right_widgets = {
layout = wibox.layout.fixed.horizontal,
s.mylayoutbox,
}
end
-- Add widgets to the wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
mylauncher,
s.mytaglist,
s.mypromptbox,
},
s.mytasklist, -- Middle widget
right_widgets,
}
end)
-- }}}
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = awful.util.table.join(
awful.key({ modkey, }, "s", hotkeys_popup.show_help,
{description="show help", group="awesome"}),
awful.key({ modkey, }, "Left", awful.tag.viewprev,
{description = "view previous", group = "tag"}),
awful.key({ modkey, }, "Right", awful.tag.viewnext,
{description = "view next", group = "tag"}),
awful.key({ modkey, }, "Escape", awful.tag.history.restore,
{description = "go back", group = "tag"}),
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
end,
{description = "focus next by index", group = "client"}
),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
end,
{description = "focus previous by index", group = "client"}
),
awful.key({ modkey, }, "w", function () mymainmenu:show() end,
{description = "show main menu", group = "awesome"}),
awful.key({ modkey, "Shift" }, "l", lock,
{description = "lock screen", group = "screen"}),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
{description = "swap with next client by index", group = "client"}),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
{description = "swap with previous client by index", group = "client"}),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
{description = "focus the next screen", group = "screen"}),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
{description = "focus the previous screen", group = "screen"}),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
{description = "jump to urgent client", group = "client"}),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end,
{description = "go back", group = "client"}),
-- Standard program
awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
{description = "open a terminal", group = "launcher"}),
awful.key({ modkey, "Control" }, "r", awesome.restart,
{description = "reload awesome", group = "awesome"}),
awful.key({ modkey, "Shift" }, "q", awesome.quit,
{description = "quit awesome", group = "awesome"}),
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
{description = "increase master width factor", group = "layout"}),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
{description = "decrease master width factor", group = "layout"}),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
{description = "increase the number of master clients", group = "layout"}),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
{description = "decrease the number of master clients", group = "layout"}),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
{description = "increase the number of columns", group = "layout"}),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
{description = "decrease the number of columns", group = "layout"}),
awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
{description = "select next", group = "layout"}),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
{description = "select previous", group = "layout"}),
awful.key({ modkey, "Control" }, "n",
function ()
local c = awful.client.restore()
-- Focus restored client
if c then
client.focus = c
c:raise()
end
end,
{description = "restore minimized", group = "client"}),
-- Prompt
awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
{description = "run prompt", group = "launcher"}),
awful.key({ modkey }, "x",
function ()
awful.prompt.run {
prompt = "Run Lua code: ",
textbox = awful.screen.focused().mypromptbox.widget,
exe_callback = awful.util.eval,
history_path = awful.util.get_cache_dir() .. "/history_eval"
}
end,
{description = "lua execute prompt", group = "awesome"}),
-- Menubar
awful.key({ modkey }, "p", function() menubar.show() end,
{description = "show the menubar", group = "launcher"}),
-- Menubar (dmenu)
awful.key({ modkey }, "d",
function()
--awful.spawn(string.format("dmenu_run -i -b -l 20 -fn 'Fura Code Nerd Font:size=10:style=Regular'"))
awful.spawn(string.format("rofi -show combi -combi-modi 'window,run,ssh' -modi combi"))
end,
{description = "show the menubar", group = "launcher"})
)
clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f",
function (c)
c.fullscreen = not c.fullscreen
c:raise()
end,
{description = "toggle fullscreen", group = "client"}),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
{description = "close", group = "client"}),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
{description = "toggle floating", group = "client"}),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
{description = "move to master", group = "client"}),
awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
{description = "move to screen", group = "client"}),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
{description = "toggle keep on top", group = "client"}),
awful.key({ modkey, }, "n",
function (c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end ,
{description = "minimize", group = "client"}),
awful.key({ modkey, }, "m",
function (c)
c.maximized = not c.maximized
c:raise()
end ,
{description = "maximize", group = "client"})
)
local commands = {
print = false
}
-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, 9 do
globalkeys = awful.util.table.join(globalkeys,
-- View tag only.
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
tag:view_only()
end
end,
{description = "view tag #"..i, group = "tag"}),
-- Toggle tag display.
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
awful.tag.viewtoggle(tag)
end
end,
{description = "toggle tag #" .. i, group = "tag"}),
-- Move client to tag.
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:move_to_tag(tag)
end
end
end,
{description = "move focused client to tag #"..i, group = "tag"}),
-- Toggle tag on focused client.
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:toggle_tag(tag)
end
end
end,
{description = "toggle focused client on tag #" .. i, group = "tag"})
)
end
globalkeys = awful.util.table.join(globalkeys,
-- Pulseaudio
awful.key({ any }, "XF86AudioRaiseVolume", function()
awful.spawn(string.format("pactl set-sink-volume %s +1%%", volume.device))
volume.update()
end,
{description = "Raise audio volume", group = "audio"}), awful.key({ any }, "XF86AudioLowerVolume", function()
awful.spawn(string.format("pactl set-sink-volume %s -1%%", volume.device))
volume.update()
end,
{description = "Lower audio volume", group = "audio"}),
awful.key({ any }, "XF86AudioMute",
function()
awful.spawn(string.format("pactl set-sink-mute %s 1", volume.device))
volume.update()
end,
{description = "mute audio", group = "audio"}),
awful.key({ 'Shift' }, "XF86AudioMute",
function()
awful.spawn(string.format("pactl set-sink-mute %s 0", volume.device))
volume.update()
end,
{description = "unmute audio", group = "audio"}),
awful.key({ }, "Print",
function ()
--local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']]
for i=1,screen:count() do
local command = "bash -c 'flameshot screen -n ".. i-1 .." -p \"$(xdg-user-dir PICTURES)/\"'"
awful.spawn.easy_async(command, function(stdout, stderr)
--naughty.notify {
-- title = "Screenshot saved!",
-- text = stdout,
--}
end)
end
end,
{description = "Take screenshot", group = "video"}),
awful.key({ 'Shift' }, "Print",
function ()
--local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']]
for i=1,screen:count() do
local command = "bash -c 'flameshot gui -p \"$(xdg-user-dir PICTURES)/\"'"
awful.spawn.easy_async(command, function(stdout, stderr)
--naughty.notify {
-- title = "Screenshot saved!",
-- text = stdout,
--}
end)
end
end,
{description = "Take screenshot", group = "video"})
)
clientbuttons = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 3, awful.mouse.client.resize))
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
-- Rules to apply to new clients (through the "manage" signal).
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = awful.client.focus.filter,
raise = true,
keys = clientkeys,
buttons = clientbuttons,
screen = awful.screen.preferred,
placement = awful.placement.no_overlap+awful.placement.no_offscreen
}
},
-- Maximized clients.
{ rule_any = {
instance = {
},
class = {
"Zathura",
"MComix"
},
name = {
},
role = {
}
}, properties = {
floating = true,
maximized = true
}
},
-- Floating clients.
{ rule_any = {
instance = {
},
class = {
"Arandr",
"cantata",
"Steam",
"itch",
"Wine",
"mpv",
"Vlc",
"Sxiv",
"Plugin-container"
},
name = {
},
role = {
"pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
}
}, properties = {
floating = true
}
},
-- Add titlebars to normal clients and dialogs
{ rule_any = {type = { "normal", "dialog" }
}, properties = { titlebars_enabled = false }
},
-- Window positioning
{ rule = { class = "Chromium" },
properties = { screen = primary_screen, tag = "Net" } },
{ rule = { class = "Firefox" },
properties = { screen = primary_screen, tag = "Net" } },
{ rule = { class = "Inkscape" },
properties = { screen = primary_screen, tag = "GFX" } },
{ rule = { class = "Gimp" },
properties = { screen = primary_screen, tag = "GFX" } },
{ rule = { class = "Blender" },
properties = { screen = primary_screen, tag = "GFX" } },
{ rule = { class = "Steam", name = "Friends List" },
properties = { screen = secondary_screen, tag = "Other", width = 300, height = 800, x = 3530, y = 30 } },
{ rule = { class = "Steam", name = "Steam" },
properties = { screen = secondary_screen, tag = "Other" } },
}
-- }}}
-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c)
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- if not awesome.startup then awful.client.setslave(c) end
if awesome.startup and
not c.size_hints.user_position
and not c.size_hints.program_position then
-- Prevent clients from being unreachable after screen count changes.
awful.placement.no_offscreen(c)
end
end)
-- Add a titlebar if titlebars_enabled is set to true in the rules.
client.connect_signal("request::titlebars", function(c)
-- buttons for the titlebar
local buttons = awful.util.table.join(
awful.button({ }, 1, function()
client.focus = c
c:raise()
awful.mouse.client.move(c)
end),
awful.button({ }, 3, function()
client.focus = c
c:raise()
awful.mouse.client.resize(c)
end)
)
awful.titlebar(c) : setup {
{ -- Left
awful.titlebar.widget.iconwidget(c),
buttons = buttons,
layout = wibox.layout.fixed.horizontal
},
{ -- Middle
{ -- Title
align = "center",
widget = awful.titlebar.widget.titlewidget(c)
},
buttons = buttons,
layout = wibox.layout.flex.horizontal
},
{ -- Right
awful.titlebar.widget.floatingbutton (c),
awful.titlebar.widget.maximizedbutton(c),
awful.titlebar.widget.stickybutton (c),
awful.titlebar.widget.ontopbutton (c),
awful.titlebar.widget.closebutton (c),
layout = wibox.layout.fixed.horizontal()
},
layout = wibox.layout.align.horizontal
}
end)
-- Enable sloppy focus, so that focus follows mouse.
client.connect_signal("mouse::enter", function(c)
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and awful.client.focus.filter(c) then
client.focus = c
end
end)
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
-- }}}
local fullscreened_clients = {}
local function remove_client(tabl, c)
local index = awful.util.table.hasitem(tabl, c)
if index then
table.remove(tabl, index)
if #tabl == 0 then
awful.util.spawn("xset s blank")
awful.util.spawn("xset s on")
awful.util.spawn("xset +dpms")
naughty.notify({ preset = naughty.config.presets.low,
title = "DPMS information",
text = "Display power management is now back ON"})
end
end
end
client.connect_signal("property::fullscreen", function(c)
if c.fullscreen then
table.insert(fullscreened_clients, c)
if #fullscreened_clients == 1 then
awful.util.spawn("xset s noblank")
awful.util.spawn("xset s off")
awful.util.spawn("xset -dpms")
naughty.notify({
preset = naughty.config.presets.low,
title = "DPMS information",
text = "Display power management is now OFF"
})
end
else
remove_client(fullscreened_clients, c)
end
end)
client.connect_signal("unmanage", function(c)
if c.fullscreen then
remove_client(fullscreened_clients, c)
end
end)
awful.util.spawn_with_shell("run-once pasystray")
awful.util.spawn_with_shell("run-once blueman-applet")
awful.util.spawn_with_shell("run-once nm-applet")
awful.util.spawn_with_shell("run-once 'nextcloud --background'")
awful.util.spawn_with_shell("run-once 'udiskie --tray --notify --automount'")
awful.util.spawn_with_shell("run-once 'mpd /home/lanxu/.config/mpd/mpd.conf'")
awful.util.spawn_with_shell("run-once 'xscreensaver -no-splash'")
--awful.util.spawn_with_shell("run-once conky")
--awful.util.spawn_with_shell("run-once light-locker")
--awful.util.spawn_with_shell("run-once firefox-developer-edition")
--awful.util.spawn_with_shell("run-once firefox")
--awful.util.spawn_with_shell("run-once syncthing-gtk")

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

View File

@ -0,0 +1,127 @@
---------------------------
-- Default awesome theme --
---------------------------
local theme_assets = require("beautiful.theme_assets")
local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
local theme = {}
theme.dir = os.getenv("HOME") .. "/.config/awesome/themes/lanxu"
theme.wallpaper = theme.dir .. "/background.png"
theme.font = "Fira Sans 10"
theme.bg_normal = "#222222"
theme.bg_focus = "#8A2BE2"
theme.bg_urgent = "#ff0000"
theme.bg_minimize = "#444444"
theme.bg_systray = theme.bg_normal
theme.fg_normal = "#d0bce2"
theme.fg_focus = "#ffffff"
theme.fg_urgent = "#ffffff"
theme.fg_minimize = "#ffffff"
theme.useless_gap = dpi(0)
theme.border_width = dpi(1)
theme.border_normal = "#000000"
theme.border_focus = "#535d6c"
theme.border_marked = "#91231c"
theme.wibar_height = 20
-- theme.wibar_border_width = 2
-- theme.wibar_border_color = "#222222"
-- There are other variable sets
-- overriding the default one when
-- defined, the sets are:
-- taglist_[bg|fg]_[focus|urgent|occupied|empty]
-- tasklist_[bg|fg]_[focus|urgent]
-- titlebar_[bg|fg]_[normal|focus]
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
-- Example:
--theme.taglist_bg_focus = "#ff0000"
-- Display the taglist squares
--theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png"
--theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png"
local taglist_square_size = dpi(4)
theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
taglist_square_size, theme.fg_normal
)
theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
taglist_square_size, theme.fg_normal
)
-- Variables set for theming the menu:
-- menu_[bg|fg]_[normal|focus]
-- menu_[border_color|border_width]
theme.menu_submenu_icon = theme.dir .. "/submenu.png"
theme.menu_height = dpi(15)
theme.menu_width = dpi(100)
-- You can add as many variables as
-- you wish and access them by using
-- beautiful.variable in your rc.lua
--theme.bg_widget = "#cc0000"
-- Define the image to load
theme.titlebar_close_button_normal = theme.dir .. "/titlebar/close_normal.png"
theme.titlebar_close_button_focus = theme.dir .. "/titlebar/close_focus.png"
theme.titlebar_minimize_button_normal = theme.dir .. "/titlebar/minimize_normal.png"
theme.titlebar_minimize_button_focus = theme.dir .. "/titlebar/minimize_focus.png"
theme.titlebar_ontop_button_normal_inactive = theme.dir .. "/titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive = theme.dir .. "/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_active = theme.dir .. "/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_active = theme.dir .. "/titlebar/ontop_focus_active.png"
theme.titlebar_sticky_button_normal_inactive = theme.dir .. "/titlebar/sticky_normal_inactive.png"
theme.titlebar_sticky_button_focus_inactive = theme.dir .. "/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_active = theme.dir .. "/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_active = theme.dir .. "/titlebar/sticky_focus_active.png"
theme.titlebar_floating_button_normal_inactive = theme.dir .. "/titlebar/floating_normal_inactive.png"
theme.titlebar_floating_button_focus_inactive = theme.dir .. "/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_active = theme.dir .. "/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active = theme.dir .. "/titlebar/floating_focus_active.png"
theme.titlebar_maximized_button_normal_inactive = theme.dir .. "/titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive = theme.dir .. "/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active = theme.dir .. "/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_active = theme.dir .. "/titlebar/maximized_focus_active.png"
theme.wallpaper = theme.dir .. "/background.png"
-- You can use your own layout icons like this:
theme.layout_fairh = theme.dir .. "/layouts/fairhw.png"
theme.layout_fairv = theme.dir .. "/layouts/fairvw.png"
theme.layout_floating = theme.dir .. "/layouts/floatingw.png"
theme.layout_magnifier = theme.dir .. "/layouts/magnifierw.png"
theme.layout_max = theme.dir .. "/layouts/maxw.png"
theme.layout_fullscreen = theme.dir .. "/layouts/fullscreenw.png"
theme.layout_tilebottom = theme.dir .. "/layouts/tilebottomw.png"
theme.layout_tileleft = theme.dir .. "/layouts/tileleftw.png"
theme.layout_tile = theme.dir .. "/layouts/tilew.png"
theme.layout_tiletop = theme.dir .. "/layouts/tiletopw.png"
theme.layout_spiral = theme.dir .. "/layouts/spiralw.png"
theme.layout_dwindle = theme.dir .. "/layouts/dwindlew.png"
theme.layout_cornernw = theme.dir .. "/layouts/cornernww.png"
theme.layout_cornerne = theme.dir .. "/layouts/cornernew.png"
theme.layout_cornersw = theme.dir .. "/layouts/cornersww.png"
theme.layout_cornerse = theme.dir .. "/layouts/cornersew.png"
theme.awesome_icon = theme_assets.awesome_icon(
theme.menu_height, theme.bg_focus, theme.fg_focus
)
--theme.awesome_icon = theme.dir .. "/logo16.png"
-- Define the icon theme for application icons. If not set then the icons
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = nil
return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

172
config/awesome/widgets.lua Normal file
View File

@ -0,0 +1,172 @@
local gputemp = require("gputemp")
local hubic = require("hubic")
local dpmsstatus = require("dpmsstatus")
local lain = require("lain")
local vicious = require("vicious") -- Custom
local beautiful = require("beautiful") -- CPU temp
local wibox = require("wibox")
local gears = require("gears")
-- Variables
local valuecolor = "white"
icons_dir = os.getenv("HOME") .. "/.config/awesome/themes/lanxu/icons/"
cpuicon = wibox.widget.imagebox()
cpuicon.image = icons_dir .. "cpu.png"
cpuicon.resize = false
-- Helpers
function file_exists(name)
local f = io.open(name,"r")
if f ~= nil then io.close(f) return true else return false end
end
function create_markup(key, value, postfix, color)
return key .. " <span foreground='" .. color .. "'><b>" .. value .. postfix .."</b></span>"
end
-- Spacer
spacer = wibox.widget.textbox()
--spacer.text = "-"
spacer.forced_width = 8;
-- CPU
mycpu = lain.widget.cpu({
settings = function()
widget.markup = create_markup("CPU", cpu_now.usage, " %", valuecolor)
end
})
-- MEM
mymem = lain.widget.mem({
settings = function()
widget.markup = create_markup("MEM", mem_now.used, " MB", valuecolor)
end
})
-- GPU
mygputemp_text = wibox.widget.textbox()
mygputemp_text.align = "center"
vicious.register(mygputemp_text, gputemp,
function(widget, args)
temp = string.format("%.0f", tonumber(args[0]))
return create_markup("", temp, "", valuecolor)
end, 15, "AMD")
mygputemp = wibox.container.background()
mygputemp.forced_width = 70
mygputemp:set_widget(mygputemp_text)
--mytextclock:set_shape(gears.shape.hexagon)
mygputemp:set_bg('#5e35b1')
-- Hubic
myhubic = wibox.widget.textbox()
vicious.register(myhubic, hubic, create_markup("CLOUD", "$0", "", valuecolor), 15, "HUBIC")
-- Volume
volume = lain.widget.pulse({
scallback = function()
return "pacmd list-sinks | grep -Paoz \"(?s)(\\* index.*$(pactl info | grep -e 'ink' | cut -d' ' -f3).*(index)?)\" | tr -d '\\000' | grep -e 'index' -e 'device.string' -e 'name:' -e 'volume: front' -e 'muted'"
end,
settings = function()
volstr = volume_now.left .. " "
volcolor = valuecolor
if volume_now.muted == "yes" then
volcolor = "red"
end
widget.markup = create_markup("VOL", volstr, "%", volcolor)
end
})
-- Text clock
mytextclock_text = wibox.widget.textclock(create_markup("","%Y-%m-%d %H:%M","", valuecolor))
mytextclock_text.align = "center"
lain.widget.cal({
followtag = true,
attach_to = {mytextclock_text},
notification_preset = {
font = "Monospace 11", fg = "#FFFFFF", bg = "#000000"
}
})
mytextclock = wibox.container.background()
mytextclock.forced_width = 130
mytextclock:set_widget(mytextclock_text)
mytextclock:set_bg('#512da8')
-- CPU temperature
local tempfile = "/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon1/temp1_input"
if file_exists(tempfile) == false then
tempfile = "/sys/class/thermal/thermal_zone0/temp"
end
mycputemp_text = lain.widget.temp({
tempfile = tempfile,
settings = function()
temp = string.format("%.0f", tonumber(coretemp_now))
widget.markup = create_markup("", temp, "", valuecolor)
end
})
mycputemp_text.widget.align = "center"
mycputemp = wibox.container.background()
mycputemp.forced_width = 70
mycputemp:set_widget(mycputemp_text.widget)
mycputemp:set_bg('#9575cd')
-- Weather Widget
myweather = lain.widget.weather({
city_id = 634963,
lang = "fi",
followtag = true,
settings = function()
widget.markup = create_markup("Tampere", weather_now.main.temp, "", valuecolor)
end,
notification_preset = {
font = "Monospace 11", fg = "#FFFFFF", bg = "#000000"
}
})
-- DPMS
mydpmsstatus = wibox.widget.textbox()
-- mydpmsstatus.container.background.bg = '#ff0000'
--mydpmsstatus = {
-- widget = wibox.widget.textbox
--}
vicious.register(mydpmsstatus, dpmsstatus, function(widget, args)
color = valuecolor
if args[0] == "Enabled" then
return create_markup("DPMS", "ON", "", color)
else
color = "red"
return create_markup("DPMS", "OFF", "", color)
end
end)
local notification = {
font = "Monospace 10"
}
-- Servers
--local mcstatus = require("lanxu/mcstatus")
--myserverstatus = mcstatus({
--notification_preset = notification,
--settings = function()
--widget.markup = create_markup("PLAYERS", totalplayers, "", valuecolor)
--end
--})
--local cloudstatus = require("lanxu/cloudstatus")
--mycloudstatus = cloudstatus({
--notification_preset = notification,
--settings = function()
--widget.markup = create_markup("CLOUD", currentstatus, "", valuecolor)
--end
--})
local ip = require("lanxu/ip")
ipaddress = ip({
homeaddress = "91.157.104.247",
settings = function()
widget.markup = create_markup("IP", address, "", valuecolor)
end
})

View File

@ -0,0 +1,9 @@
# menu = { shadow = false; };
dropdown_menu = { shadow = false; };
popup_menu = { shadow = false; };
utility = { shadow = false; };
opacity-rule = [
"95:class_g = 'kitty' && focused",
"80:class_g = 'kitty' && !focused"
];

425
config/dunst/dunstrc Normal file
View File

@ -0,0 +1,425 @@
[global]
### Display ###
# Which monitor should the notifications be displayed on.
monitor = 0
# Display notification on focused monitor. Possible modes are:
# mouse: follow mouse pointer
# keyboard: follow window with keyboard focus
# none: don't follow anything
#
# "keyboard" needs a window manager that exports the
# _NET_ACTIVE_WINDOW property.
# This should be the case for almost all modern window managers.
#
# If this option is set to mouse or keyboard, the monitor option
# will be ignored.
follow = mouse
# The geometry of the window:
# [{width}]x{height}[+/-{x}+/-{y}]
# The geometry of the message window.
# The height is measured in number of notifications everything else
# in pixels. If the width is omitted but the height is given
# ("-geometry x2"), the message window expands over the whole screen
# (dmenu-like). If width is 0, the window expands to the longest
# message displayed. A positive x is measured from the left, a
# negative from the right side of the screen. Y is measured from
# the top and down respectively.
# The width can be negative. In this case the actual width is the
# screen width minus the width defined in within the geometry option.
geometry = "300x5-30+20"
# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes
# Shrink window if it's smaller than the width. Will be ignored if
# width is 0.
shrink = no
# The transparency of the window. Range: [0; 100].
# This option will only work if a compositing window manager is
# present (e.g. xcompmgr, compiz, etc.).
transparency = 5
# The height of the entire notification. If the height is smaller
# than the font height and padding combined, it will be raised
# to the font height and padding.
notification_height = 0
# Draw a line of "separator_height" pixel height between two
# notifications.
# Set to 0 to disable.
separator_height = 2
# Padding between text and separator.
padding = 10
# Horizontal padding.
horizontal_padding = 8
# Defines width in pixels of frame around the notification window.
# Set to 0 to disable.
frame_width = 3
# Defines color of the frame around the notification window.
#frame_color = "#aaaaaa"
frame_color = foreground
# Define a color for the separator.
# possible values are:
# * auto: dunst tries to find a color fitting to the background;
# * foreground: use the same color as the foreground;
# * frame: use the same color as the frame;
# * anything else will be interpreted as a X color.
separator_color = frame
# Sort messages by urgency.
sort = yes
# Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds.
# Set to 0 to disable.
# A client can set the 'transient' hint to bypass this. See the rules
# section for how to disable this if necessary
idle_threshold = 120
### Text ###
font = Monospace 10
# The spacing between lines. If the height is smaller than the
# font height, it will get raised to the font height.
line_height = 0
# Possible values are:
# full: Allow a small subset of html markup in notifications:
# <b>bold</b>
# <i>italic</i>
# <s>strikethrough</s>
# <u>underline</u>
#
# For a complete reference see
# <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
#
# strip: This setting is provided for compatibility with some broken
# clients that send markup even though it's not enabled on the
# server. Dunst will try to strip the markup but the parsing is
# simplistic so using this option outside of matching rules for
# specific applications *IS GREATLY DISCOURAGED*.
#
# no: Disable markup parsing, incoming notifications will be treated as
# plain text. Dunst will not advertise that it has the body-markup
# capability if this is set as a global setting.
#
# It's important to note that markup inside the format option will be parsed
# regardless of what this is set to.
markup = full
# The format of the message. Possible variables are:
# %a appname
# %s summary
# %b body
# %i iconname (including its path)
# %I iconname (without its path)
# %p progress value if set ([ 0%] to [100%]) or nothing
# %n progress value if set without any extra characters
# %% Literal %
# Markup is allowed
format = "<b>%s</b>\n%b"
# Alignment of message text.
# Possible values are "left", "center" and "right".
alignment = left
# Show age of message if message is older than show_age_threshold
# seconds.
# Set to -1 to disable.
show_age_threshold = 60
# Split notifications into multiple lines if they don't fit into
# geometry.
word_wrap = yes
# When word_wrap is set to no, specify where to make an ellipsis in long lines.
# Possible values are "start", "middle" and "end".
ellipsize = middle
# Ignore newlines '\n' in notifications.
ignore_newline = no
# Stack together notifications with the same content
stack_duplicates = true
# Hide the count of stacked notifications with the same content
hide_duplicate_count = false
# Display indicators for URLs (U) and actions (A).
show_indicators = yes
### Icons ###
# Align icons left/right/off
icon_position = left
# Scale larger icons down to this size, set to 0 to disable
max_icon_size = 32
# Paths to default icons.
icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
### History ###
# Should a notification popped up from history be sticky or timeout
# as if it would normally do.
sticky_history = yes
# Maximum amount of notifications kept in history
history_length = 20
### Misc/Advanced ###
# dmenu path.
dmenu = /usr/bin/rofi -p dunst:
# Browser for opening urls in context menu.
browser = /usr/bin/firefox -new-tab
# Always run rule-defined scripts, even if the notification is suppressed
always_run_script = true
# Define the title of the windows spawned by dunst
title = Dunst
# Define the class of the windows spawned by dunst
class = Dunst
# Print a notification on startup.
# This is mainly for error detection, since dbus (re-)starts dunst
# automatically after a crash.
startup_notification = false
# Manage dunst's desire for talking
# Can be one of the following values:
# crit: Critical features. Dunst aborts
# warn: Only non-fatal warnings
# mesg: Important Messages
# info: all unimportant stuff
# debug: all less than unimportant stuff
verbosity = mesg
# Define the corner radius of the notification window
# in pixel size. If the radius is 0, you have no rounded
# corners.
# The radius will be automatically lowered if it exceeds half of the
# notification height to avoid clipping text and/or icons.
corner_radius = 0
### Legacy
# Use the Xinerama extension instead of RandR for multi-monitor support.
# This setting is provided for compatibility with older nVidia drivers that
# do not support RandR and using it on systems that support RandR is highly
# discouraged.
#
# By enabling this setting dunst will not be able to detect when a monitor
# is connected or disconnected which might break follow mode if the screen
# layout changes.
force_xinerama = false
### mouse
# Defines action of mouse event
# Possible values are:
# * none: Don't do anything.
# * do_action: If the notification has exactly one action, or one is marked as default,
# invoke it. If there are multiple and no default, open the context menu.
# * close_current: Close current notification.
# * close_all: Close all notifications.
mouse_left_click = close_current
mouse_middle_click = do_action
mouse_right_click = close_all
# Experimental features that may or may not work correctly. Do not expect them
# to have a consistent behaviour across releases.
[experimental]
# Calculate the dpi to use on a per-monitor basis.
# If this setting is enabled the Xft.dpi value will be ignored and instead
# dunst will attempt to calculate an appropriate dpi value for each monitor
# using the resolution and physical size. This might be useful in setups
# where there are multiple screens with very different dpi values.
per_monitor_dpi = false
[shortcuts]
# Shortcuts are specified as [modifier+][modifier+]...key
# Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
# "mod3" and "mod4" (windows-key).
# Xev might be helpful to find names for keys.
# Close notification.
close = ctrl+space
# Close all notifications.
close_all = ctrl+shift+space
# Redisplay last message(s).
# On the US keyboard layout "grave" is normally above TAB and left
# of "1". Make sure this key actually exists on your keyboard layout,
# e.g. check output of 'xmodmap -pke'
history = ctrl+grave
# Context menu.
context = ctrl+shift+period
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the "#" and following would be interpreted as a comment.
# background = "#222222"
# foreground = "#888888"
background = "#fdf6e3"
foreground = "#93a1a1"
frame_color = "#93a1a1"
timeout = 10
# Icon for notifications with low urgency, uncomment to enable
#icon = /path/to/icon
[urgency_normal]
background = "#fdf6e3"
foreground = "#002b36"
frame_color = "#002b36"
timeout = 10
# Icon for notifications with normal urgency, uncomment to enable
#icon = /path/to/icon
[urgency_critical]
#background = "#900000"
#foreground = "#ffffff"
#frame_color = "#ff0000"
background = "#dc322f"
foreground = "#eee8d5"
frame_color = "#cb4b16"
timeout = 0
# Icon for notifications with critical urgency, uncomment to enable
#icon = /path/to/icon
# Every section that isn't one of the above is interpreted as a rules to
# override settings for certain messages.
#
# Messages can be matched by
# appname (discouraged, see desktop_entry)
# body
# category
# desktop_entry
# icon
# match_transient
# msg_urgency
# stack_tag
# summary
#
# and you can override the
# background
# foreground
# format
# frame_color
# fullscreen
# new_icon
# set_stack_tag
# set_transient
# timeout
# urgency
#
# Shell-like globbing will get expanded.
#
# Instead of the appname filter, it's recommended to use the desktop_entry filter.
# GLib based applications export their desktop-entry name. In comparison to the appname,
# the desktop-entry won't get localized.
#
# SCRIPTING
# You can specify a script that gets run when the rule matches by
# setting the "script" option.
# The script will be called as follows:
# script appname summary body icon urgency
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
#
# NOTE: if you don't want a notification to be displayed, set the format
# to "".
# NOTE: It might be helpful to run dunst -print in a terminal in order
# to find fitting options for rules.
# Disable the transient hint so that idle_threshold cannot be bypassed from the
# client
#[transient_disable]
# match_transient = yes
# set_transient = no
#
# Make the handling of transient notifications more strict by making them not
# be placed in history.
#[transient_history_ignore]
# match_transient = yes
# history_ignore = yes
# fullscreen values
# show: show the notifications, regardless if there is a fullscreen window opened
# delay: displays the new notification, if there is no fullscreen window active
# If the notification is already drawn, it won't get undrawn.
# pushback: same as delay, but when switching into fullscreen, the notification will get
# withdrawn from screen again and will get delayed like a new notification
#[fullscreen_delay_everything]
# fullscreen = delay
#[fullscreen_show_critical]
# msg_urgency = critical
# fullscreen = show
#[espeak]
# summary = "*"
# script = dunst_espeak.sh
#[script-test]
# summary = "*script*"
# script = dunst_test.sh
#[ignore]
# # This notification will not be displayed
# summary = "foobar"
# format = ""
#[history-ignore]
# # This notification will not be saved in history
# summary = "foobar"
# history_ignore = yes
#[skip-display]
# # This notification will not be displayed, but will be included in the history
# summary = "foobar"
# skip_display = yes
#[signed_on]
# appname = Pidgin
# summary = "*signed on*"
# urgency = low
#
#[signed_off]
# appname = Pidgin
# summary = *signed off*
# urgency = low
#
#[says]
# appname = Pidgin
# summary = *says*
# urgency = critical
#
#[twitter]
# appname = Pidgin
# summary = *twitter.com*
# urgency = normal
#
#[stack-volumes]
# appname = "some_volume_notifiers"
# set_stack_tag = "volume"
#
# vim: ft=cfg
[sound]
summary = "*"
script = ~/Scripts/dunst_message.sh

View File

@ -0,0 +1,112 @@
<fontconfig>
<match target="font">
<!-- If the requested font is Bitstream Vera Serif -->
<test name="family" compare="eq">
<string>Bitstream Vera Serif</string>
</test>
<!-- Replace the entire match list with Bitstream Vera Serif alone -->
<edit name="family" mode="assign_replace">
<string>Bitstream Vera Serif</string>
</edit>
<!-- Assign the serif family -->
<edit name="family" mode="append_last">
<string>serif</string>
</edit>
</match>
<match>
<!-- If the requested font is serif -->
<test qual="any" name="family">
<string>serif</string>
</test>
<!-- Make Bitstream Vera Serif the first result -->
<edit name="family" mode="prepend_first">
<string>Bitstream Vera Serif</string>
</edit>
<!-- Followed by Noto Color Emoji -->
<edit name="family" mode="prepend_first">
<string>Noto Color Emoji</string>
</edit>
</match>
<match target="font">
<!-- If the requested font is Bitstream Vera Sans -->
<test name="family" compare="eq">
<string>Bitstream Vera Sans</string>
</test>
<!-- Replace the entire match list with Bitstream Vera Sans alone -->
<edit name="family" mode="assign_replace">
<string>Bitstream Vera Sans</string>
</edit>
<!-- Assign the sans-serif family -->
<edit name="family" mode="append_last">
<string>sans-serif</string>
</edit>
</match>
<match target="pattern">
<!-- If the requested font is sans-serif -->
<test qual="any" name="family">
<string>sans-serif</string>
</test>
<!-- Make Bitstream Vera Sans the first result -->
<edit name="family" mode="prepend_first">
<string>Bitstream Vera Sans</string>
</edit>
<!-- Followed by Noto Color Emoji -->
<edit name="family" mode="prepend_first">
<string>Noto Color Emoji</string>
</edit>
</match>
<match target="font">
<!-- If the requested font is Bitstream Vera Sans Mono -->
<test name="family" compare="eq">
<string>Bitstream Vera Sans Mono</string>
</test>
<!-- Replace the entire match list with Bitstream Vera Sans Mono alone -->
<edit name="family" mode="assign_replace">
<string>Bitstream Vera Sans Mono</string>
</edit>
<!-- Assign the monospace family last -->
<edit name="family" mode="append_last">
<string>monospace</string>
</edit>
</match>
<match target="pattern">
<!-- If the requested font is monospace -->
<test qual="any" name="family">
<string>monospace</string>
</test>
<!--
Make Bitstream Vera Sans Mono the first result
Note: If you want a different monospace font, this is where you change it.
-->
<edit name="family" mode="prepend_first">
<string>Bitstream Vera Sans Mono</string>
</edit>
<!-- Followed by Noto Color Emoji -->
<edit name="family" mode="prepend_first">
<string>Noto Color Emoji</string>
</edit>
</match>
<!-- Add emoji generic family -->
<alias binding="strong">
<family>emoji</family>
<default><family>Noto Color Emoji</family></default>
</alias>
<!-- Alias requests for the other emoji fonts -->
<alias binding="strong">
<family>Apple Color Emoji</family>
<prefer><family>Noto Color Emoji</family></prefer>
<default><family>sans-serif</family></default>
</alias>
<alias binding="strong">
<family>Segoe UI Emoji</family>
<prefer><family>Noto Color Emoji</family></prefer>
<default><family>sans-serif</family></default>
</alias>
</fontconfig>

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Priority:
! 1. The generic family OR specific family
! 2. The emoji font family (defined in 60-generic.conf)
! 3. All the rest
!-->
<alias binding="weak">
<family>monospace</family>
<prefer>
<family>emoji</family>
<family>Liberation Mono</family>
<family>Fira Mono</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Priority:
! 1. The generic family OR specific family
! 2. The emoji font family (defined in 60-generic.conf)
! 3. All the rest
!-->
<alias binding="weak">
<family>sans-serif</family>
<prefer>
<family>emoji</family>
</prefer>
</alias>
<alias binding="weak">
<family>serif</family>
<prefer>
<family>emoji</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
! Sorry DejaVu... but you're treadin' on my emoji!
! I've gotta keep you around for package dependency reasons, though.
!-->
<selectfont>
<rejectfont>
<pattern>
<patelt name="family">
<string>DejaVu Sans</string>
</patelt>
</pattern>
<pattern>
<patelt name="family">
<string>DejaVu Serif</string>
</patelt>
</pattern>
<pattern>
<patelt name="family">
<string>DejaVu Sans Mono</string>
</patelt>
</pattern>
</rejectfont>
</selectfont>
</fontconfig>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
No to the baked-in Firefox emoji font.
Firefox version <= 60 uses EmojiOne Mozilla, while newer uses Twemoji Mozilla
-->
<selectfont>
<rejectfont>
<pattern>
<patelt name="family">
<string>EmojiOne Mozilla</string>
</patelt>
</pattern>
<pattern>
<patelt name="family">
<string>Twemoji Mozilla</string>
</patelt>
</pattern>
</rejectfont>
</selectfont>
</fontconfig>

View File

@ -0,0 +1,64 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<!--<edit mode="assign" name="autohint"><bool>true</bool></edit>
<edit mode="assign" name="hinting"><bool>true</bool></edit>-->
<edit mode="assign" name="autohint"><bool>true</bool></edit>
<edit mode="assign" name="hinting"><bool>true</bool></edit>
<edit mode="assign" name="lcdfilter"><const>lcddefault</const></edit>
<edit mode="assign" name="hintstyle"><const>hintnone</const></edit>
<!-- symbols do not support antialias -->
<!-- Removed antialias because it made all emoji invisible -->
<edit mode="assign" name="rgba"><const>rgb</const></edit>
</match>
<match target="font">
<test name="pixelsize" qual="any" compare="more"><double>15</double></test>
<edit mode="assign" name="hintstyle"><const>hintnone</const></edit>
<edit mode="assign" name="lcdfilter"><const>lcdlight</const></edit>
</match>
<match target="font">
<test name="pixelsize" qual="any" compare="more"><double>12</double></test>
<edit mode="assign" name="hintstyle"><const>hintnone</const></edit>
<edit mode="assign" name="lcdfilter"><const>lcdlight</const></edit>
</match>
<match target="font">
<test name="slant" compare="not_eq"><double>0</double></test>
<edit mode="assign" name="hintstyle"><const>hintnone</const></edit>
<edit mode="assign" name="lcdfilter"><const>lcdlight</const></edit>
</match>
<match target="pattern">
<test qual="any" name="family"><string>verdana</string></test>
<edit name="family" mode="assign" binding="same"><string>Bitstream Vera Sans</string></edit>
</match>
<!-- Prefer Liberation -->
<alias>
<family>sans-serif</family>
<prefer>
<family>Liberation Sans</family>
</prefer>
<default><family>Liberation Sans</family></default>
</alias>
<alias>
<family>serif</family>
<prefer>
<family>Liberation Serif</family>
</prefer>
<default><family>Liberation Serif</family></default>
</alias>
<!-- Monospace fonts are handled by 69-emoji-monospace.conf -->
<!--
<alias>
<family>monospace</family>
<prefer>
<family>Liberation Mono</family>
</prefer>
<default><family>Liberation Mono</family></default>
</alias>
-->
</fontconfig>

View File

@ -0,0 +1,4 @@
#!/bin/sh
rm ./conf.d/70-no-dejavu.conf
echo "Removed configuration"

View File

@ -0,0 +1,51 @@
{
"extractor": {
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
"cookies": "~/cookies.txt",
"base-directory": "~/Lataukset/gallery-dl/",
"archive": "~/Lataukset/gallery-dl/archive.sqlite3",
"exhentai":
{
"filename": "{num:>04}_{name}.{extension}",
"directory": ["{category!c}", "{title}"],
"postprocessors": [
{
"name": "zip",
"compression": "store",
"extension": "cbz"
}
],
"wait-min": 1.0,
"wait-max": 5.0
}
},
"downloader": {
"part-directory": "/tmp/.download/",
"rate": "1M",
"retries": 3,
"timeout": 8.5
},
"output":
{
"mode": "terminal",
"log": {
"format": "{name}: {message}",
"level": "info"
},
"logfile": {
"path": "~/Lataukset/gallery-dl/log.txt",
"mode": "w",
"level": "debug"
},
"unsupportedfile": {
"path": "~/Lataukset/gallery-dl/unsupported.txt",
"mode": "a",
"format": "{asctime} {message}",
"format-date": "%Y-%m-%d-%H-%M-%S"
}
},
"cache": {
"file": "~/Lataukset/gallery-dl/cache.sqlite3"
}
}

BIN
config/i3/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

422
config/i3/config Normal file
View File

@ -0,0 +1,422 @@
# i3 config file (v4)
#
# Please see https://i3wm.org/docs/userguide.html for a complete reference!
#
# This config file uses keycodes (bindsym) and was written for the QWERTY
# layout.
#
# To get a config file with the same key positions, but for your current
# layout, use the i3-config-wizard
#
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
font pango:DejaVu Sans Mono 10
# This font is widely installed, provides lots of unicode glyphs, right-to-left
# text rendering and scalability on retina/hidpi displays (thanks to pango).
#font pango:DejaVu Sans Mono 8
# The combination of xss-lock, nm-applet and pactl is a popular choice, so
# they are included here as an example. Modify as you see fit.
# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
# screen before suspend. Use loginctl lock-session to lock your screen.
#exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
# NetworkManager is the most popular way to manage wireless networks on Linux,
# and nm-applet is a desktop environment-independent system tray GUI for it.
#exec --no-startup-id nm-applet
# Use pactl to adjust volume in PulseAudio.
set $refresh_i3status killall -SIGUSR1 i3status
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% && $refresh_i3status
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% && $refresh_i3status
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
# use these keys for focus, movement, and resize directions when reaching for
# the arrows is not convenient
set $up Up
set $down Down
set $left Left
set $right Right
# use Mouse+Mod4 to drag floating windows to their wanted position
floating_modifier Mod4
# start a terminal
bindsym Mod4+Return exec i3-sensible-terminal
# kill focused window
bindsym Mod4+Shift+q kill
# start dmenu (a program launcher)
#bindsym Mod1+d exec --no-startup-id dmenu_run
# A more modern dmenu replacement is rofi:
bindsym Mod4+d exec --no-startup-id "rofi -modi power:'/home/lanxu/.config/rofi/scripts/powermenu.sh',combi -combi-modi 'window,power,run,ssh' -show combi"
# There also is i3-dmenu-desktop which only displays applications shipping a
# .desktop file. It is a wrapper around dmenu, so you need that installed.
# bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop
# change focus
bindsym Mod4+$left focus left
bindsym Mod4+$down focus down
bindsym Mod4+$up focus up
bindsym Mod4+$right focus right
# alternatively, you can use the cursor keys:
#bindsym Mod4+Left focus left
#bindsym Mod4+Down focus down
#bindsym Mod4+Up focus up
#bindsym Mod4+Right focus right
# move focused window
bindsym Mod4+Shift+$left move left
bindsym Mod4+Shift+$down move down
bindsym Mod4+Shift+$up move up
bindsym Mod4+Shift+$right move right
# alternatively, you can use the cursor keys:
#bindsym Mod4+Shift+Left move left
#bindsym Mod4+Shift+Down move down
#bindsym Mod4+Shift+Up move up
#bindsym Mod4+Shift+Right move right
# split in horizontal orientation
bindsym Mod4+h split h
# split in vertical orientation
bindsym Mod4+v split v
# enter fullscreen mode for the focused container
bindsym Mod4+f fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindsym Mod4+s layout stacking
bindsym Mod4+w layout tabbed
bindsym Mod4+e layout toggle split
# toggle tiling / floating
bindsym Mod4+Shift+space floating toggle
# change focus between tiling / floating windows
bindsym Mod4+space focus mode_toggle
# focus the parent container
bindsym Mod4+a focus parent
# focus the child container
#bindsym Mod4+d focus child
# move the currently focused window to the scratchpad
bindsym Mod4+Shift+minus move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym Mod4+minus scratchpad show
# Define names for default workspaces for which we configure key bindings later on.
# We use variables to avoid repeating the names in multiple places.
set $ws1 "1:term"
set $ws2 "2:irc"
set $ws3 "3:net"
set $ws4 "4:gfx"
set $ws5 "5:steam"
set $ws6 "6:lutris"
set $ws7 "7:x"
set $ws8 "8:x"
set $ws9 "9:pw"
set $ws10 "10:tray"
# switch to workspace
bindsym Mod4+1 workspace $ws1
bindsym Mod4+2 workspace $ws2
bindsym Mod4+3 workspace $ws3
bindsym Mod4+4 workspace $ws4
bindsym Mod4+5 workspace $ws5
bindsym Mod4+6 workspace $ws6
bindsym Mod4+7 workspace $ws7
bindsym Mod4+8 workspace $ws8
bindsym Mod4+9 workspace $ws9
bindsym Mod4+0 workspace $ws10
# move focused container to workspace
bindsym Mod4+Shift+1 move container to workspace $ws1
bindsym Mod4+Shift+2 move container to workspace $ws2
bindsym Mod4+Shift+3 move container to workspace $ws3
bindsym Mod4+Shift+4 move container to workspace $ws4
bindsym Mod4+Shift+5 move container to workspace $ws5
bindsym Mod4+Shift+6 move container to workspace $ws6
bindsym Mod4+Shift+7 move container to workspace $ws7
bindsym Mod4+Shift+8 move container to workspace $ws8
bindsym Mod4+Shift+9 move container to workspace $ws9
bindsym Mod4+Shift+0 move container to workspace $ws10
# reload the configuration file
bindsym Mod4+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym Mod4+Shift+r restart
# exit i3 (logs you out of your X session)
bindsym Mod4+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {
# These bindings trigger as soon as you enter the resize mode
# Pressing left will shrink the windows width.
# Pressing right will grow the windows width.
# Pressing up will shrink the windows height.
# Pressing down will grow the windows height.
bindsym $left resize shrink width 10 px or 10 ppt
bindsym $down resize grow height 10 px or 10 ppt
bindsym $up resize shrink height 10 px or 10 ppt
bindsym $right resize grow width 10 px or 10 ppt
# same bindings, but for the arrow keys
bindsym Left resize shrink width 10 px or 10 ppt
bindsym Down resize grow height 10 px or 10 ppt
bindsym Up resize shrink height 10 px or 10 ppt
bindsym Right resize grow width 10 px or 10 ppt
# Back to normal: Enter or Escape or Mod4+r
bindsym Return mode "default"
bindsym Escape mode "default"
bindsym Mod4+r mode "default"
}
bindsym Mod1+r mode "resize"
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
#bar {
# status_command i3status
#}
#######################################################################
# automatically start i3-config-wizard to offer the user to create a
# keysym-based config which used their favorite modifier (alt or windows)
#
# i3-config-wizard will not launch if there already is a config file
# in ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) or
# ~/.i3/config.
#
# Please remove the following exec line:
#######################################################################
#exec i3-config-wizard
#######################################################################
# lanxu's modifications
#######################################################################
# Assignments
assign [class="^firefox$"] → $ws3
assign [class="^krita$"] → $ws4
assign [class="^Blender$"] → $ws4
assign [class="^Gimp$"] → $ws4
assign [class="^Lutris$"] → $ws6
assign [class="^Nextcloud$"] → $ws10
assign [class="^Blueman-manager$"] → $ws10
assign [class="^Pavucontrol$"] → $ws10
assign [class="^cantata$"] → $ws10
assign [class="^Boincmgr$"] → $ws10
assign [class="^KeePassXC$"] → $ws9
# Modifiers
for_window [class="^firefox$"] layout tabbed
for_window [class="Arandr"] floating enable
for_window [title="^Telegram$"] floating enable, move scratchpad
for_window [class="itch"] floating enable
# for_window [class="Wine"] floating enable
for_window [class="mpv"] floating enable, move position center
for_window [class="vlc"] floating enable
for_window [class="Mumble"] floating enable, move position center
for_window [class="Sxiv"] floating enable
# services
#for_window [class="Nextcloud"] floating enable, move position center, move scratchpad
for_window [class="cantata"] floating disable
for_window [class="boincmgr"] floating disable
# Games
for_window [class="kfgame.exe"] floating enable
for_window [class="Wine"] floating enable
for_window [class="xscreensaver-demo"] floating enable
# Steam
# https://github.com/ValveSoftware/steam-for-linux/issues/1040
for_window [class="^Steam$" title="^Friends$"] floating enable
for_window [class="^Steam$" title="Steam - News"] floating enable
for_window [class="^Steam$" title=".* - Chat"] floating enable
for_window [class="^Steam$" title="^Settings$"] floating enable
for_window [class="^Steam$" title=".* - event started"] floating enable
for_window [class="^Steam$" title=".* CD key"] floating enable
for_window [class="^Steam$" title="^Steam - Self Updater$"] floating enable
for_window [class="^Steam$" title="^Screenshot Uploader$"] floating enable
for_window [class="^Steam$" title="^Steam Guard - Computer Authorization Required$"] floating enable
for_window [title="^Steam Keyboard$"] floating enable
for_window [class="^Steam$"] move container to workspace $ws5
for_window [title="^Friends List$"] move container to workspace $ws5, floating enable, resize set width 400px
mouse_warping none
# Special keysyms
bindsym Mod4+t [class="TelegramDesktop"] scratchpad show
bindsym Mod4+n [class="^Nextcloud"] scratchpad show
# i3-gaps
#smart_borders on
#smart_gaps on
#gaps outer 0
#gaps inner 5
## Base16 Gruvbox dark, hard
# Author: Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
#
# You can use these variables anywhere in the i3 configuration file.
set $base00 #1d2021
set $base01 #3c3836
set $base02 #504945
set $base03 #665c54
set $base04 #bdae93
set $base05 #d5c4a1
set $base06 #ebdbb2
set $base07 #fbf1c7
set $base08 #fb4934
set $base09 #fe8019
set $base0A #fabd2f
set $base0B #b8bb26
set $base0C #8ec07c
set $base0D #83a598
set $base0E #d3869b
set $base0F #d65d0e
# https://github.com/khamer/base16-i3/tree/master/colors
## Base16 Solarized Light
# Author: Ethan Schoonover (modified by aramisgithub)
#
# You can use these variables anywhere in the i3 configuration file.
#set $base00 #fdf6e3
#set $base01 #eee8d5
#set $base02 #93a1a1
#set $base03 #839496
#set $base04 #657b83
#set $base05 #586e75
#set $base06 #073642
#set $base07 #002b36
#set $base08 #dc322f
#set $base09 #cb4b16
#set $base0A #b58900
#set $base0B #859900
#set $base0C #2aa198
#set $base0D #268bd2
#set $base0E #6c71c4
#set $base0F #d33682
## Base16 Solarized Dark
# Author: Ethan Schoonover (modified by aramisgithub)
#
# You can use these variables anywhere in the i3 configuration file.
#set $base00 #002b36
#set $base01 #073642
#set $base02 #586e75
#set $base03 #657b83
#set $base04 #839496
#set $base05 #93a1a1
#set $base06 #eee8d5
#set $base07 #fdf6e3
#set $base08 #dc322f
#set $base09 #cb4b16
#set $base0A #b58900
#set $base0B #859900
#set $base0C #2aa198
#set $base0D #268bd2
#set $base0E #6c71c4
#set $base0F #d33682
# Basic bar configuration using the Base16 variables.
bar {
font pango: DejaVu Sans Mono Bold 10
mode dock
status_command py3status
position top
i3bar_command i3bar -t
tray_output none
separator_symbol " "
colors {
background $base00
separator $base03
statusline $base04
# State Border BG Text
focused_workspace $base05 $base0D $base00
active_workspace $base05 $base03 $base05
inactive_workspace $base03 $base01 $base05
urgent_workspace $base08 $base08 $base00
binding_mode $base00 $base0A $base00
}
}
# Basic color configuration using the Base16 variables for windows and borders.
# Property Name Border BG Text Indicator Child Border
client.focused $base05 $base0D $base00 $base0D $base0C
client.focused_inactive $base01 $base01 $base05 $base03 $base01
client.unfocused $base01 $base00 $base05 $base01 $base01
client.urgent $base08 $base08 $base00 $base08 $base08
client.placeholder $base00 $base00 $base05 $base00 $base00
client.background $base07
default_border pixel 1
# Removes all borders
for_window [class=".*"] border pixel 1
#exec --no-startup-id "dunst" # in case multiple daemons are installed
#exec --no-startup-id "pasystray"
#exec --no-startup-id "blueman-applet"
#exec --no-startup-id "udiskie --tray --notify --automount"
# Services
exec --no-startup-id "mpd /home/lanxu/.config/mpd/mpd.conf" # Music Player Daemon
exec --no-startup-id xss-lock -- lock.sh
exec --no-startup-id "./Scripts/screensaver.sh" # Screensaver
#exec --no-startup-id "xscreensaver -no-splash" # Screensaver
#exec --no-startup-id "./Scripts/xscreensaverstopper.sh" # Screensaver inhibitor
#exec --no-startup-id "compton -b" # Compositor
exec --no-startup-id "nitrogen --restore" # Wallpaper
exec --no-startup-id "udiskie --notify --automount" # Automounter
# dunst is used for notifications
# Background software
#exec --no-startup-id "blueman-manager" # Bluetooth
exec --no-startup-id "cantata"
#exec --no-startup-id "boincmgr"
#exec --no-startup-id "nextcloud"
exec --no-startup-id "pavucontrol"
exec --no-startup-id "keepassxc" # Password manager
# Applications
exec --no-startup-id "telegram-desktop"
# Set manual layout for tray workspace
#exec --no-startup-id "i3-msg 'workspace 10:tray; append_layout /home/lanxu/.config/i3/tray.json'"
bindsym XF86AudioStop exec --no-startup-id mpc stop
bindsym XF86AudioPlay exec --no-startup-id mpc play
bindsym XF86AudioPause exec --no-startup-id mpc pause
bindsym XF86AudioNext exec --no-startup-id mpc next
bindsym XF86AudioPrev exec --no-startup-id mpc prev
# Print screen
bindsym Print exec --no-startup-id flameshot gui
bindsym Mod4+l exec --no-startup-id "loginctl lock-session"
# Moving desktops
bindsym Mod4+o move workspace to output left
bindsym Mod4+Ctrl+Right move workspace to output right
bindsym Mod4+Ctrl+Left move workspace to output left

52
config/i3/i3status.conf Normal file
View File

@ -0,0 +1,52 @@
general {
# These will be used if not supplied by a module
# Solarized
#color = '#073642' # base0
color = '#93a1a1' # base1
color_good = '#859900'
color_degraded = '#b58900'
color_bad = '#dc322f'
}
py3status {
align = 'center'
markup = 'pango'
min_width = 50
separator = True
separator_block_width = 20
border = '#4c7899'
#border = '#073642'
border_bottom = 0
border_left = 0
border_right = 0
border_top = 0
}
time {
format = "%Y-%m-%d %H:%M "
}
mpd_status {
format = "[[[{artist} - ]{title}]|[{file}]]"
max_width = 30
}
volume_status {
command = "pactl"
}
weather_owm {
api_key = "4e3b7bbd3da07052c4fed6d342e48707"
city = "Tampere"
unit_temperature = "C"
format_temperature = "[\?color=all {current:.0f}°{unit}]"
format = "{city} {icon} {temperature}"
}
order += "net_status"
order += "dpms"
order += "volume_status"
order += "sysdata"
order += "gpu_temp"
order += "weather_owm"
order += "mpd_status"
order += "time"

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
This module produces GPU temperature
"""
import sys
sys.path.insert(1, '/home/lanxu/Scripts/')
from gputemp import get_temperature
class Py3status:
format = 'GPU: {temp}'
thresholds = [
(0, "good"),
(50, "degraded"),
(70, "bad")
]
def gpu_temp(self):
temp = float(get_temperature())
full_text = self.py3.safe_format(self.format, { 'temp': temp})
color = self.py3.threshold_get_color(temp)
return {
'full_text': full_text,
'color': color,
'cached_until': self.py3.time_in(15)
}

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""
This module produces list of enabled network interfaces
"""
import sys
import subprocess
from subprocess import check_output
class Py3status:
format = 'NET: {status}'
def net_status(self):
# Retrieve active connections, Ignore bridges
command = 'nmcli --mode multiline --colors no con show --active | rg DEVICE | awk -F":" \'{ gsub(/ /, ""); print $2}\' | rg \'^[^br-]\''
return_value = check_output(command, shell=True)
value = return_value.decode("utf-8")
value = value.replace('\n', ', ').strip(', ')
full_text = self.py3.safe_format(self.format, { 'status': value})
return {
'full_text': full_text,
'cached_until': self.py3.time_in(15)
}

104
config/i3/tray.json Normal file
View File

@ -0,0 +1,104 @@
{
// splitv split container with 2 children
"border": "pixel",
"floating": "auto_off",
"layout": "splitv",
"percent": 0.5,
"type": "con",
"nodes": [
{
// splitv split container with 1 children
"border": "pixel",
"floating": "auto_off",
"layout": "splitv",
"percent": 0.5,
"type": "con",
"nodes": [
{
"border": "pixel",
"current_border_width": 0,
"floating": "auto_off",
"geometry": {
"height": 514,
"width": 945,
"x": 0,
"y": 0
},
"name": "Äänenvoimakkuus",
"percent": 1,
"swallows": [
{
"class": "^Pavucontrol$"
// "instance": "^pavucontrol$",
// "title": "^Äänenvoimakkuus$"
}
],
"type": "con"
}
]
},
{
// splith split container with 1 children
"border": "pixel",
"floating": "auto_off",
"layout": "splith",
"percent": 0.5,
"type": "con",
"nodes": [
{
"border": "pixel",
"current_border_width": 0,
"floating": "auto_off",
"geometry": {
"height": 950,
"width": 1223,
"x": 0,
"y": 0
},
"name": "Cantata",
"percent": 1,
"swallows": [
{
"class": "^cantata$"
// "instance": "^cantata$",
// "title": "^Cantata$"
}
],
"type": "con"
}
]
}
]
}
{
// splitv split container with 2 children
"border": "pixel",
"floating": "auto_off",
"layout": "splitv",
"percent": 0.5,
"type": "con",
"nodes": [
{
"border": "pixel",
"current_border_width": 0,
"floating": "user_off",
"geometry": {
"height": 1037,
"width": 617,
"x": 1455,
"y": 33
},
"name": "Nextcloud",
"percent": 0.5,
"swallows": [
{
"class": "^Nextcloud$"
// "instance": "^nextcloud$",
// "title": "^Nextcloud$"
}
],
"type": "con"
}
]
}

4
config/imv/config Normal file
View File

@ -0,0 +1,4 @@
[binds]
y = exec wl-copy < "$imv_current_file"
d = exec dragon -a -x "$imv_current_file"
f = fullscreen; reset

139
config/kitty/kitty.conf Normal file
View File

@ -0,0 +1,139 @@
font_family Fira Code Medium
bold_font Fira Code Bold
italic_font Fira Code Italic
bold_italic_font auto
font_size 11.0
window_padding_width 2.0
window_padding_height 2.0
# Base16 Gruvbox dark, hard - kitty color config
# Scheme by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
background #1d2021
foreground #d5c4a1
selection_background #d5c4a1
selection_foreground #1d2021
url_color #bdae93
cursor #d5c4a1
active_border_color #665c54
inactive_border_color #3c3836
active_tab_background #1d2021
active_tab_foreground #d5c4a1
inactive_tab_background #3c3836
inactive_tab_foreground #bdae93
tab_bar_background #3c3836
# normal
color0 #1d2021
color1 #fb4934
color2 #b8bb26
color3 #fabd2f
color4 #83a598
color5 #d3869b
color6 #8ec07c
color7 #d5c4a1
# bright
color8 #665c54
color9 #fb4934
color10 #b8bb26
color11 #fabd2f
color12 #83a598
color13 #d3869b
color14 #8ec07c
color15 #fbf1c7
# extended base16 colors
color16 #fe8019
color17 #d65d0e
color18 #3c3836
color19 #504945
color20 #bdae93
color21 #ebdbb2
## Base16 Solarized Dark - kitty color config
## Scheme by Ethan Schoonover (modified by aramisgithub)
#background #002b36
#foreground #93a1a1
#selection_background #93a1a1
#selection_foreground #002b36
#url_color #839496
#cursor #93a1a1
#active_border_color #657b83
#inactive_border_color #073642
#active_tab_background #002b36
#active_tab_foreground #93a1a1
#inactive_tab_background #073642
#inactive_tab_foreground #839496
#tab_bar_background #073642
#
## normal
#color0 #002b36
#color1 #dc322f
#color2 #859900
#color3 #b58900
#color4 #268bd2
#color5 #6c71c4
#color6 #2aa198
#color7 #93a1a1
#
## bright
#color8 #657b83
#color9 #dc322f
#color10 #859900
#color11 #b58900
#color12 #268bd2
#color13 #6c71c4
#color14 #2aa198
#color15 #fdf6e3
#
## extended base16 colors
#color16 #cb4b16
#color17 #d33682
#color18 #073642
#color19 #586e75
#color20 #839496
#color21 #eee8d5
# Base16 Default Dark - kitty color config
## Scheme by Chris Kempson (http://chriskempson.com)
#background #181818
#foreground #d8d8d8
#selection_background #d8d8d8
#selection_foreground #181818
#url_color #b8b8b8
#cursor #d8d8d8
#active_border_color #585858
#inactive_border_color #282828
#active_tab_background #181818
#active_tab_foreground #d8d8d8
#inactive_tab_background #282828
#inactive_tab_foreground #b8b8b8
#tab_bar_background #282828
#
## normal
#color0 #181818
#color1 #ab4642
#color2 #a1b56c
#color3 #f7ca88
#color4 #7cafc2
#color5 #ba8baf
#color6 #86c1b9
#color7 #d8d8d8
#
## bright
#color8 #585858
#color9 #ab4642
#color10 #a1b56c
#color11 #f7ca88
#color12 #7cafc2
#color13 #ba8baf
#color14 #86c1b9
#color15 #f8f8f8
#
## extended base16 colors
#color16 #dc9656
#color17 #a16946
#color18 #282828
#color19 #383838
#color20 #b8b8b8
#color21 #e8e8e8

View File

@ -0,0 +1,43 @@
# Base16 Gruvbox dark, hard - kitty color config
# Scheme by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
background #1d2021
foreground #d5c4a1
selection_background #d5c4a1
selection_foreground #1d2021
url_color #bdae93
cursor #d5c4a1
active_border_color #665c54
inactive_border_color #3c3836
active_tab_background #1d2021
active_tab_foreground #d5c4a1
inactive_tab_background #3c3836
inactive_tab_foreground #bdae93
tab_bar_background #3c3836
# normal
color0 #1d2021
color1 #fb4934
color2 #b8bb26
color3 #fabd2f
color4 #83a598
color5 #d3869b
color6 #8ec07c
color7 #d5c4a1
# bright
color8 #665c54
color9 #fb4934
color10 #b8bb26
color11 #fabd2f
color12 #83a598
color13 #d3869b
color14 #8ec07c
color15 #fbf1c7
# extended base16 colors
color16 #fe8019
color17 #d65d0e
color18 #3c3836
color19 #504945
color20 #bdae93
color21 #ebdbb2

View File

@ -0,0 +1,43 @@
# Base16 Solarized Dark - kitty color config
# Scheme by Ethan Schoonover (modified by aramisgithub)
background #002b36
foreground #93a1a1
selection_background #93a1a1
selection_foreground #002b36
url_color #839496
cursor #93a1a1
active_border_color #657b83
inactive_border_color #073642
active_tab_background #002b36
active_tab_foreground #93a1a1
inactive_tab_background #073642
inactive_tab_foreground #839496
tab_bar_background #073642
# normal
color0 #002b36
color1 #dc322f
color2 #859900
color3 #b58900
color4 #268bd2
color5 #6c71c4
color6 #2aa198
color7 #93a1a1
# bright
color8 #657b83
color9 #dc322f
color10 #859900
color11 #b58900
color12 #268bd2
color13 #6c71c4
color14 #2aa198
color15 #fdf6e3
# extended base16 colors
color16 #cb4b16
color17 #d33682
color18 #073642
color19 #586e75
color20 #839496
color21 #eee8d5

26
config/lf/lfrc Normal file
View File

@ -0,0 +1,26 @@
set previewer ~/.config/lf/pv.sh
map i $~/.config/lf/pv.sh $f | less -R
# Trash
cmd trash %trash-put "$fx"
# Search with fzf
map f $vi $(fzf)
# Recreate open-with with lf
cmd open-with %"$@" "$fx"
map ` push :open-with<space>
# Show current directory in window title
cmd on-cd &{{
# '&' commands run silently in background (which is what we want here),
# but are not connected to stdout.
# To make sure our escape sequence still reaches stdout we pipe it to /dev/tty
printf "\033]0; $PWD\007" > /dev/tty
}}
map r reload
# Drag and drop
map <c-d> %dragon --all --and-exit "$fx"
map <c-c> &wl-copy < "$fx"

37
config/lf/pv.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
FILE="${1}"
HEIGHT="${2}"
case "$1" in
#*.png|*.jpg|*.jpeg|*.gif|*.webp)viu -w 100 -s "$1";;
*.png|*.jpg|*.jpeg|*.gif|*.webp)
catimg -w 100 "${FILE}";;
*.tar*)
tar tf "$1";;
*.zip)
unzip -l "$1";;
*.rar)
unrar l "$1";;
*.7z)
7z l "$1";;
*.pdf)
pdftotext "$1" -;;
*.mp4|*.avi|*.mkv|*.webm|*.mpg)
TMPFILE=$(mktemp)
ffmpegthumbnailer -i "${FILE}" -o "${TMPFILE}" -s 0
catimg -w 100 "${TMPFILE}";;
#mediainfo ${FILE};;
*.cbz|*.cbr|*.epub)
TMPFILE=$(mktemp)
comicthumb.py "${FILE}" "${TMPFILE}" 512 > /dev/null 2>&1
echo $TMPFILE
catimg -w 100 "${TMPFILE}";;
*)
bat --color=always --theme=base16 "$1";;
esac
IFS=$SAVEIFS

32
config/mimeapps.list Normal file
View File

@ -0,0 +1,32 @@
[Default Applications]
application/vnd.comicbook+rar=mcomix.desktop
application/vnd.comicbook+zip=mcomix.desktop
application/vnd.rar=xarchiver.desktop
application/x-cbr=mcomix.desktop
application/x-cbz=mcomix.desktop
application/zip=xarchiver.desktop
application/epub+zip=mcomix.desktop;
application/octet-stream=gvim.desktop;
application/pdf=org.pwmt.zathura-pdf-mupdf.desktop;
application/pgp-signature=gvim.desktop;
application/vnd.ms-publisher=gvim.desktop;
application/vnd.rar=mcomix.desktop;xarchiver.desktop;
application/x-alz=xarchiver.desktop;
image/gif=sxiv_browser.desktop
image/jpeg=sxiv_browser.desktop
image/png=sxiv_browser.desktop
image/svg+xml=inkscape.desktop
inode/directory=pcmanfm.desktop
video/mp4=mpv.desktop
video/quicktime=mpv.desktop
video/x-msvideo=mpv.desktop
video/x-flv=mpv.desktop
video/x-matroska=mpv.desktop
text/plain=gvim.desktop
x-scheme-handler/itchio=io.itch.itch.desktop
x-terminal-emulator=urxvt.desktop
x-scheme-handler/discord-378483863044882443=discord-378483863044882443.desktop
x-scheme-handler/http=firefox.desktop
[Added Associations]
application/x-blender=blender.desktop;

424
config/mpd/mpd.conf Normal file
View File

@ -0,0 +1,424 @@
# An example configuration file for MPD.
# Read the user manual for documentation: http://www.musicpd.org/doc/user/
# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
#music_directory "~/music"
#
# This setting sets the MPD internal playlist directory. The purpose of this
# directory is storage for playlists created by MPD. The server will use
# playlist files not created by the server but only if they are in the MPD
# format. This setting defaults to playlist saving being disabled.
#
#playlist_directory "~/.mpd/playlists"
#
# This setting sets the location of the MPD database. This file is used to
# load the database at server start up and store the database while the
# server is not up. This setting defaults to disabled which will allow
# MPD to accept files over ipc socket (using file:// protocol) or streaming
# files over an accepted protocol.
#
#db_file "~/.mpd/database"
#
# These settings are the locations for the daemon log files for the daemon.
# These logs are great for troubleshooting, depending on your log_level
# settings.
#
# The special value "syslog" makes MPD use the local syslog daemon. This
# setting defaults to logging to syslog, otherwise logging is disabled.
#
#log_file "~/.mpd/log"
#
# This setting sets the location of the file which stores the process ID
# for use of mpd --kill and some init scripts. This setting is disabled by
# default and the pid file will not be stored.
#
#pid_file "~/.mpd/pid"
#
# This setting sets the location of the file which contains information about
# most variables to get MPD back into the same general shape it was in before
# it was brought down. This setting is disabled by default and the server
# state will be reset on server start up.
#
#state_file "~/.mpd/state"
#
# The location of the sticker database. This is a database which
# manages dynamic information attached to songs.
#
#sticker_file "~/.mpd/sticker.sql"
#
###############################################################################
# General music daemon options ################################################
#
# This setting specifies the user that MPD will run as. MPD should never run as
# root and you may use this setting to make MPD change its user ID after
# initialization. This setting is disabled by default and MPD is run as the
# current user.
#
#user "nobody"
#
# This setting specifies the group that MPD will run as. If not specified
# primary group of user specified with "user" setting will be used (if set).
# This is useful if MPD needs to be a member of group such as "audio" to
# have permission to use sound card.
#
#group "nogroup"
#
# This setting sets the address for the daemon to listen on. Careful attention
# should be paid if this is assigned to anything other then the default, any.
# This setting can deny access to control of the daemon.
#
# For network
bind_to_address "127.0.0.1"
#
# And for Unix Socket
#bind_to_address "~/.config/mpd/socket"
#
# This setting is the TCP port that is desired for the daemon to get assigned
# to.
#
#port "6600"
#
# This setting controls the type of information which is logged. Available
# setting arguments are "default", "secure" or "verbose". The "verbose" setting
# argument is recommended for troubleshooting, though can quickly stretch
# available resources on limited hardware storage.
#
#log_level "default"
#
# If you have a problem with your MP3s ending abruptly it is recommended that
# you set this argument to "no" to attempt to fix the problem. If this solves
# the problem, it is highly recommended to fix the MP3 files with vbrfix
# (available from <http://www.willwap.co.uk/Programs/vbrfix.php>), at which
# point gapless MP3 playback can be enabled.
#
#gapless_mp3_playback "yes"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
#
#restore_paused "no"
#
# This setting enables MPD to create playlists in a format usable by other
# music players.
#
#save_absolute_paths_in_playlists "no"
#
# This setting defines a list of tag types that will be extracted during the
# audio file discovery process. The complete list of possible values can be
# found in the mpd.conf man page.
#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
#
# This setting enables automatic update of MPD's database when files in
# music_directory are changed.
#
#auto_update "yes"
#
# Limit the depth of the directories being watched, 0 means only watch
# the music directory itself. There is no limit by default.
#
#auto_update_depth "3"
#
###############################################################################
# Symbolic link behavior ######################################################
#
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links outside of the configured music_directory.
#
#follow_outside_symlinks "yes"
#
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links inside of the configured music_directory.
#
#follow_inside_symlinks "yes"
#
###############################################################################
# Zeroconf / Avahi Service Discovery ##########################################
#
# If this setting is set to "yes", service information will be published with
# Zeroconf / Avahi.
#
#zeroconf_enabled "yes"
#
# The argument to this setting will be the Zeroconf / Avahi unique name for
# this MPD server on the network.
#
#zeroconf_name "Music Player"
#
###############################################################################
# Permissions #################################################################
#
# If this setting is set, MPD will require password authorization. The password
# can setting can be specified multiple times for different password profiles.
#
#password "password@read,add,control,admin"
#
# This setting specifies the permissions a user has who has not yet logged in.
#
#default_permissions "read,add,control,admin"
#
###############################################################################
# Database #######################################################################
#
#database {
# plugin "proxy"
# host "other.mpd.host"
# port "6600"
#}
# Input #######################################################################
#
input {
plugin "curl"
# proxy "proxy.isp.com:8080"
# proxy_user "user"
# proxy_password "password"
}
#
###############################################################################
# Audio Output ################################################################
#
# MPD supports various audio output types, as well as playing through multiple
# audio outputs at the same time, through multiple audio_output settings
# blocks. Setting this block is optional, though the server will only attempt
# autodetection for one sound card.
#
# An example of an ALSA output:
#
#audio_output {
# type "alsa"
# name "My ALSA Device"
## device "hw:0,0" # optional
## mixer_type "hardware" # optional
## mixer_device "default" # optional
## mixer_control "PCM" # optional
## mixer_index "0" # optional
#}
#
# An example of an OSS output:
#
#audio_output {
# type "oss"
# name "My OSS Device"
## device "/dev/dsp" # optional
## mixer_type "hardware" # optional
## mixer_device "/dev/mixer" # optional
## mixer_control "PCM" # optional
#}
#
# An example of a shout output (for streaming to Icecast):
#
#audio_output {
# type "shout"
# encoding "ogg" # optional
# name "My Shout Stream"
# host "localhost"
# port "8000"
# mount "/mpd.ogg"
# password "hackme"
# quality "5.0"
# bitrate "128"
# format "44100:16:1"
## protocol "icecast2" # optional
## user "source" # optional
## description "My Stream Description" # optional
## url "http://example.com" # optional
## genre "jazz" # optional
## public "no" # optional
## timeout "2" # optional
## mixer_type "software" # optional
#}
#
# An example of a recorder output:
#
#audio_output {
# type "recorder"
# name "My recorder"
# encoder "vorbis" # optional, vorbis or lame
# path "/var/lib/mpd/recorder/mpd.ogg"
## quality "5.0" # do not define if bitrate is defined
# bitrate "128" # do not define if quality is defined
# format "44100:16:1"
#}
#
# An example of a httpd output (built-in HTTP streaming server):
#
#audio_output {
# type "httpd"
# name "My HTTP Stream"
# encoder "vorbis" # optional, vorbis or lame
# port "8000"
# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6
## quality "5.0" # do not define if bitrate is defined
# bitrate "128" # do not define if quality is defined
# format "44100:16:1"
# max_clients "0" # optional 0=no limit
#}
#
# An example of a pulseaudio output (streaming to a remote pulseaudio server)
#
audio_output {
type "pulse"
name "My Pulse Output"
# server "remote_server" # optional
# sink "remote_server_sink" # optional
}
#
# An example of a winmm output (Windows multimedia API).
#
#audio_output {
# type "winmm"
# name "My WinMM output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
# or
## device "0" # optional
## mixer_type "hardware" # optional
#}
#
# An example of an openal output.
#
#audio_output {
# type "openal"
# name "My OpenAL output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
#}
#
## Example "pipe" output:
#
#audio_output {
# type "pipe"
# name "my pipe"
# command "aplay -f cd 2>/dev/null"
## Or if you're want to use AudioCompress
# command "AudioCompress -m | aplay -f cd 2>/dev/null"
## Or to send raw PCM stream through PCM:
# command "nc example.org 8765"
# format "44100:16:2"
#}
#
## An example of a null output (for no audio output):
#
#audio_output {
# type "null"
# name "My Null Output"
# mixer_type "none" # optional
#}
#
# If MPD has been compiled with libsamplerate support, this setting specifies
# the sample rate converter to use. Possible values can be found in the
# mpd.conf man page or the libsamplerate documentation. By default, this is
# setting is disabled.
#
#samplerate_converter "Fastest Sinc Interpolator"
#
###############################################################################
# Normalization automatic volume adjustments ##################################
#
# This setting specifies the type of ReplayGain to use. This setting can have
# the argument "off", "album", "track" or "auto". "auto" is a special mode that
# chooses between "track" and "album" depending on the current state of
# random playback. If random playback is enabled then "track" mode is used.
# See <http://www.replaygain.org> for more details about ReplayGain.
# This setting is off by default.
#
#replaygain "album"
#
# This setting sets the pre-amp used for files that have ReplayGain tags. By
# default this setting is disabled.
#
#replaygain_preamp "0"
#
# This setting sets the pre-amp used for files that do NOT have ReplayGain tags.
# By default this setting is disabled.
#
#replaygain_missing_preamp "0"
#
# This setting enables or disables ReplayGain limiting.
# MPD calculates actual amplification based on the ReplayGain tags
# and replaygain_preamp / replaygain_missing_preamp setting.
# If replaygain_limit is enabled MPD will never amplify audio signal
# above its original level. If replaygain_limit is disabled such amplification
# might occur. By default this setting is enabled.
#
#replaygain_limit "yes"
#
# This setting enables on-the-fly normalization volume adjustment. This will
# result in the volume of all playing audio to be adjusted so the output has
# equal "loudness". This setting is disabled by default.
#
#volume_normalization "no"
#
###############################################################################
# Character Encoding ##########################################################
#
# If file or directory names do not display correctly for your locale then you
# may need to modify this setting.
#
#filesystem_charset "UTF-8"
#
# This setting controls the encoding that ID3v1 tags should be converted from.
#
#id3v1_encoding "ISO-8859-1"
#
###############################################################################
# SIDPlay decoder #############################################################
#
# songlength_database:
# Location of your songlengths file, as distributed with the HVSC.
# The sidplay plugin checks this for matching MD5 fingerprints.
# See http://www.c64.org/HVSC/DOCUMENTS/Songlengths.faq
#
# default_songlength:
# This is the default playing time in seconds for songs not in the
# songlength database, or in case you're not using a database.
# A value of 0 means play indefinitely.
#
# filter:
# Turns the SID filter emulation on or off.
#
#decoder {
# plugin "sidplay"
# songlength_database "/media/C64Music/DOCUMENTS/Songlengths.txt"
# default_songlength "120"
# filter "true"
#}
#
###############################################################################
# Required files
db_file "~/.config/mpd/database"
log_file "~/.config/mpd/log"
# # Optional
music_directory "~/Musiikki"
playlist_directory "~/.config/mpd/playlists"
pid_file "~/.config/mpd/pid"
state_file "~/.config/mpd/state"
sticker_file "~/.config/mpd/sticker.sql"

304
config/mpv/lua/notify.lua Normal file
View File

@ -0,0 +1,304 @@
-- notify.lua -- Desktop notifications for mpv.
-- Just put this file into your ~/.mpv/lua folder and mpv will find it.
--
-- Copyright (c) 2014 Roland Hieber
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
-------------------------------------------------------------------------------
-- helper functions
-------------------------------------------------------------------------------
function print_debug(s)
-- print("DEBUG: " .. s) -- comment out for no debug info
return true
end
-- url-escape a string, per RFC 2396, Section 2
function string.urlescape(str)
local s, c = string.gsub(str, "([^A-Za-z0-9_.!~*'()/-])",
function(c)
return ("%%%02x"):format(c:byte())
end)
return s;
end
-- escape string for html
function string.htmlescape(str)
local str = string.gsub(str, "<", "&lt;")
str = string.gsub(str, ">", "&gt;")
str = string.gsub(str, "&", "&amp;")
str = string.gsub(str, "\"", "&quot;")
str = string.gsub(str, "'", "&apos;")
return str
end
-- escape string for shell inclusion
function string.shellescape(str)
return "'"..string.gsub(str, "'", "'\"'\"'").."'"
end
-- converts string to a valid filename on most (modern) filesystems
function string.safe_filename(str)
local s, _ = string.gsub(str, "([^A-Za-z0-9_.-])",
function(c)
return ("%02x"):format(c:byte())
end)
return s;
end
-------------------------------------------------------------------------------
-- here we go.
-------------------------------------------------------------------------------
local http = require("socket.http")
http.TIMEOUT = 3
http.USERAGENT = "mpv-notify/0.1"
local posix = require("posix")
local CACHE_DIR = os.getenv("XDG_CACHE_HOME")
CACHE_DIR = CACHE_DIR or os.getenv("HOME").."/.cache"
CACHE_DIR = CACHE_DIR.."/mpv/coverart"
print_debug("making " .. CACHE_DIR)
os.execute("mkdir -p -- " .. string.shellescape(CACHE_DIR))
function tmpname()
local _, fname = posix.mkstemp(CACHE_DIR .. "/rescale.XXXXXX")
return fname
end
-- scale an image file
-- @return boolean of success
function scale_image(src, dst)
local convert_cmd = ("convert -scale x64 -- %s %s"):format(
string.shellescape(src), string.shellescape(dst))
print_debug("executing " .. convert_cmd)
if os.execute(convert_cmd) then
return true
end
return false
end
-- look for a list of possible cover art images in the same folder as the file
-- @param absolute filename name of currently played file, or nil if no match
function get_folder_cover_art(filename)
if not filename or string.len(filename) < 1 then
return nil
end
print_debug("get_folder_cover_art: filename is " .. filename)
local cover_extensions = { "png", "jpg", "jpeg", "gif" }
local cover_names = { "cover", "folder", "front", "back", "insert" }
local path = string.match(filename, "^(.*/)[^/]+$")
for _,name in pairs(cover_names) do
for _,ext in pairs(cover_extensions) do
morenames = { name, string.upper(name),
string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2, -1) }
moreexts = { ext, string.upper(ext) }
for _,name in pairs(morenames) do
for _,ext in pairs(moreexts) do
local fn = path .. name .. "." .. ext
--print_debug("get_folder_cover_art: trying " .. fn)
local f = io.open(fn, "r")
if f then
f:close()
print_debug("get_folder_cover_art: match at " .. fn)
return fn
end
end
end
end
end
return nil
end
-- fetch cover art from MusicBrainz/Cover Art Archive
-- @return file name of downloaded cover art, or nil in case of error
-- @param mbid optional MusicBrainz release ID
function fetch_musicbrainz_cover_art(artist, album, mbid)
print_debug("fetch_musicbrainz_cover_art parameters:")
print_debug("artist: " .. artist)
print_debug("album: " .. album)
print_debug("mbid: " .. mbid)
if not artist or artist == "" or not album or album == "" then
print("not enough metadata, not fetching cover art.")
return nil
end
local output_filename = string.safe_filename(artist .. "_" .. album)
output_filename = (CACHE_DIR .. "/%s.png"):format(output_filename)
-- TODO: dirty hack, may only work on Linux.
f, err = io.open(output_filename, "r")
if f then
print_debug("file is already in cache: " .. output_filename)
return output_filename -- exists and is readable
elseif string.find(err, "[Pp]ermission denied") then
print(("cannot read from cached file %s: %s"):format(output_filename, err))
return nil
end
print_debug("fetching album art to " .. output_filename)
local valid_mbid = function(s)
return s and string.len(s) > 0 and not string.find(s, "[^0-9a-fA-F-]")
end
-- fetch release MBID from MusicBrainz, needed for Cover Art Archive
if not valid_mbid(mbid) then
string.gsub(artist, '"', "")
local query = ("%s AND artist:%s"):format(album, artist)
local url = "http://musicbrainz.org/ws/2/release?limit=1&query="
.. string.urlescape(query)
print_debug("fetching " .. url)
local d, c, h = http.request(url)
-- poor man's XML parsing:
local mbid = string.match(d or "",
"<%s*release%s+[^>]*id%s*=%s*['\"]%s*([0-9a-fA-F-]+)%s*['\"]")
if not mbid or not valid_mbid(mbid) then
print("MusicBrainz returned no match.")
print_debug("content: " .. d)
return nil
end
end
print_debug("got MusicBrainz ID " .. mbid)
-- fetch image from Cover Art Archive
local url = ("http://coverartarchive.org/release/%s/front-250"):format(mbid)
print("fetching album cover from " .. url)
local d, c, h = http.request(url)
if c ~= 200 then
print(("Cover Art Archive returned HTTP %s for MBID %s"):format(c, mbid))
return nil
end
if not d or string.len(d) < 1 then
print(("Cover Art Archive returned no content for MBID %s"):format(mbid))
print_debug("HTTP response: " .. d)
return nil
end
local tmp_filename = tmpname()
local f = io.open(tmp_filename, "w+")
f:write(d)
f:flush()
f:close()
-- make it a nice size
if scale_image(tmp_filename, output_filename) then
if not os.remove(tmp_filename) then
print("could not remove" .. tmp_filename .. ", please remove it manually")
end
return output_filename
end
print(("could not scale %s to %s"):format(tmp_filename, output_filename))
return nil
end
function notify_current_track()
local data = mp.get_property_native("metadata")
if not data then
return
end
function get_metadata(data, keys)
for _,v in pairs(keys) do
if data[v] and string.len(data[v]) > 0 then
return data[v]
end
end
return ""
end
-- srsly MPV, why do we have to do this? :-(
local artist = get_metadata(data, {"artist", "ARTIST"})
local album = get_metadata(data, {"album", "ALBUM"})
local album_mbid = get_metadata(data, {"MusicBrainz Album Id",
"MUSICBRAINZ_ALBUMID"})
local title = get_metadata(data, {"title", "TITLE", "icy-title"})
print_debug("notify_current_track: relevant metadata:")
print_debug("artist: " .. artist)
print_debug("album: " .. album)
print_debug("album_mbid: " .. album_mbid)
local summary = ""
local body = ""
local params = ""
local scaled_image = ""
local delete_scaled_image = false
-- first try finding local cover art
local abs_filename = os.getenv("PWD") .. "/" .. mp.get_property_native("path")
local cover_image = get_folder_cover_art(abs_filename)
if cover_image and cover_image ~= "" then
scaled_image = tmpname()
scale_image(cover_image, scaled_image)
delete_scaled_image = true
end
-- then load cover art from the internet
if (not scaled_image or scaled_image == "")
and ((artist ~= "" and album ~= "") or album_mbid ~= "") then
scaled_image = fetch_musicbrainz_cover_art(artist, album, album_mbid)
cover_image = scaled_image
end
if scaled_image and string.len(scaled_image) > 1 then
print("found cover art in " .. cover_image)
params = " -i " .. string.shellescape(scaled_image)
end
if(artist == "") then
summary = string.shellescape("Now playing:")
else
summary = string.shellescape(string.htmlescape(artist))
end
if title == "" then
body = string.shellescape(mp.get_property_native("filename"))
else
if album == "" then
body = string.shellescape(string.htmlescape(title))
else
body = string.shellescape(("%s<br /><i>%s</i>"):format(
string.htmlescape(title), string.htmlescape(album)))
end
end
local command = ("notify-send -a mpv %s -- %s %s"):format(params, summary, body)
print_debug("command: " .. command)
os.execute(command)
if delete_scaled_image and not os.remove(scaled_image) then
print("could not remove" .. scaled_image .. ", please remove it manually")
end
end
function notify_metadata_updated(name, data)
notify_current_track()
end
-- insert main() here
mp.register_event("file-loaded", notify_current_track)
mp.observe_property("metadata", nil, notify_metadata_updated)

7
config/mpv/mpv.conf Normal file
View File

@ -0,0 +1,7 @@
hwdec=vaapi
vo=gpu
osd-font-size=14
ao=pulse
[extension.webm]
loop-file=inf

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