NixOS config
24
config/awesome/dpmsstatus.lua
Normal 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 })
|
23
config/awesome/gputemp.lua
Normal 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
|
@ -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 })
|
35
config/awesome/lanxu/README.md
Normal 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
|
||||
})
|
||||
~~~
|
80
config/awesome/lanxu/cloudstatus.lua
Normal 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
|
714
config/awesome/lanxu/dkjson.lua
Normal 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
|
||||
|
53
config/awesome/lanxu/ip.lua
Normal 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
|
116
config/awesome/lanxu/mcstatus.lua
Normal 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
|
23
config/awesome/lanxu/mcstatustest.lua
Normal 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
|
@ -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")
|
BIN
config/awesome/themes/lanxu/background.png
Normal file
After Width: | Height: | Size: 6.1 MiB |
BIN
config/awesome/themes/lanxu/icons/cpu.png
Normal file
After Width: | Height: | Size: 478 B |
BIN
config/awesome/themes/lanxu/icons/gpu.png
Normal file
After Width: | Height: | Size: 475 B |
BIN
config/awesome/themes/lanxu/icons/ram.png
Normal file
After Width: | Height: | Size: 464 B |
BIN
config/awesome/themes/lanxu/icons/wall-clock.png
Normal file
After Width: | Height: | Size: 587 B |
BIN
config/awesome/themes/lanxu/layouts/cornerne.png
Normal file
After Width: | Height: | Size: 451 B |
BIN
config/awesome/themes/lanxu/layouts/cornernew.png
Normal file
After Width: | Height: | Size: 409 B |
BIN
config/awesome/themes/lanxu/layouts/cornernw.png
Normal file
After Width: | Height: | Size: 439 B |
BIN
config/awesome/themes/lanxu/layouts/cornernww.png
Normal file
After Width: | Height: | Size: 381 B |
BIN
config/awesome/themes/lanxu/layouts/cornerse.png
Normal file
After Width: | Height: | Size: 424 B |
BIN
config/awesome/themes/lanxu/layouts/cornersew.png
Normal file
After Width: | Height: | Size: 411 B |
BIN
config/awesome/themes/lanxu/layouts/cornersw.png
Normal file
After Width: | Height: | Size: 424 B |
BIN
config/awesome/themes/lanxu/layouts/cornersww.png
Normal file
After Width: | Height: | Size: 423 B |
BIN
config/awesome/themes/lanxu/layouts/dwindle.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
config/awesome/themes/lanxu/layouts/dwindlew.png
Normal file
After Width: | Height: | Size: 444 B |
BIN
config/awesome/themes/lanxu/layouts/fairh.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
config/awesome/themes/lanxu/layouts/fairhw.png
Normal file
After Width: | Height: | Size: 314 B |
BIN
config/awesome/themes/lanxu/layouts/fairv.png
Normal file
After Width: | Height: | Size: 323 B |
BIN
config/awesome/themes/lanxu/layouts/fairvw.png
Normal file
After Width: | Height: | Size: 323 B |
BIN
config/awesome/themes/lanxu/layouts/floating.png
Normal file
After Width: | Height: | Size: 361 B |
BIN
config/awesome/themes/lanxu/layouts/floatingw.png
Normal file
After Width: | Height: | Size: 365 B |
BIN
config/awesome/themes/lanxu/layouts/fullscreen.png
Normal file
After Width: | Height: | Size: 866 B |
BIN
config/awesome/themes/lanxu/layouts/fullscreenw.png
Normal file
After Width: | Height: | Size: 865 B |
BIN
config/awesome/themes/lanxu/layouts/magnifier.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
config/awesome/themes/lanxu/layouts/magnifierw.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
config/awesome/themes/lanxu/layouts/max.png
Normal file
After Width: | Height: | Size: 574 B |
BIN
config/awesome/themes/lanxu/layouts/maxw.png
Normal file
After Width: | Height: | Size: 581 B |
BIN
config/awesome/themes/lanxu/layouts/spiral.png
Normal file
After Width: | Height: | Size: 427 B |
BIN
config/awesome/themes/lanxu/layouts/spiralw.png
Normal file
After Width: | Height: | Size: 442 B |
BIN
config/awesome/themes/lanxu/layouts/tile.png
Normal file
After Width: | Height: | Size: 353 B |
BIN
config/awesome/themes/lanxu/layouts/tilebottom.png
Normal file
After Width: | Height: | Size: 340 B |
BIN
config/awesome/themes/lanxu/layouts/tilebottomw.png
Normal file
After Width: | Height: | Size: 350 B |
BIN
config/awesome/themes/lanxu/layouts/tileleft.png
Normal file
After Width: | Height: | Size: 363 B |
BIN
config/awesome/themes/lanxu/layouts/tileleftw.png
Normal file
After Width: | Height: | Size: 367 B |
BIN
config/awesome/themes/lanxu/layouts/tiletop.png
Normal file
After Width: | Height: | Size: 326 B |
BIN
config/awesome/themes/lanxu/layouts/tiletopw.png
Normal file
After Width: | Height: | Size: 342 B |
BIN
config/awesome/themes/lanxu/layouts/tilew.png
Normal file
After Width: | Height: | Size: 357 B |
BIN
config/awesome/themes/lanxu/logo.png
Normal file
After Width: | Height: | Size: 245 B |
BIN
config/awesome/themes/lanxu/logo16.png
Normal file
After Width: | Height: | Size: 226 B |
BIN
config/awesome/themes/lanxu/submenu.png
Normal file
After Width: | Height: | Size: 440 B |
BIN
config/awesome/themes/lanxu/taglist/squarefw.png
Normal file
After Width: | Height: | Size: 187 B |
BIN
config/awesome/themes/lanxu/taglist/squarew.png
Normal file
After Width: | Height: | Size: 193 B |
127
config/awesome/themes/lanxu/theme.lua
Normal 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
|
BIN
config/awesome/themes/lanxu/titlebar/close_focus.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
config/awesome/themes/lanxu/titlebar/close_normal.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
config/awesome/themes/lanxu/titlebar/floating_focus_active.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
config/awesome/themes/lanxu/titlebar/floating_focus_inactive.png
Normal file
After Width: | Height: | Size: 350 B |
BIN
config/awesome/themes/lanxu/titlebar/floating_normal_active.png
Normal file
After Width: | Height: | Size: 492 B |
After Width: | Height: | Size: 350 B |
BIN
config/awesome/themes/lanxu/titlebar/maximized_focus_active.png
Normal file
After Width: | Height: | Size: 696 B |
After Width: | Height: | Size: 719 B |
BIN
config/awesome/themes/lanxu/titlebar/maximized_normal_active.png
Normal file
After Width: | Height: | Size: 693 B |
After Width: | Height: | Size: 695 B |
BIN
config/awesome/themes/lanxu/titlebar/minimize_focus.png
Normal file
After Width: | Height: | Size: 277 B |
BIN
config/awesome/themes/lanxu/titlebar/minimize_normal.png
Normal file
After Width: | Height: | Size: 272 B |
BIN
config/awesome/themes/lanxu/titlebar/ontop_focus_active.png
Normal file
After Width: | Height: | Size: 609 B |
BIN
config/awesome/themes/lanxu/titlebar/ontop_focus_inactive.png
Normal file
After Width: | Height: | Size: 756 B |
BIN
config/awesome/themes/lanxu/titlebar/ontop_normal_active.png
Normal file
After Width: | Height: | Size: 619 B |
BIN
config/awesome/themes/lanxu/titlebar/ontop_normal_inactive.png
Normal file
After Width: | Height: | Size: 769 B |
BIN
config/awesome/themes/lanxu/titlebar/sticky_focus_active.png
Normal file
After Width: | Height: | Size: 717 B |
BIN
config/awesome/themes/lanxu/titlebar/sticky_focus_inactive.png
Normal file
After Width: | Height: | Size: 937 B |
BIN
config/awesome/themes/lanxu/titlebar/sticky_normal_active.png
Normal file
After Width: | Height: | Size: 726 B |
BIN
config/awesome/themes/lanxu/titlebar/sticky_normal_inactive.png
Normal file
After Width: | Height: | Size: 981 B |
172
config/awesome/widgets.lua
Normal 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
|
||||
})
|
||||
|
9
config/compton/compton.conf
Normal 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
|
@ -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
|
112
config/fontconfig/avail/01-noto.conf
Normal 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>
|
20
config/fontconfig/avail/69-emoji-monospace.conf
Normal 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>
|
25
config/fontconfig/avail/69-emoji.conf
Normal 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>
|
30
config/fontconfig/avail/70-no-dejavu.conf
Normal 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>
|
25
config/fontconfig/avail/70-no-mozilla-emoji.conf
Normal 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>
|
64
config/fontconfig/fonts.conf
Normal 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>
|
4
config/fontconfig/with-dejavu-emojiless.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
rm ./conf.d/70-no-dejavu.conf
|
||||
|
||||
echo "Removed configuration"
|
51
config/gallery-dl/config.json
Normal 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
After Width: | Height: | Size: 6.1 MiB |
422
config/i3/config
Normal 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 window’s width.
|
||||
# Pressing right will grow the window’s width.
|
||||
# Pressing up will shrink the window’s height.
|
||||
# Pressing down will grow the window’s 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
|
@ -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"
|
28
config/i3/py3status/gpu_temp.py
Normal 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)
|
||||
}
|
24
config/i3/py3status/net_status.py
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
43
config/kitty/theme-base16-gruvbox-dark.conf
Normal 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
|
43
config/kitty/theme-base16-solarized-dark.conf
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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, "<", "<")
|
||||
str = string.gsub(str, ">", ">")
|
||||
str = string.gsub(str, "&", "&")
|
||||
str = string.gsub(str, "\"", """)
|
||||
str = string.gsub(str, "'", "'")
|
||||
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
|
@ -0,0 +1,7 @@
|
|||
hwdec=vaapi
|
||||
vo=gpu
|
||||
osd-font-size=14
|
||||
ao=pulse
|
||||
|
||||
[extension.webm]
|
||||
loop-file=inf
|