big update
This commit is contained in:
parent
736ada7652
commit
7d60e5625f
|
@ -23,6 +23,11 @@ The installation process is not much different from the previous iteration, exce
|
||||||
3. Install AwesomeWM (version 4.3 as of right now)
|
3. Install AwesomeWM (version 4.3 as of right now)
|
||||||
4. (Optional) Read additional installation steps in `extra/README.md`
|
4. (Optional) Read additional installation steps in `extra/README.md`
|
||||||
|
|
||||||
|
## Keybindings and user guide
|
||||||
|
- press win+s
|
||||||
|
- read extra/README.md
|
||||||
|
- enjoy
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- [x] Port widgets from original config to AWMTK2
|
- [x] Port widgets from original config to AWMTK2
|
||||||
|
|
11
desktop.conf
11
desktop.conf
|
@ -26,11 +26,20 @@ modkey+b = ":client.below"
|
||||||
modkey+f = ":client.fullscreen"
|
modkey+f = ":client.fullscreen"
|
||||||
modkey+n = ":client.minimize"
|
modkey+n = ":client.minimize"
|
||||||
modkey+m = ":client.maximize"
|
modkey+m = ":client.maximize"
|
||||||
|
modkey+p = ":client.pin"
|
||||||
|
modkey+y = ":client.toggle_titlebars"
|
||||||
|
|
||||||
# Widget keys
|
# Widget keys
|
||||||
modkey+r = ":dismal.run"
|
modkey+r = ":dismal.run"
|
||||||
modkey+s = ":help.show"
|
modkey+s = ":help.show"
|
||||||
|
Control+XF86AudioRaiseVolume = ":client.volume_up"
|
||||||
|
Control+XF86AudioLowerVolume = ":client.volume_down"
|
||||||
|
Control+XF86AudioMute = ":client.volume_mute"
|
||||||
|
XF86MonBrightnessUp = ":battery.brightness_up"
|
||||||
|
XF86MonBrightnessDown = ":battery.brightness_down"
|
||||||
|
XF86AudioPlay = ":mpc.play"
|
||||||
|
XF86AudioPrev = ":mpc.prev"
|
||||||
|
XF86AudioNext = ":mpc.next"
|
||||||
# Custom keys
|
# Custom keys
|
||||||
Print = "flameshot gui"
|
Print = "flameshot gui"
|
||||||
Shift+Print = "flameshot launcher"
|
Shift+Print = "flameshot launcher"
|
||||||
|
|
|
@ -12,6 +12,12 @@ local asckey = {
|
||||||
}
|
}
|
||||||
local awful = require("awful")
|
local awful = require("awful")
|
||||||
|
|
||||||
|
asckey.set_keymap = function(keymap)
|
||||||
|
for k,v in pairs(keymap) do
|
||||||
|
asckey.keymap[v] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
asckey.get_keycomb = function(name)
|
asckey.get_keycomb = function(name)
|
||||||
local modifiers = {}
|
local modifiers = {}
|
||||||
name = name:gsub("[^%s%+]+%+",function(v)
|
name = name:gsub("[^%s%+]+%+",function(v)
|
||||||
|
|
|
@ -162,6 +162,9 @@ awmtk.proto_style.center = awmtk.create_delta("center", {
|
||||||
awmtk.proto_style.slider = awmtk.create_delta("slider", {
|
awmtk.proto_style.slider = awmtk.create_delta("slider", {
|
||||||
margins = 1
|
margins = 1
|
||||||
}, awmtk.proto_style,awmtk.proto_style.base)
|
}, awmtk.proto_style,awmtk.proto_style.base)
|
||||||
|
|
||||||
|
awmtk.proto_style.checkbox = awmtk.create_delta("checkbox", {
|
||||||
|
}, awmtk.proto_style,awmtk.proto_style.base)
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
-- {{{ Generic templates
|
-- {{{ Generic templates
|
||||||
|
@ -407,6 +410,19 @@ awmtk.proto_templates = {
|
||||||
widget = wibox.widget.slider
|
widget = wibox.widget.slider
|
||||||
},args or {})
|
},args or {})
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
checkbox = function(style)
|
||||||
|
return function(args)
|
||||||
|
return awmtk.merge({
|
||||||
|
color = style.checkbox.bg_focus,
|
||||||
|
padding = 2,
|
||||||
|
shape = style.checkbox.shape,
|
||||||
|
border_width = style.checkbox.shape_border_width,
|
||||||
|
bg = style.checkbox.shape_border_color,
|
||||||
|
widget = wibox.widget.checkbox
|
||||||
|
},args or {})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,15 @@
|
||||||
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
|
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
local parsers = require("parsers")
|
local parsers = require("parsers")
|
||||||
|
function rprint(t,ident)
|
||||||
|
ident = ident or 0
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
print((" "):rep(ident)..k,v)
|
||||||
|
if type(v) == "table" then
|
||||||
|
rprint(v,ident+4)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
-- Conf parser
|
-- Conf parser
|
||||||
local data = [[
|
local data = [[
|
||||||
# Global variables
|
# Global variables
|
||||||
|
@ -45,3 +54,163 @@ for k,v in pairs(parsers.conf(data)) do
|
||||||
print(kk,vv)
|
print(kk,vv)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- yaml-like (pactl) parser
|
||||||
|
data = [[
|
||||||
|
Sink Input #75
|
||||||
|
Driver: PipeWire
|
||||||
|
Owner Module: n/a
|
||||||
|
Client: 58
|
||||||
|
Sink: 46
|
||||||
|
Sample Specification: float32le 2ch 44100Hz
|
||||||
|
Channel Map: front-left,front-right
|
||||||
|
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\""
|
||||||
|
Corked: no
|
||||||
|
Mute: no
|
||||||
|
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB
|
||||||
|
balance 0.00
|
||||||
|
Buffer Latency: 0 usec
|
||||||
|
Sink Latency: 0 usec
|
||||||
|
Resample method: PipeWire
|
||||||
|
Properties:
|
||||||
|
client.api = "pipewire-pulse"
|
||||||
|
pulse.server.type = "unix"
|
||||||
|
application.name = "LibreWolf"
|
||||||
|
application.process.id = "1756"
|
||||||
|
application.process.user = "yessiest"
|
||||||
|
application.process.host = "architect"
|
||||||
|
application.process.binary = "librewolf"
|
||||||
|
application.language = "C.UTF-8"
|
||||||
|
window.x11.display = ":0"
|
||||||
|
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c"
|
||||||
|
application.process.session_id = "1"
|
||||||
|
media.name = "AudioStream"
|
||||||
|
node.rate = "1/44100"
|
||||||
|
node.latency = "3307/44100"
|
||||||
|
stream.is-live = "true"
|
||||||
|
node.name = "LibreWolf"
|
||||||
|
node.autoconnect = "true"
|
||||||
|
node.want-driver = "true"
|
||||||
|
media.class = "Stream/Output/Audio"
|
||||||
|
adapt.follower.spa-node = ""
|
||||||
|
object.register = "false"
|
||||||
|
factory.id = "6"
|
||||||
|
clock.quantum-limit = "8192"
|
||||||
|
factory.mode = "split"
|
||||||
|
audio.adapt.follower = ""
|
||||||
|
library.name = "audioconvert/libspa-audioconvert"
|
||||||
|
client.id = "56"
|
||||||
|
object.id = "57"
|
||||||
|
object.serial = "75"
|
||||||
|
pulse.attr.maxlength = "4194304"
|
||||||
|
pulse.attr.tlength = "44104"
|
||||||
|
pulse.attr.prebuf = "35296"
|
||||||
|
pulse.attr.minreq = "8816"
|
||||||
|
module-stream-restore.id = "sink-input-by-application-name:LibreWolf"
|
||||||
|
]]
|
||||||
|
rprint(parsers.yaml_pseudo(data))
|
||||||
|
-- Fast incomplete yaml parser
|
||||||
|
data = [[
|
||||||
|
Sink Input #73
|
||||||
|
Driver: PipeWire
|
||||||
|
Owner Module: n/a
|
||||||
|
Client: 58
|
||||||
|
Sink: 46
|
||||||
|
Sample Specification: float32le 2ch 44100Hz
|
||||||
|
Channel Map: front-left,front-right
|
||||||
|
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\""
|
||||||
|
Corked: no
|
||||||
|
Mute: no
|
||||||
|
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB
|
||||||
|
balance 0.00
|
||||||
|
Buffer Latency: 0 usec
|
||||||
|
Sink Latency: 0 usec
|
||||||
|
Resample method: PipeWire
|
||||||
|
Properties:
|
||||||
|
client.api = "pipewire-pulse"
|
||||||
|
pulse.server.type = "unix"
|
||||||
|
application.name = "LibreWolf"
|
||||||
|
application.process.id = "1756"
|
||||||
|
application.process.user = "yessiest"
|
||||||
|
application.process.host = "architect"
|
||||||
|
application.process.binary = "librewolf"
|
||||||
|
application.language = "C.UTF-8"
|
||||||
|
window.x11.display = ":0"
|
||||||
|
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c"
|
||||||
|
application.process.session_id = "1"
|
||||||
|
media.name = "AudioStream"
|
||||||
|
node.rate = "1/44100"
|
||||||
|
node.latency = "3307/44100"
|
||||||
|
stream.is-live = "true"
|
||||||
|
node.name = "LibreWolf"
|
||||||
|
node.autoconnect = "true"
|
||||||
|
node.want-driver = "true"
|
||||||
|
media.class = "Stream/Output/Audio"
|
||||||
|
adapt.follower.spa-node = ""
|
||||||
|
object.register = "false"
|
||||||
|
factory.id = "6"
|
||||||
|
clock.quantum-limit = "8192"
|
||||||
|
factory.mode = "split"
|
||||||
|
audio.adapt.follower = ""
|
||||||
|
library.name = "audioconvert/libspa-audioconvert"
|
||||||
|
client.id = "56"
|
||||||
|
object.id = "57"
|
||||||
|
object.serial = "75"
|
||||||
|
pulse.attr.maxlength = "4194304"
|
||||||
|
pulse.attr.tlength = "44104"
|
||||||
|
pulse.attr.prebuf = "35296"
|
||||||
|
pulse.attr.minreq = "8816"
|
||||||
|
module-stream-restore.id = "sink-input-by-application-name:LibreWolf"
|
||||||
|
|
||||||
|
Sink Input #75
|
||||||
|
Driver: PipeWire
|
||||||
|
Owner Module: n/a
|
||||||
|
Client: 58
|
||||||
|
Sink: 46
|
||||||
|
Sample Specification: float32le 2ch 44100Hz
|
||||||
|
Channel Map: front-left,front-right
|
||||||
|
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\""
|
||||||
|
Corked: no
|
||||||
|
Mute: no
|
||||||
|
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB
|
||||||
|
balance 0.00
|
||||||
|
Buffer Latency: 0 usec
|
||||||
|
Sink Latency: 0 usec
|
||||||
|
Resample method: PipeWire
|
||||||
|
Properties:
|
||||||
|
client.api = "pipewire-pulse"
|
||||||
|
pulse.server.type = "unix"
|
||||||
|
application.name = "LibreWolf"
|
||||||
|
application.process.id = "1756"
|
||||||
|
application.process.user = "yessiest"
|
||||||
|
application.process.host = "architect"
|
||||||
|
application.process.binary = "librewolf"
|
||||||
|
application.language = "C.UTF-8"
|
||||||
|
window.x11.display = ":0"
|
||||||
|
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c"
|
||||||
|
application.process.session_id = "1"
|
||||||
|
media.name = "AudioStream"
|
||||||
|
node.rate = "1/44100"
|
||||||
|
node.latency = "3307/44100"
|
||||||
|
stream.is-live = "true"
|
||||||
|
node.name = "LibreWolf"
|
||||||
|
node.autoconnect = "true"
|
||||||
|
node.want-driver = "true"
|
||||||
|
media.class = "Stream/Output/Audio"
|
||||||
|
adapt.follower.spa-node = ""
|
||||||
|
object.register = "false"
|
||||||
|
factory.id = "6"
|
||||||
|
clock.quantum-limit = "8192"
|
||||||
|
factory.mode = "split"
|
||||||
|
audio.adapt.follower = ""
|
||||||
|
library.name = "audioconvert/libspa-audioconvert"
|
||||||
|
client.id = "56"
|
||||||
|
object.id = "57"
|
||||||
|
object.serial = "75"
|
||||||
|
pulse.attr.maxlength = "4194304"
|
||||||
|
pulse.attr.tlength = "44104"
|
||||||
|
pulse.attr.prebuf = "35296"
|
||||||
|
pulse.attr.minreq = "8816"
|
||||||
|
module-stream-restore.id = "sink-input-by-application-name:LibreWolf"
|
||||||
|
]]
|
||||||
|
rprint(parsers.fast_split_yaml(data))
|
||||||
|
|
|
@ -34,7 +34,60 @@ local function split_strings(text)
|
||||||
return split
|
return split
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parsers.fast_split_yaml = function(cfgtext)
|
||||||
|
-- Fast yaml splitter - incomplete parsing, only first layer is parsed
|
||||||
|
-- Used within timers to find objects while decreasing CPU usage
|
||||||
|
local items = {}
|
||||||
|
local replacements = 1
|
||||||
|
cfgtext = cfgtext:gsub("^%s*","")
|
||||||
|
while replacements > 0 do
|
||||||
|
cfgtext,replacements = cfgtext:gsub("^(.-\n)(%S+)",function(struct,n)
|
||||||
|
table.insert(items,struct)
|
||||||
|
return ""..n
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
table.insert(items,cfgtext)
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
parsers.yaml_pseudo = function(cfgtext)
|
||||||
|
-- Somewhat yaml-like structure used by pactl
|
||||||
|
local struct = {}
|
||||||
|
local lines = {}
|
||||||
|
cfgtext:gsub("(%s*)([^\n]*)",function(spacing,line)
|
||||||
|
table.insert(lines,
|
||||||
|
{
|
||||||
|
spacing:len(),
|
||||||
|
-- key
|
||||||
|
line:match("^([^:=]-)%s*[:=]") or line,
|
||||||
|
-- value
|
||||||
|
line:match(":%s*(.-)%s*$") or
|
||||||
|
line:match("=%s*(.-)%s*$")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
local history = {struct}
|
||||||
|
local spacing_width = 0
|
||||||
|
for k,v in pairs(lines) do
|
||||||
|
if v[1] > spacing_width then
|
||||||
|
history[#history][lines[k-1][2]] = {
|
||||||
|
[lines[k-1][2]] = lines[k-1][3]
|
||||||
|
}
|
||||||
|
history[#history+1] = history[#history][lines[k-1][2]]
|
||||||
|
elseif v[1] < spacing_width then
|
||||||
|
history[#history] = nil
|
||||||
|
end
|
||||||
|
if v[3] and v[3]:match("^%s*\".*\"%s*$") then
|
||||||
|
history[#history][v[2]] = v[3]:match("^%s*\"(.*)\"%s*$")
|
||||||
|
else
|
||||||
|
history[#history][v[2]] = v[3]
|
||||||
|
end
|
||||||
|
spacing_width = v[1]
|
||||||
|
end
|
||||||
|
return struct
|
||||||
|
end
|
||||||
|
|
||||||
parsers.conf = function(cfgtext)
|
parsers.conf = function(cfgtext)
|
||||||
|
-- Conf style parser (not exactly TOML)
|
||||||
cfgtext = cfgtext:gsub("#[^\n]*","")
|
cfgtext = cfgtext:gsub("#[^\n]*","")
|
||||||
local split_by_strings,err = split_strings(cfgtext)
|
local split_by_strings,err = split_strings(cfgtext)
|
||||||
if not split_by_strings then
|
if not split_by_strings then
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
local syscontrol = {
|
local syscontrol = {
|
||||||
power_supply = {},
|
power_supply = {},
|
||||||
backlight = {},
|
backlight = {},
|
||||||
hwmon = {}
|
hwmon = {},
|
||||||
|
pulse = {}
|
||||||
}
|
}
|
||||||
syscontrol.backlight.enumerate = function()
|
syscontrol.backlight.enumerate = function()
|
||||||
local lshandler = io.popen("ls -1 /sys/class/backlight","r")
|
local lshandler = io.popen("ls -1 /sys/class/backlight","r")
|
||||||
|
|
|
@ -11,7 +11,7 @@ local gears = require("gears")
|
||||||
local ask = require("asckey")
|
local ask = require("asckey")
|
||||||
global.modkey = global.modkey or "Mod4"
|
global.modkey = global.modkey or "Mod4"
|
||||||
|
|
||||||
ask.keymap = keybindings
|
ask.set_keymap(config.keys)
|
||||||
local custom_keys = ask.custom_binds()
|
local custom_keys = ask.custom_binds()
|
||||||
local k = ask.k
|
local k = ask.k
|
||||||
|
|
||||||
|
@ -101,7 +101,22 @@ local clientkeys = gears.table.join(
|
||||||
c.maximized = not c.maximized
|
c.maximized = not c.maximized
|
||||||
c:raise()
|
c:raise()
|
||||||
end ,
|
end ,
|
||||||
{description = "(un)maximize", group = "client"}))
|
{description = "(un)maximize", group = "client"}),
|
||||||
|
k(":client.pin",
|
||||||
|
function (c)
|
||||||
|
c.sticky = not c.sticky
|
||||||
|
end ,
|
||||||
|
{description = "(un)pin", group = "client"}),
|
||||||
|
k(":client.toggle_titlebars",
|
||||||
|
function (c)
|
||||||
|
if (not c.titlebar_top.visible) then
|
||||||
|
c:emit_signal("titlebar::unhide")
|
||||||
|
else
|
||||||
|
c:emit_signal("titlebar::hide")
|
||||||
|
end
|
||||||
|
end ,
|
||||||
|
{description = "(un)hide titlebars", group = "client"}))
|
||||||
|
|
||||||
awful.rules.rules[1].properties.keys = clientkeys
|
awful.rules.rules[1].properties.keys = clientkeys
|
||||||
|
|
||||||
local clientbuttons = gears.table.join(
|
local clientbuttons = gears.table.join(
|
||||||
|
|
|
@ -156,7 +156,7 @@ client.connect_signal("request::titlebars",function(c)
|
||||||
fg_focus = style[v].fg_focus,
|
fg_focus = style[v].fg_focus,
|
||||||
font = style[v].font
|
font = style[v].font
|
||||||
})
|
})
|
||||||
titlebar:setup(t.titlebar(contents))
|
c[v] = titlebar:setup(t.titlebar(contents))
|
||||||
awful.rules.rules[1].properties.placement(c)
|
awful.rules.rules[1].properties.placement(c)
|
||||||
if style[v].onfocus then
|
if style[v].onfocus then
|
||||||
c:connect_signal("focus",function()
|
c:connect_signal("focus",function()
|
||||||
|
@ -168,6 +168,12 @@ client.connect_signal("request::titlebars",function(c)
|
||||||
style[v].onunfocus(titlebar)
|
style[v].onunfocus(titlebar)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
c:connect_signal("titlebar::hide",function(c)
|
||||||
|
c[v].visible = false
|
||||||
|
end)
|
||||||
|
c:connect_signal("titlebar::unhide",function(c)
|
||||||
|
c[v].visible = true
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end --}}}
|
end --}}}
|
||||||
|
|
|
@ -12,16 +12,8 @@ local conf_file = io.open(root_path.."/desktop.conf","r")
|
||||||
if not conf_file then
|
if not conf_file then
|
||||||
error("desktop.conf is missing or not readable")
|
error("desktop.conf is missing or not readable")
|
||||||
end
|
end
|
||||||
local config = conf(conf_file:read("*a"))
|
config = conf(conf_file:read("*a"))
|
||||||
conf_file:close()
|
conf_file:close()
|
||||||
global = config.global
|
global = config.global
|
||||||
global.terminal = envsub(global.terminal)
|
global.terminal = envsub(global.terminal)
|
||||||
global.browser = envsub(global.browser)
|
global.browser = envsub(global.browser)
|
||||||
local function invert(t)
|
|
||||||
local new_t = {}
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
new_t[v] = k
|
|
||||||
end
|
|
||||||
return new_t
|
|
||||||
end
|
|
||||||
keybindings = invert(config.keys)
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
-- This file is part of Reno desktop.
|
||||||
|
--
|
||||||
|
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
-- Powerman X - second generation of the power management daemon
|
||||||
|
local sysctl = require("syscontrol")
|
||||||
|
local naughty = require("naughty")
|
||||||
|
local gears = require("gears")
|
||||||
|
local awful = require("awful")
|
||||||
|
local batteries = sysctl.power_supply.enumerate()
|
||||||
|
local state_tracking = {}
|
||||||
|
-- Configuration variables
|
||||||
|
local cfg = config.powerman or {}
|
||||||
|
local quality_min = cfg.battery_quality_min or 33
|
||||||
|
local capacity_min = cfg.battery_capacity_min or 15
|
||||||
|
-- Main loop
|
||||||
|
local update_loop = gears.timer({
|
||||||
|
timeout = 2,
|
||||||
|
autostart = true,
|
||||||
|
callback = function()
|
||||||
|
for k,v in pairs(batteries) do
|
||||||
|
local data,err = sysctl.power_supply.read_attribs(v)
|
||||||
|
state_tracking[v] = state_tracking[v] or {}
|
||||||
|
if data.type == "Battery" then
|
||||||
|
if (tonumber(data.quality) < quality_min) and
|
||||||
|
(not state_tracking[v].quality_notification) then
|
||||||
|
naughty.notify({
|
||||||
|
title = "Critical battery condition",
|
||||||
|
text = "Battery "..data.name.." has reached critically low condition, seek a suitable replacement"
|
||||||
|
})
|
||||||
|
state_tracking[v].quality_notification = true
|
||||||
|
end
|
||||||
|
if (tonumber(data.capacity) <= capacity_min) and
|
||||||
|
(not data.charging) and
|
||||||
|
(not state_tracking[v].capacity_notification) then
|
||||||
|
naughty.notify({
|
||||||
|
title = "Battery capacity low",
|
||||||
|
text = "Battery "..data.name.." capacity is at "..tostring(data.capacity).."%"
|
||||||
|
})
|
||||||
|
state_tracking[v].capacity_notification = true
|
||||||
|
end
|
||||||
|
if (tonumber(data.capacity) > capacity_min) then
|
||||||
|
state_tracking[v].capacity_notification = false
|
||||||
|
end
|
||||||
|
if (data.capacity == "100") and
|
||||||
|
(data.charging) and
|
||||||
|
(not state_tracking[v].charged_notification) then
|
||||||
|
naughty.notify({
|
||||||
|
title = "Battery is completely charged",
|
||||||
|
text = "Disconnect the charger from the power grid to avoid passive electricity usage."
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if (not data.charging) then
|
||||||
|
state_tracking[v].charged_notification = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
1
rc.lua
1
rc.lua
|
@ -16,6 +16,7 @@ package.cpath = package.cpath
|
||||||
-- Modules list
|
-- Modules list
|
||||||
require("modules.collect_garbage")
|
require("modules.collect_garbage")
|
||||||
require("modules.global")
|
require("modules.global")
|
||||||
|
require("modules.powermanX")
|
||||||
require("modules.errorlog")
|
require("modules.errorlog")
|
||||||
require("modules.base")
|
require("modules.base")
|
||||||
require("modules.binds")
|
require("modules.binds")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"list": [
|
"list": [
|
||||||
|
{"widget": "widgets.clientvolume"},
|
||||||
{"widget": "widgets.clientcontrols"},
|
{"widget": "widgets.clientcontrols"},
|
||||||
{"widget": "widgets.clientbuttons"}
|
{"widget": "widgets.clientbuttons"}
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- Reno98 - a retro replica of a very recognizable theme
|
-- Reno Unity - Unity theme for Reno desktop
|
||||||
--[[
|
--[[
|
||||||
Reno98 - A theme for Reno desktop
|
Reno Unity - A theme for Reno desktop
|
||||||
|
|
||||||
Written in 2022 by Yessiest (yessiest@memeware.net)
|
Written in 2022 by Yessiest (yessiest@memeware.net)
|
||||||
|
|
||||||
|
@ -306,11 +306,20 @@ theme.widgets = {
|
||||||
end,
|
end,
|
||||||
height = 20,
|
height = 20,
|
||||||
width = 140,
|
width = 140,
|
||||||
|
bg_focus = theme.bg_normal,
|
||||||
|
bg_normal = theme.bg_focus,
|
||||||
handle_width = 8,
|
handle_width = 8,
|
||||||
handle_border_color = theme.bg_focus,
|
handle_border_color = theme.bg_normal,
|
||||||
handle_border_width = 2,
|
handle_border_width = 2,
|
||||||
bar_height = 6
|
bar_height = 6,
|
||||||
}
|
bar_border_color = theme.bg_focus,
|
||||||
|
bar_border_width = 2
|
||||||
|
},
|
||||||
|
checkbox = {
|
||||||
|
shape = gears.shape.circle,
|
||||||
|
shape_border_width = 3,
|
||||||
|
shaoe_border_color = theme.bg_focus
|
||||||
|
},
|
||||||
},
|
},
|
||||||
-- }}}
|
-- }}}
|
||||||
-- {{{ Menus
|
-- {{{ Menus
|
||||||
|
|
|
@ -12,6 +12,7 @@ local gears = require("gears")
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
local awmtk2 = require("awmtk2")
|
local awmtk2 = require("awmtk2")
|
||||||
local syscontrol = require("syscontrol")
|
local syscontrol = require("syscontrol")
|
||||||
|
local ask = require("asckey")
|
||||||
|
|
||||||
local function get_virtual_icon(data)
|
local function get_virtual_icon(data)
|
||||||
-- Get an icon from a cumulative total of battery percentages and current charging state
|
-- Get an icon from a cumulative total of battery percentages and current charging state
|
||||||
|
@ -182,14 +183,25 @@ return function(args)
|
||||||
-- }}}
|
-- }}}
|
||||||
-- {{{ Backlight
|
-- {{{ Backlight
|
||||||
local backlight_devices = syscontrol.backlight.enumerate()
|
local backlight_devices = syscontrol.backlight.enumerate()
|
||||||
|
local default_backlight_device
|
||||||
for k,v in pairs(backlight_devices) do
|
for k,v in pairs(backlight_devices) do
|
||||||
local data = syscontrol.backlight.read_attribs(v)
|
local data = syscontrol.backlight.read_attribs(v)
|
||||||
if data then
|
if data then
|
||||||
widget_map[data.name] = wibox.widget(t.container({
|
widget_map[data.name] = wibox.widget(t.container({
|
||||||
|
{
|
||||||
t.article({
|
t.article({
|
||||||
icon = beautiful["backlight-symbolic"],
|
icon = beautiful["backlight-symbolic"],
|
||||||
title = "Backlight",
|
title = "Backlight",
|
||||||
}),
|
}),
|
||||||
|
(data.writable and t.checkbox({
|
||||||
|
checked = true,
|
||||||
|
id = "checkbox",
|
||||||
|
forced_height = style.article.icon_size,
|
||||||
|
forced_width = style.article.icon_size
|
||||||
|
})),
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
spacing = style.base.spacing
|
||||||
|
},
|
||||||
t.textbox({
|
t.textbox({
|
||||||
markup = "Brightness: "..tostring(data.brightness),
|
markup = "Brightness: "..tostring(data.brightness),
|
||||||
id = "brightness_id"
|
id = "brightness_id"
|
||||||
|
@ -201,7 +213,7 @@ return function(args)
|
||||||
(data.writable and t.slider({
|
(data.writable and t.slider({
|
||||||
minimum = data.max_brightness*0.05,
|
minimum = data.max_brightness*0.05,
|
||||||
maximum = data.max_brightness,
|
maximum = data.max_brightness,
|
||||||
value = data.brightness,
|
value = tonumber(data.brightness),
|
||||||
id = "slider"
|
id = "slider"
|
||||||
})),
|
})),
|
||||||
layout = wibox.layout.fixed.vertical
|
layout = wibox.layout.fixed.vertical
|
||||||
|
@ -210,11 +222,22 @@ return function(args)
|
||||||
bgimage = style.container.bgimage_highlight
|
bgimage = style.container.bgimage_highlight
|
||||||
}))
|
}))
|
||||||
if data.writable then
|
if data.writable then
|
||||||
local slider = widget_map[data.name]:get_children_by_id("slider")[1]
|
local w = widget_map[data.name]
|
||||||
|
local slider = w:get_children_by_id("slider")[1]
|
||||||
slider:connect_signal("widget::redraw_needed",function(self)
|
slider:connect_signal("widget::redraw_needed",function(self)
|
||||||
local value = self.value
|
local value = self.value
|
||||||
syscontrol.backlight.set_brightness(data,math.floor(value))
|
syscontrol.backlight.set_brightness(data,math.floor(value))
|
||||||
end)
|
end)
|
||||||
|
slider.value = tonumber(data.brightness)
|
||||||
|
local checkbox = w:get_children_by_id("checkbox")[1]
|
||||||
|
checkbox:connect_signal("button::press",function()
|
||||||
|
if default_backlight_device then
|
||||||
|
local check2 = widget_map[default_backlight_device.name]
|
||||||
|
:get_children_by_id("checkbox")[1]
|
||||||
|
check2.checked = false
|
||||||
|
end
|
||||||
|
default_backlight_device = data
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
layout:add(widget_map[data.name])
|
layout:add(widget_map[data.name])
|
||||||
end
|
end
|
||||||
|
@ -236,6 +259,34 @@ return function(args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
-- Keybindings
|
||||||
|
root.keys(gears.table.join(
|
||||||
|
root.keys(),
|
||||||
|
ask.k(":battery.brightness_up",function()
|
||||||
|
if default_backlight_device then
|
||||||
|
local data = default_backlight_device
|
||||||
|
local s = widget_map[data.name]:get_children_by_id("slider")[1]
|
||||||
|
local value = s.value+(data.max_brightness*0.05)
|
||||||
|
if value > data.max_brightness then
|
||||||
|
value = data.max_brightness
|
||||||
|
end
|
||||||
|
syscontrol.backlight.set_brightness(data,math.floor(value))
|
||||||
|
s.value = math.floor(value)
|
||||||
|
end
|
||||||
|
end,{description="increase brightness", group = "widgets"}),
|
||||||
|
ask.k(":battery.brightness_down",function()
|
||||||
|
if default_backlight_device then
|
||||||
|
local data = default_backlight_device
|
||||||
|
local s = widget_map[data.name]:get_children_by_id("slider")[1]
|
||||||
|
local value = s.value-(data.max_brightness*0.05)
|
||||||
|
if value < data.max_brightness*0.05 then
|
||||||
|
value = data.max_brightness*0.05
|
||||||
|
end
|
||||||
|
syscontrol.backlight.set_brightness(data,math.floor(value))
|
||||||
|
s.value = math.floor(value)
|
||||||
|
end
|
||||||
|
end,{description="decrease brightness", group = "widgets"})
|
||||||
|
))
|
||||||
-- }}}
|
-- }}}
|
||||||
-- We don't need this widget if we don't have anything to show
|
-- We don't need this widget if we don't have anything to show
|
||||||
local function count(t)
|
local function count(t)
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
-- This file is part of Reno desktop.
|
||||||
|
--
|
||||||
|
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
-- Pulseaudio per-client volume setting
|
||||||
|
local awful = require("awful")
|
||||||
|
local gears = require("gears")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local awmtk2 = require("awmtk2")
|
||||||
|
local fastyaml = require("parsers").fast_split_yaml
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
local ask = require("asckey")
|
||||||
|
local pactl_data = {}
|
||||||
|
|
||||||
|
local test_pactl = os.execute("pactl --version")
|
||||||
|
local result = test_pactl
|
||||||
|
if _VERSION:match("5.1") then
|
||||||
|
result = (test_pactl == 0)
|
||||||
|
end
|
||||||
|
if not result then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_icon(percent)
|
||||||
|
if percent >= 66 then
|
||||||
|
return beautiful["volume-high-symbolic"]
|
||||||
|
elseif percent >= 33 then
|
||||||
|
return beautiful["volume-medium-symbolic"]
|
||||||
|
elseif percent > 0 then
|
||||||
|
return beautiful["volume-low-symbolic"]
|
||||||
|
else
|
||||||
|
return beautiful["volume-muted-symbolic"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return function(args)
|
||||||
|
local style = awmtk2.create_style("client_volume",
|
||||||
|
awmtk2.generic.oneline_widget, args.style)
|
||||||
|
local templates = awmtk2.create_template_lib("client_volume",awmtk2.templates,args.templates)
|
||||||
|
local t = awmtk2.build_templates(templates,style)
|
||||||
|
local widget = wibox.widget(t.container({
|
||||||
|
t.center({
|
||||||
|
id = "client_volume_icon",
|
||||||
|
widget = wibox.widget.imagebox
|
||||||
|
}),
|
||||||
|
t.textbox({
|
||||||
|
id = "error"
|
||||||
|
}),
|
||||||
|
t.slider({
|
||||||
|
minimum = 0,
|
||||||
|
maximum = 100,
|
||||||
|
id = "client_volume",
|
||||||
|
value = -1
|
||||||
|
}),
|
||||||
|
layout = wibox.layout.fixed.horizontal
|
||||||
|
}))
|
||||||
|
local errorbox = widget:get_children_by_id("error")[1]
|
||||||
|
local icon = widget:get_children_by_id("client_volume_icon")[1]
|
||||||
|
local slider = widget:get_children_by_id("client_volume")[1]
|
||||||
|
-- Local tracking value to prevent zero volume on start
|
||||||
|
local slider_touched = false
|
||||||
|
-- Get initial pactl data
|
||||||
|
awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
|
||||||
|
local pactl_data = fastyaml(stdout)
|
||||||
|
end)
|
||||||
|
-- Attach to focus change
|
||||||
|
client.connect_signal("update_volume",function(c)
|
||||||
|
awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
|
||||||
|
local pactl_data = fastyaml(stdout)
|
||||||
|
local cl
|
||||||
|
for k,v in pairs(pactl_data) do
|
||||||
|
if not c then return end
|
||||||
|
if v:match("application.process.id = \""..tostring(c.pid).."\"") then
|
||||||
|
cl = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not cl then
|
||||||
|
slider.visible = false
|
||||||
|
errorbox.visible = true
|
||||||
|
errorbox:set_markup("No sound/Not available")
|
||||||
|
icon:set_image(beautiful["volume-muted-symbolic"])
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local volume = tonumber(cl:match("Volume:[^\n]-(%d*)%%"))
|
||||||
|
slider.visible = true
|
||||||
|
errorbox.visible = false
|
||||||
|
icon:set_image(get_icon(volume))
|
||||||
|
slider.value = volume
|
||||||
|
touched = true
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
client.connect_signal("focus",function(c)
|
||||||
|
touched = false
|
||||||
|
c:emit_signal("update_volume")
|
||||||
|
end)
|
||||||
|
local update_timer = gears.timer({
|
||||||
|
timeout = 0.5,
|
||||||
|
autostart = true,
|
||||||
|
callback = function()
|
||||||
|
if client.focus then
|
||||||
|
client.focus:emit_signal("update_volume")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
-- Async lock to prevent callback interference
|
||||||
|
local volume_lock = false
|
||||||
|
-- Function to set client volume
|
||||||
|
local function volume(volume)
|
||||||
|
if volume_lock then return end
|
||||||
|
volume_lock = true
|
||||||
|
awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
|
||||||
|
local pactl_data = fastyaml(stdout)
|
||||||
|
local cl = {}
|
||||||
|
if not (client.focus and client.focus.pid) then
|
||||||
|
volume_lock = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for k,v in pairs(pactl_data) do
|
||||||
|
if v:match("application.process.id = \""..tostring(client.focus.pid).."\"") then
|
||||||
|
local sink_id = v:match("^%s*Sink Input #(%d+)")
|
||||||
|
if sink_id then
|
||||||
|
print(sink_id, volume)
|
||||||
|
awful.spawn("pactl set-sink-input-volume "..tostring(sink_id).." "..tostring(volume).."%")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
volume_lock = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
-- Attach change to slider
|
||||||
|
slider:connect_signal("widget::redraw_needed",function(widget)
|
||||||
|
if touched then
|
||||||
|
volume(slider.value)
|
||||||
|
update_timer:again()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
root.keys(gears.table.join(
|
||||||
|
root.keys(),
|
||||||
|
ask.k(":client.volume_up", function()
|
||||||
|
volume("+5")
|
||||||
|
end,{description = "increase client volume", group = "client"}),
|
||||||
|
ask.k(":client.volume_down", function()
|
||||||
|
volume("-5")
|
||||||
|
end,{description = "decrease client volume", group = "client"}),
|
||||||
|
ask.k(":client.volume_mute", function()
|
||||||
|
volume(0)
|
||||||
|
end,{description = "mute client", group = "client"})
|
||||||
|
))
|
||||||
|
return widget
|
||||||
|
end
|
|
@ -12,6 +12,7 @@ local wibox = require("wibox")
|
||||||
local gears = require("gears")
|
local gears = require("gears")
|
||||||
local awful = require("awful")
|
local awful = require("awful")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
|
local ask = require("asckey")
|
||||||
|
|
||||||
return function(args)
|
return function(args)
|
||||||
local style = awmtk2.create_style("soundclown",
|
local style = awmtk2.create_style("soundclown",
|
||||||
|
@ -72,15 +73,16 @@ return function(args)
|
||||||
local bprev = widget:get_children_by_id("prev")[1]
|
local bprev = widget:get_children_by_id("prev")[1]
|
||||||
bprev:connect_signal("button::press",style.button.onpress)
|
bprev:connect_signal("button::press",style.button.onpress)
|
||||||
bprev:connect_signal("button::release",style.button.onrelease)
|
bprev:connect_signal("button::release",style.button.onrelease)
|
||||||
bprev:connect_signal("button::press",function()
|
local function prev()
|
||||||
awful.spawn("mpc cdprev")
|
awful.spawn("mpc cdprev")
|
||||||
end)
|
end
|
||||||
|
bprev:connect_signal("button::press",prev)
|
||||||
local pause_state = true
|
local pause_state = true
|
||||||
local icon = widget:get_children_by_id("statusicon")[1]
|
local icon = widget:get_children_by_id("statusicon")[1]
|
||||||
local bplay = widget:get_children_by_id("play")[1]
|
local bplay = widget:get_children_by_id("play")[1]
|
||||||
bplay:connect_signal("button::press",style.button.onpress)
|
bplay:connect_signal("button::press",style.button.onpress)
|
||||||
bplay:connect_signal("button::release",style.button.onrelease)
|
bplay:connect_signal("button::release",style.button.onrelease)
|
||||||
bplay:connect_signal("button::press",function()
|
local function play()
|
||||||
pause_state = (not pause_state)
|
pause_state = (not pause_state)
|
||||||
if pause_state == false then
|
if pause_state == false then
|
||||||
icon.image = beautiful["mpc-pause-symbolic"]
|
icon.image = beautiful["mpc-pause-symbolic"]
|
||||||
|
@ -89,13 +91,16 @@ return function(args)
|
||||||
icon.image = beautiful["mpc-play-symbolic"]
|
icon.image = beautiful["mpc-play-symbolic"]
|
||||||
awful.spawn("mpc play")
|
awful.spawn("mpc play")
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
bplay:connect_signal("button::press",play)
|
||||||
local bnext = widget:get_children_by_id("next")[1]
|
local bnext = widget:get_children_by_id("next")[1]
|
||||||
bnext:connect_signal("button::press",style.button.onpress)
|
bnext:connect_signal("button::press",style.button.onpress)
|
||||||
bnext:connect_signal("button::release",style.button.onrelease)
|
bnext:connect_signal("button::release",style.button.onrelease)
|
||||||
bnext:connect_signal("button::press",function()
|
local function nextb()
|
||||||
awful.spawn("mpc next")
|
awful.spawn("mpc next")
|
||||||
end)
|
end
|
||||||
|
bnext:connect_signal("button::press",nextb)
|
||||||
|
local update_ready = true
|
||||||
local function update_mpd_status()
|
local function update_mpd_status()
|
||||||
awful.spawn.easy_async("mpc",function(out)
|
awful.spawn.easy_async("mpc",function(out)
|
||||||
local status = ""
|
local status = ""
|
||||||
|
@ -104,6 +109,7 @@ return function(args)
|
||||||
state = true
|
state = true
|
||||||
icon.image = beautiful["mpc-play-symbolic"]
|
icon.image = beautiful["mpc-play-symbolic"]
|
||||||
display:set_markup(status)
|
display:set_markup(status)
|
||||||
|
update_ready = true
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
status = status.."[PAUSED] "
|
status = status.."[PAUSED] "
|
||||||
|
@ -113,6 +119,7 @@ return function(args)
|
||||||
out:match("[^\n]*").." "..
|
out:match("[^\n]*").." "..
|
||||||
out:match("%d*:%d*/%d*:%d*%s*%(%d*%%%)")
|
out:match("%d*:%d*/%d*:%d*%s*%(%d*%%%)")
|
||||||
display:set_markup(status)
|
display:set_markup(status)
|
||||||
|
update_ready = true
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
update_mpd_status()
|
update_mpd_status()
|
||||||
|
@ -120,8 +127,19 @@ return function(args)
|
||||||
timeout = args.polling_delay or 1,
|
timeout = args.polling_delay or 1,
|
||||||
autostart = true,
|
autostart = true,
|
||||||
callback = function()
|
callback = function()
|
||||||
|
if not update_ready then return end
|
||||||
|
update_ready = false
|
||||||
update_mpd_status()
|
update_mpd_status()
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
root.keys(gears.table.join(
|
||||||
|
root.keys(),
|
||||||
|
ask.k(":mpc.prev",prev,
|
||||||
|
{description = "switch to previous MPD track",group="widgets"}),
|
||||||
|
ask.k(":mpc.play",play,
|
||||||
|
{description = "play/pause MPD",group="widgets"}),
|
||||||
|
ask.k(":mpc.next",nextb,
|
||||||
|
{description = "switch to next MPD track",group="widgets"})
|
||||||
|
))
|
||||||
return widget
|
return widget
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue