Added some extra project management utilities

This commit is contained in:
Yessiest 2022-12-11 02:28:22 +04:00
parent 379b838751
commit 0d3131a8f9
24 changed files with 423 additions and 107 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/links /links
/libs/pam /libs/pam
/libs/pam.so /libs/pam.so
/doc

4
.ldoc.lua Normal file
View File

@ -0,0 +1,4 @@
file = {"libs","modules","widgets"}
format = "markdown"
title = "Reno Desktop documentation"
description = "Reno Desktop is an AwesomeWM config that harnesses the power of AwesomeWM to bring the essential functionality of a desktop environment."

31
.luarc.json Normal file
View File

@ -0,0 +1,31 @@
{
"diagnostics": {
"enable": true,
"globals": [
"awesome",
"button",
"dbus",
"client",
"mouse",
"screen",
"root"
]
},
"runtime": {
"version": "Lua 5.3",
"path": [
"/usr/share/awesome/lib/?/?.lua"
],
"pathStrict": true
},
"workspace": {
"library": [
"runtime/lua",
"/usr/share/awesome/lib"
],
"checkThirdParty": false,
"maxPreload": 2000,
"preloadFileSize": 1000
},
"telemetry.enable": true
}

49
Rakefile Normal file
View File

@ -0,0 +1,49 @@
task default: [:install]
ConfigPath = (ENV["XDG_DATA_HOME"] or ENV["HOME"]+'/.config')
desc "Copy files to .config"
file "copy-config" => ["rc.lua"] do
sh "mkdir -p #{ConfigPath}/awesome"
["libs","modules","themes","widgets","rc.lua","desktop.conf"].each { |x|
cp_r "./#{x}" "#{ConfigPath}/awesome"
}
end
desc "Compile and install luapam"
file "build-luapam" => "#{ConfigPath}/libs/pam.so" do
sh "sh ./extra/install_luapam.sh"
end
desc "Install config"
task install: ["copy-config","build-luapam"]
desc "Build documentation"
task :doc do
sh "ldoc ./.ldoc.lua"
end
desc "Install extras"
task "install-extra" do
if Process.euid != 0
raise Exception, "You need to be root to install extras"
end
cp "./extra/udev/backlight.rules" "/etc/udev/rules.d"
mkdir "#{ConfigPath}/autostart"
begin
cp "/usr/share/applications/picom.desktop" "#{ConfigPath}/autostart/"
rescue
puts "picom not installed - ignoring"
else
cp "./extra/picom.conf" "#{ConfigPath}"
end
puts "Done! Reload awesome to complete installation"
end
desc "Uninstall from .config"
task :clean do
rm_rf "#{ConfigPath}/awesome"
end
desc "Wipe configuration and reinstall from scratch"
task reinstall: [:clean,:install]

View File

@ -17,6 +17,7 @@ modkey+Control+Down = ":root.screen_previous"
modkey+Tab = ":root.client_swap" modkey+Tab = ":root.client_swap"
modkey+Return = ":root.spawn_terminal" modkey+Return = ":root.spawn_terminal"
modkey+Shift+Return = ":root.spawn_browser" modkey+Shift+Return = ":root.spawn_browser"
modkey+Shift+y = ":root.toggle_titlebars"
# Client keys only work if a focused client exists # Client keys only work if a focused client exists
modkey+Shift+c = ":client.kill" modkey+Shift+c = ":client.kill"
@ -40,6 +41,7 @@ XF86MonBrightnessDown = ":battery.brightness_down"
XF86AudioPlay = ":mpc.play" XF86AudioPlay = ":mpc.play"
XF86AudioPrev = ":mpc.prev" XF86AudioPrev = ":mpc.prev"
XF86AudioNext = ":mpc.next" XF86AudioNext = ":mpc.next"
# Custom keys # Custom keys
Print = "flameshot gui" Print = "flameshot gui"
Shift+Print = "flameshot launcher" Shift+Print = "flameshot launcher"

View File

@ -1,6 +1,5 @@
backend = "xrender"; backend = "xrender";
vsync = true; vsync = true;
# Shadow # Shadow
shadow = true; # Enabled client-side shadows on windows. shadow = true; # Enabled client-side shadows on windows.
shadow-radius = 12; # The blur radius for shadows. (default 12) shadow-radius = 12; # The blur radius for shadows. (default 12)
@ -31,7 +30,8 @@ shadow-exclude = [
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher. # This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
# Fading # Fading
fading = true# Fade windows during opacity changes. fading = true;
# Fade windows during opacity changes.
fade-delta = 4; # The time between steps in a fade in milliseconds. (default 10). fade-delta = 4; # The time between steps in a fade in milliseconds. (default 10).
fade-in-step = 0.03; # Opacity change between steps while fading in. (default 0.028). fade-in-step = 0.03; # Opacity change between steps while fading in. (default 0.028).
fade-out-step = 0.03; # Opacity change between steps while fading out. (default 0.03). fade-out-step = 0.03; # Opacity change between steps while fading out. (default 0.03).

View File

@ -19,7 +19,6 @@ local awmtk = {}
awmtk.create_delta = function(name,instance_delta,class_delta,parent_delta) awmtk.create_delta = function(name,instance_delta,class_delta,parent_delta)
-- to save memory, we create proxies for lower layers called "deltas" -- to save memory, we create proxies for lower layers called "deltas"
-- this function creates that proxy layer using metatables -- this function creates that proxy layer using metatables
-- fun story - i used instance_delta instead of {} at first. -- fun story - i used instance_delta instead of {} at first.
-- the results were horrifying and confusing. -- the results were horrifying and confusing.
return setmetatable({},{ return setmetatable({},{
@ -86,8 +85,8 @@ end
awmtk.wrap_hooks = function(w,callbacks) awmtk.wrap_hooks = function(w,callbacks)
-- attach hooks to function -- attach hooks to function
local mcall = getmetatable(w).__call local mcall = (getmetatable(w) and getmetatable(w).__call) or w
return awmtk.mask_object_call(w,function(...) local call_wrapper = function(...)
if callbacks and callbacks.on_create_pre then if callbacks and callbacks.on_create_pre then
callbacks.on_create_pre(...) callbacks.on_create_pre(...)
end end
@ -96,8 +95,12 @@ awmtk.wrap_hooks = function(w,callbacks)
callbacks.on_create(widget,...) callbacks.on_create(widget,...)
end end
if callbacks and callbacks.on_ready then if callbacks and callbacks.on_ready then
callbacks._on_ready_called = false
local func = function() local func = function()
if not callbacks._on_ready_called then
callbacks.on_ready(widget) callbacks.on_ready(widget)
callbacks._on_ready_called = true
end
end end
widget:connect_signal("widget::layout_changed",func) widget:connect_signal("widget::layout_changed",func)
widget:connect_signal("widget::layout_changed",function() widget:connect_signal("widget::layout_changed",function()
@ -105,7 +108,9 @@ awmtk.wrap_hooks = function(w,callbacks)
end) end)
end end
return widget return widget
end) end
return (getmetatable(w) and awmtk.mask_object_call(w,call_wrapper)) or
call_wrapper
end end
awmtk.merge = gears.table.join awmtk.merge = gears.table.join
@ -245,7 +250,7 @@ awmtk.proto_templates = {
shape = style.button.shape, shape = style.button.shape,
shape_border_color = style.button.shape_border_color, shape_border_color = style.button.shape_border_color,
shape_border_width = style.button.shape_border_width, shape_border_width = style.button.shape_border_width,
widget = wibox.container.background widget = awmtk.wrap_hooks(wibox.container.background,options)
},options or {}) },options or {})
end end
end, end,
@ -255,7 +260,7 @@ awmtk.proto_templates = {
return function(options) return function(options)
return awmtk.merge({ return awmtk.merge({
font = style.textbox.font, font = style.textbox.font,
widget = wibox.widget.textbox, widget = awmtk.wrap_hooks(wibox.widget.textbox,options)
},options or {}) },options or {})
end end
end, end,
@ -264,7 +269,7 @@ awmtk.proto_templates = {
-- wow, i guess? -- wow, i guess?
return function(options) return function(options)
return awmtk.merge({ return awmtk.merge({
widget = wibox.widget.separator, widget = awmtk.wrap_hooks(wibox.widget.separator,options),
orientation = "horizontal", orientation = "horizontal",
thickness = style.separator.thickness, thickness = style.separator.thickness,
color = style.separator.color, color = style.separator.color,
@ -277,7 +282,7 @@ awmtk.proto_templates = {
-- i'm running out of comments -- i'm running out of comments
return function(options) return function(options)
return awmtk.merge({ return awmtk.merge({
widget = wibox.widget.separator, widget = awmtk.wrap_hooks(wibox.widget.separator,options),
orientation = "vertical", orientation = "vertical",
thickness = style.separator.thickness, thickness = style.separator.thickness,
color = style.separator.color, color = style.separator.color,
@ -332,7 +337,10 @@ awmtk.proto_templates = {
layout = wibox.layout.flex.vertical layout = wibox.layout.flex.vertical
}, },
spacing = style.article.spacing, spacing = style.article.spacing,
layout = wibox.layout.fixed.horizontal, layout = awmtk.wrap_hooks(
wibox.layout.fixed.horizontal,
options
)
}, options or {}) }, options or {})
end end
end, end,
@ -350,7 +358,10 @@ awmtk.proto_templates = {
style.center.width, style.center.width,
widget = wibox.container.constraint widget = wibox.container.constraint
}, },
widget = wibox.container.place, widget = awmtk.wrap_hooks(
wibox.container.place,
options
),
valign = "center", valign = "center",
halign = "center" halign = "center"
},options or {}) },options or {})
@ -365,7 +376,7 @@ awmtk.proto_templates = {
widget = { widget = {
widget, widget,
margins = style.popup.margins, margins = style.popup.margins,
layout = wibox.container.margin layout = awmtk.wrap_hooks(wibox.container.margin,options)
}, },
bgimage = style.popup.bgimage_normal, bgimage = style.popup.bgimage_normal,
shape = style.popup.shape, shape = style.popup.shape,
@ -393,7 +404,7 @@ awmtk.proto_templates = {
return awmtk.merge({ return awmtk.merge({
layout, layout,
margins = margins, margins = margins,
layout = wibox.container.margin, layout = awmtk.wrap_hooks(wibox.container.margin,options),
left = style.titlebar.left, left = style.titlebar.left,
right = style.titlebar.right, right = style.titlebar.right,
bottom = style.titlebar.bottom, bottom = style.titlebar.bottom,
@ -415,7 +426,7 @@ awmtk.proto_templates = {
return awmtk.merge({ return awmtk.merge({
layout, layout,
margins = margins, margins = margins,
layout = wibox.container.margin, layout = awmtk.wrap_hooks(wibox.container.margin,options),
left = style.wibar.left, left = style.wibar.left,
right = style.wibar.right, right = style.wibar.right,
bottom = style.wibar.bottom, bottom = style.wibar.bottom,
@ -442,7 +453,7 @@ awmtk.proto_templates = {
bar_border_color = style.slider.bar_border_color, bar_border_color = style.slider.bar_border_color,
forced_width = style.slider.width, forced_width = style.slider.width,
forced_height = style.slider.height, forced_height = style.slider.height,
widget = wibox.widget.slider widget = awmtk.wrap_hooks(wibox.widget.slider,args)
},args or {}) },args or {})
end end
end, end,
@ -450,13 +461,16 @@ awmtk.proto_templates = {
checkbox = function(style) checkbox = function(style)
return function(args) return function(args)
return awmtk.merge({ return awmtk.merge({
color = style.checkbox.bg_focus, color = style.checkbox.color or style.checkbox.bg_normal,
padding = 2, paddings = style.checkbox.paddings,
shape = style.checkbox.shape, shape = style.checkbox.shape,
border_width = style.checkbox.shape_border_width, border_width = style.checkbox.border_width,
bg = style.checkbox.shape_border_color, border_color = style.checkbox.border_color or style.checkbox.bg_normal,
widget = wibox.widget.checkbox bg = style.checkbox.bg or style.checkbox.bg_focus,
},args or {}) check_color = style.checkbox.check_color or style.checkbox.bg_normal,
check_shape = style.checkbox.check_shape,
widget = awmtk.wrap_hooks(wibox.widget.checkbox,args)
},args)
end end
end end
} }

View File

@ -14,6 +14,7 @@ global.modkey = global.modkey or "Mod4"
ask.set_keymap(config.keys) 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
local titlebar_states = {}
local keys = gears.table.join( local keys = gears.table.join(
k(':root.client_next', k(':root.client_next',
@ -54,6 +55,11 @@ local keys = gears.table.join(
awful.spawn(global.browser) awful.spawn(global.browser)
end, end,
{description = "open browser", group = "launcher"}), {description = "open browser", group = "launcher"}),
k(":root.toggle_titlebars",
function (c)
awesome.emit_signal("titlebar::toggle")
end ,
{description = "(un)hide all titlebars", group = "client"}),
table.unpack(custom_keys)) table.unpack(custom_keys))
root.keys(keys) root.keys(keys)
@ -109,14 +115,9 @@ local clientkeys = gears.table.join(
{description = "(un)pin", group = "client"}), {description = "(un)pin", group = "client"}),
k(":client.toggle_titlebars", k(":client.toggle_titlebars",
function (c) function (c)
if (not c.titlebar_top.visible) then c:emit_signal("titlebar::toggle")
c:emit_signal("titlebar::unhide")
else
c:emit_signal("titlebar::hide")
end
end , end ,
{description = "(un)hide titlebars", group = "client"})) {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(

View File

@ -116,15 +116,47 @@ table.insert(awful.rules.rules,
} }
) )
client.connect_signal("manage", function(c) local window_shape_hide = function(cr, width, height)
local shape = beautiful.window_shape or function(cr, width, height) return gears.shape.partially_rounded_rect(cr,width,height,
false,false,false,false,0)
end
local window_shape = beautiful.window_shape or function(cr, width, height)
return gears.shape.partially_rounded_rect(cr,width,height, return gears.shape.partially_rounded_rect(cr,width,height,
true,true,false,false,beautiful.window_rounding) true,true,false,false,beautiful.window_rounding)
end end
c.shape = shape
client.connect_signal("manage", function(c)
c.shape = window_shape
end) end)
client.connect_signal("request::titlebars",function(c) local titlebars_on = true
awesome.connect_signal("titlebar::toggle",function()
titlebars_on = not titlebars_on
for _,c in ipairs(client.get()) do
if titlebars_on then
for _, pos in ipairs({"top","bottom","left","right"}) do
awful.titlebar.show(c,pos)
end
c.shape = window_shape
c:emit_signal("titlebar::perform_action",function(titlebar)
titlebar.widget.visible = true
end)
else
for _, pos in ipairs({"top","bottom","left","right"}) do
awful.titlebar.hide(c,pos)
end
c.shape = window_shape_hide
c:emit_signal("titlebar::perform_action",function(titlebar)
titlebar.widget.visible = false
end)
end
end
end)
-- Second manage call to create hidden titlebars
client.connect_signal("manage",function(c)
-- Drag and resize buttons
local buttons = gears.table.join( local buttons = gears.table.join(
awful.button({}, 1, function() awful.button({}, 1, function()
c:emit_signal("request::activate","titlebar",{raise=true}) c:emit_signal("request::activate","titlebar",{raise=true})
@ -135,8 +167,10 @@ client.connect_signal("request::titlebars",function(c)
awful.mouse.client.resize(c) awful.mouse.client.resize(c)
end) end)
) )
-- Building the titlebars
for k,v in pairs({"titlebar_top","titlebar_bottom","titlebar_left","titlebar_right"}) do for k,v in pairs({"titlebar_top","titlebar_bottom","titlebar_left","titlebar_right"}) do
local contents = { widget = wibox.container.background } -- Build content of the titlebar
local contents = { widget = wibox.widget.textbox, text = "" }
if titlebar_config[v] then if titlebar_config[v] then
contents = builder(titlebar_config[v],{ contents = builder(titlebar_config[v],{
client = c, client = c,
@ -145,6 +179,7 @@ client.connect_signal("request::titlebars",function(c)
buttons = buttons buttons = buttons
}) })
end end
-- Create the base
local titlebar = awful.titlebar(c,{ local titlebar = awful.titlebar(c,{
size = style[v].size or 0, size = style[v].size or 0,
position = v:gsub("titlebar_",""), position = v:gsub("titlebar_",""),
@ -156,8 +191,14 @@ 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
}) })
c[v] = titlebar:setup(t.titlebar(contents)) -- Compile and build titlebar
titlebar:setup(t.titlebar({
contents,
widget = wibox.container.background
}))
-- Since new clients will be placed without titlebars, we need to apply placement rules again
awful.rules.rules[1].properties.placement(c) awful.rules.rules[1].properties.placement(c)
-- Callbacks for focus/unfocus of titlebars
if style[v].onfocus then if style[v].onfocus then
c:connect_signal("focus",function() c:connect_signal("focus",function()
style[v].onfocus(titlebar) style[v].onfocus(titlebar)
@ -168,12 +209,32 @@ 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) -- Activate focus callback if our client is focused
c[v].visible = false if (c == client.focus) and (style[v].onfocus) then
style[v].onfocus(titlebar)
end
-- Add a titlebar toggle signal
c:connect_signal("titlebar::toggle",function(c)
titlebar.widget.visible = not titlebar.widget.visible
if titlebar.widget.visible then
awful.titlebar.show(c,v:gsub("titlebar_",""))
c.shape = window_shape
else
awful.titlebar.hide(c,v:gsub("titlebar_",""))
c.shape = window_shape_hide
end
end) end)
c:connect_signal("titlebar::unhide",function(c) c:connect_signal("titlebar::perform_action",function(c,f)
c[v].visible = true f(titlebar)
end) end)
-- Add rules for hiding titlebars on creation
if (not titlebars_on) or
(c.titlebars_enabled == false) or
(c.requests_no_titlebar == true) then
titlebar.widget.visible = false
c.shape = window_shape_hide
awful.titlebar.hide(c,v:gsub("titlebar_",""))
end
end end
end) end)
end --}}} end --}}}

View File

@ -374,6 +374,7 @@ theme.widgets = {
end, end,
}, },
titlebar = { titlebar = {
hidden_size = 2,
bgimage_normal = theme.bgimage_outset, bgimage_normal = theme.bgimage_outset,
--margins = 5, --margins = 5,
left = 4, left = 4,

View File

@ -1,2 +1,3 @@
A compositor (like compton) is ***required*** for this theme to work as intended. A compositor (like compton) is ***required*** for this theme to work as intended.
This is in part due to the fact that it makes the top bar look less bland, and in part due to the fact that your titlebar corners will look weird otherwise. This is in part due to the fact that it makes the top bar look less bland, and in part due to the fact that your titlebar corners will look weird otherwise (the corners won't be properly cut).
You may, of course, dismiss using a compositor, but don't tell me about not exactly round corners being a "bug" in this theme afterwards - it's the best you can get with Awesome.

View File

@ -0,0 +1,32 @@
{
"list": [
{
"list": [
{"widget": "widgets.base.popuptitle",
"options":{
"title":"Reno Unity"
}
},
{"widget": "widgets.rootcontrols"},
{"widget": "widgets.xdgmenu",
"options": {
"exclude_category": [
"Other"
]
}
}
],
"vertical": true
},
{
"list":[
{"widget": "widgets.base.tagswitcher",
"screen":true
},
{"widget": "widgets.rootbuttons"}
],
"vertical":true
}
],
"vertical":false
}

View File

@ -7,6 +7,7 @@
], ],
"right": [ "right": [
{ "widget":"widgets.volume" },
{ "widget": "widgets.notifications", { "widget": "widgets.notifications",
"screen": true "screen": true
}, },

BIN
themes/unity/icons/reno.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -12,8 +12,6 @@ local theme_assets = require("beautiful.theme_assets")
local xresources = require("beautiful.xresources") local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi local dpi = xresources.apply_dpi
local gears = require("gears") local gears = require("gears")
local gfs = require("gears.filesystem")
local themes_path = root_path.."/themes/" local themes_path = root_path.."/themes/"
local theme = {} local theme = {}
@ -214,6 +212,12 @@ theme["mpc-next-symbolic"] = themes_path.."unity/icons/mpc-next-symbolic.png"
theme["action-poweroff-symbolic"] = themes_path.."unity/icons/action-poweroff-symbolic.png" theme["action-poweroff-symbolic"] = themes_path.."unity/icons/action-poweroff-symbolic.png"
theme["action-lock-screen-symbolic"] = themes_path.."unity/icons/action-lock-screen-symbolic.png" theme["action-lock-screen-symbolic"] = themes_path.."unity/icons/action-lock-screen-symbolic.png"
theme["action-suspend-symbolic"] = themes_path.."unity/icons/action-suspend-symbolic.png" theme["action-suspend-symbolic"] = themes_path.."unity/icons/action-suspend-symbolic.png"
theme["volume-high-symbolic"] = themes_path.."unity/icons/volume-high-symbolic.png"
theme["volume-medium-symbolic"] = themes_path.."unity/icons/volume-medium-symbolic.png"
theme["volume-low-symbolic"] = themes_path.."unity/icons/volume-low-symbolic.png"
theme["volume-muted-symbolic"] = themes_path.."unity/icons/volume-muted-symbolic.png"
theme.wallpaper = themes_path.."unity/background.png" theme.wallpaper = themes_path.."unity/background.png"
theme.wallpapers_icon = themes_path.."unity/icons/wallpapers.png" theme.wallpapers_icon = themes_path.."unity/icons/wallpapers.png"
-- Default icon for clients -- Default icon for clients
@ -244,7 +248,11 @@ for k,v in pairs({
"action-lock-screen-symbolic", "action-lock-screen-symbolic",
"action-suspend-symbolic", "action-suspend-symbolic",
"wallpapers_icon", "wallpapers_icon",
"icon_default"}) do "icon_default",
"volume-high-symbolic",
"volume-medium-symbolic",
"volume-low-symbolic",
"volume-muted-symbolic"}) do
if theme[v] and gears.filesystem.file_readable(theme[v]) then if theme[v] and gears.filesystem.file_readable(theme[v]) then
theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal) theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal)
end end
@ -281,6 +289,7 @@ theme.widgets = {
end, end,
}, },
titlebar = { titlebar = {
hidden_size = 2,
root_shape = function(cr,width,height) root_shape = function(cr,width,height)
return gears.shape.partially_rounded_rect(cr,width,height, return gears.shape.partially_rounded_rect(cr,width,height,
true,true,false,false,6) end, true,true,false,false,6) end,
@ -316,9 +325,12 @@ theme.widgets = {
bar_border_width = 2 bar_border_width = 2
}, },
checkbox = { checkbox = {
width = 15,
height = 15,
shape = gears.shape.circle, shape = gears.shape.circle,
shape_border_width = 3, border_width = 3,
shaoe_border_color = theme.bg_focus border_color = theme.bg_normal,
paddings = {2,2,2,2}
}, },
}, },
-- }}} -- }}}
@ -541,15 +553,16 @@ theme.widgets = {
local root = titlebar:get_children_by_id("titlebar_root")[1] local root = titlebar:get_children_by_id("titlebar_root")[1]
root:set_bg(theme.titlebar_bg_focus) root:set_bg(theme.titlebar_bg_focus)
root:set_shape(function(cr,width,height) root:set_shape(function(cr,width,height)
return gears.shape.partially_rounded_rect(cr,width,height, return gears.shape.partially_rounded_rect(
cr,width,height,
true,true,false,false,6) end) true,true,false,false,6) end)
end, end,
onunfocus = function(titlebar) onunfocus = function(titlebar)
local root = titlebar:get_children_by_id("titlebar_root")[1] local root = titlebar:get_children_by_id("titlebar_root")[1]
root:set_bg(theme.titlebar_bg_normal) root:set_bg(theme.titlebar_bg_normal)
root:set_shape(function(cr,width,height) root:set_shape(function(cr,width,height)
return gears.shape.partially_rounded_rect(cr,width,height, return gears.shape.partially_rounded_rect(
cr,width,height,
true,true,false,false,6) end) true,true,false,false,6) end)
end, end,
bg_focus = "#00000000", bg_focus = "#00000000",

View File

@ -19,7 +19,7 @@ local function get_virtual_icon(data)
local count = 0 local count = 0
local cumulative = 0 local cumulative = 0
local name = "battery-" local name = "battery-"
for k,v in pairs(data) do for _,v in pairs(data) do
if type(v) == "number" then if type(v) == "number" then
cumulative = cumulative + v cumulative = cumulative + v
count = count + 1 count = count + 1
@ -77,7 +77,7 @@ return function(args)
-- make it possible to press the button and make it toggle the popup -- make it possible to press the button and make it toggle the popup
battery_widget:connect_signal("button::press",style.button.onpress) battery_widget:connect_signal("button::press",style.button.onpress)
battery_widget:connect_signal("button::release",style.button.onrelease) battery_widget:connect_signal("button::release",style.button.onrelease)
battery_widget:connect_signal("button::press",function(self,x,y,button) battery_widget:connect_signal("button::press",function(_,_,_,button)
if button == 1 then if button == 1 then
popup.visible = (not popup.visible) popup.visible = (not popup.visible)
if popup.visible then if popup.visible then
@ -154,7 +154,7 @@ return function(args)
timeout = args.power_polling or 2, timeout = args.power_polling or 2,
autostart = true, autostart = true,
callback = function() callback = function()
for k,v in pairs(power_devices) do for _,v in pairs(power_devices) do
local data,err = syscontrol.power_supply.read_attribs(v) local data,err = syscontrol.power_supply.read_attribs(v)
if data and data.type == "Mains" then if data and data.type == "Mains" then
local w = widget_map[data.name] local w = widget_map[data.name]
@ -184,7 +184,7 @@ return function(args)
-- {{{ Backlight -- {{{ Backlight
local backlight_devices = syscontrol.backlight.enumerate() local backlight_devices = syscontrol.backlight.enumerate()
local default_backlight_device local default_backlight_device
for k,v in pairs(backlight_devices) do for _,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({
@ -193,12 +193,18 @@ return function(args)
icon = beautiful["backlight-symbolic"], icon = beautiful["backlight-symbolic"],
title = "Backlight", title = "Backlight",
}), }),
(data.writable and t.checkbox({ (data.writable and t.center(
checked = true, t.checkbox({
checked = false,
id = "checkbox", id = "checkbox",
forced_height = style.article.icon_size, forced_height = style.article.icon_size,
forced_width = style.article.icon_size forced_width = style.article.icon_size
})), }),
{
width = style.checkbox.width,
height = style.checkbox.height
})
),
layout = wibox.layout.fixed.horizontal, layout = wibox.layout.fixed.horizontal,
spacing = style.base.spacing spacing = style.base.spacing
}, },
@ -234,7 +240,7 @@ return function(args)
if default_backlight_device then if default_backlight_device then
local check2 = widget_map[default_backlight_device.name] local check2 = widget_map[default_backlight_device.name]
:get_children_by_id("checkbox")[1] :get_children_by_id("checkbox")[1]
check2.checked = false check2.checked = true
end end
default_backlight_device = data default_backlight_device = data
end) end)
@ -247,7 +253,7 @@ return function(args)
timeout = args.backlight_polling or 2, timeout = args.backlight_polling or 2,
autostart = true, autostart = true,
callback = function() callback = function()
for k,v in pairs(backlight_devices) do for _,v in pairs(backlight_devices) do
local data,err = syscontrol.backlight.read_attribs(v) local data,err = syscontrol.backlight.read_attribs(v)
if data then if data then
local w = widget_map[data.name] local w = widget_map[data.name]

View File

@ -8,8 +8,6 @@
-- Additional client controls, hidden for cleaner UI in the submenu. -- Additional client controls, hidden for cleaner UI in the submenu.
local awmtk2 = require("awmtk2") local awmtk2 = require("awmtk2")
local wibox = require("wibox") local wibox = require("wibox")
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful") local beautiful = require("beautiful")
return function(args) return function(args)

View File

@ -13,7 +13,6 @@ local awmtk2 = require("awmtk2")
local fastyaml = require("parsers").fast_split_yaml local fastyaml = require("parsers").fast_split_yaml
local beautiful = require("beautiful") local beautiful = require("beautiful")
local ask = require("asckey") local ask = require("asckey")
local pactl_data = {}
local test_pactl = os.execute("pactl --version") local test_pactl = os.execute("pactl --version")
local result = test_pactl local result = test_pactl
@ -45,6 +44,7 @@ return function(args)
local widget = wibox.widget(t.container({ local widget = wibox.widget(t.container({
t.center({ t.center({
id = "client_volume_icon", id = "client_volume_icon",
resize = true,
widget = wibox.widget.imagebox widget = wibox.widget.imagebox
}), }),
t.textbox({ t.textbox({
@ -62,11 +62,7 @@ return function(args)
local icon = widget:get_children_by_id("client_volume_icon")[1] local icon = widget:get_children_by_id("client_volume_icon")[1]
local slider = widget:get_children_by_id("client_volume")[1] local slider = widget:get_children_by_id("client_volume")[1]
-- Local tracking value to prevent zero volume on start -- Local tracking value to prevent zero volume on start
local slider_touched = false local 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 -- Attach to focus change
client.connect_signal("update_volume",function(c) client.connect_signal("update_volume",function(c)
awful.spawn.easy_async("pactl list sink-inputs",function(stdout) awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
@ -109,22 +105,21 @@ return function(args)
-- Async lock to prevent callback interference -- Async lock to prevent callback interference
local volume_lock = false local volume_lock = false
-- Function to set client volume -- Function to set client volume
local function volume(volume) local function volume(value)
if volume_lock then return end if volume_lock then return end
volume_lock = true volume_lock = true
awful.spawn.easy_async("pactl list sink-inputs",function(stdout) awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
local pactl_data = fastyaml(stdout) local pactl_data = fastyaml(stdout)
local cl = {}
if not (client.focus and client.focus.pid) then if not (client.focus and client.focus.pid) then
volume_lock = false volume_lock = false
return return
end end
for k,v in pairs(pactl_data) do for _,v in pairs(pactl_data) do
if v:match("application.process.id = \""..tostring(client.focus.pid).."\"") then if v:match("application.process.id = \""..tostring(client.focus.pid).."\"") then
local sink_id = v:match("^%s*Sink Input #(%d+)") local sink_id = v:match("^%s*Sink Input #(%d+)")
if sink_id then if sink_id then
print(sink_id, volume) print(sink_id, value)
awful.spawn("pactl set-sink-input-volume "..tostring(sink_id).." "..tostring(volume).."%") awful.spawn("pactl set-sink-input-volume "..tostring(sink_id).." "..tostring(value).."%")
end end
end end
end end
@ -132,7 +127,7 @@ return function(args)
end) end)
end end
-- Attach change to slider -- Attach change to slider
slider:connect_signal("widget::redraw_needed",function(widget) slider:connect_signal("widget::redraw_needed",function()
if touched then if touched then
volume(slider.value) volume(slider.value)
update_timer:again() update_timer:again()

106
widgets/volume.lua Normal file
View File

@ -0,0 +1,106 @@
-- 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 pactl_found = test_pactl
if _VERSION:match("5.1") then
pactl_found = (test_pactl == 0)
end
local test_amixer = os.execute("amixer --version")
local amixer_found = test_amixer
if _VERSION:match("5.1") then
amixer_found = (test_amixer == 0)
end
if (not (amixer_found or pactl_found)) then
return
end
local try_launch = [[which pavucontrol && pavucontrol || which pulsemixer && ]]..global.terminal..[[ -e pulsemixer || which alsamixer && ]]..global.terminal..[[ -e alsamixer ]]
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("volume",
awmtk2.generic.oneline_widget, args.style)
local templates = awmtk2.create_template_lib("volume",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style)
local widget = wibox.widget({
t.button({
image = get_icon(0),
id = "volume_icon",
resize = true,
widget = wibox.widget.imagebox
}),
t.container({
t.slider({
minimum = 0,
maximum = 100,
id = "volume",
value = -1
}),
layout = wibox.layout.fixed.horizontal
},{
visible = false,
id = "slidercontainer"
}),
layout = wibox.layout.fixed.horizontal
})
local icon = widget:get_children_by_id("volume_icon")[1]
local slider = widget:get_children_by_id("volume")[1]
local container = widget:get_children_by_id("slidercontainer")[1]
-- Alsa master handle
args.device = args.device or "default"
gears.timer {
autostart = true,
timeout = 0.5,
call_now = true,
callback = function()
awful.spawn.easy_async_with_shell("amixer -D "..args.device.." sget Master",function(stdout)
local volume_percent = stdout:match("%[(%d+)%%%]")
volume_percent = tonumber(volume_percent)
if not volume_percent then
return
end
slider.value = volume_percent
icon.image = get_icon(volume_percent)
end)
end
}
slider:connect_signal("widget::redraw_needed",function()
awful.spawn("amixer -D "..args.device.." sset Master "..slider.value.."%")
icon.image = get_icon(slider.value)
end)
icon:connect_signal("button::press",function(self,lx,ly,button)
if button == 1 then
container.visible = not container.visible
end
if button == 2 then
awful.spawn.with_shell(args.mixer or try_launch)
end
end)
return widget
end