Added the volume bars to window context menu

This commit is contained in:
Yessiest 2022-03-22 23:33:06 +04:00
parent 19f95b77c8
commit e6e79af052
4 changed files with 148 additions and 141 deletions

View File

@ -53,6 +53,9 @@ local menu_widget = menu({
before = { before = {
controls_widget controls_widget
}, },
after = {
require("widgets.client-volume")({})
},
items = { items = {
{ "Move to tag" , { "Move to tag" ,
move_screentags move_screentags

View File

@ -6,7 +6,7 @@
height="48" height="48"
viewBox="0 0 12.7 12.7" viewBox="0 0 12.7 12.7"
version="1.1" version="1.1"
id="svg5" id="svg837"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="warning.svg" sodipodi:docname="warning.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@ -14,7 +14,7 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"> xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview <sodipodi:namedview
id="namedview7" id="namedview839"
pagecolor="#ffffff" pagecolor="#ffffff"
bordercolor="#666666" bordercolor="#666666"
borderopacity="1.0" borderopacity="1.0"
@ -25,8 +25,8 @@
showgrid="true" showgrid="true"
units="px" units="px"
inkscape:zoom="12.429181" inkscape:zoom="12.429181"
inkscape:cx="32.021419" inkscape:cx="22.205807"
inkscape:cy="23.171278" inkscape:cy="27.113613"
inkscape:window-width="1866" inkscape:window-width="1866"
inkscape:window-height="1038" inkscape:window-height="1038"
inkscape:window-x="52" inkscape:window-x="52"
@ -35,60 +35,87 @@
inkscape:current-layer="layer1"> inkscape:current-layer="layer1">
<inkscape:grid <inkscape:grid
type="xygrid" type="xygrid"
id="grid1562" /> id="grid902" />
</sodipodi:namedview> </sodipodi:namedview>
<defs <defs
id="defs2"> id="defs834">
<inkscape:path-effect <inkscape:path-effect
effect="powermask" effect="powermask"
id="path-effect28575" id="path-effect2659"
is_visible="true" is_visible="true"
lpeversion="1" lpeversion="1"
uri="#mask-powermask-path-effect28575" uri="#mask-powermask-path-effect2659"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect1796"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect1796"
invert="false" invert="false"
hide_mask="false" hide_mask="false"
background="true" background="true"
background_color="#ffffffff" /> background_color="#ffffffff" />
<rect
x="20"
y="23"
width="28"
height="29"
id="rect5107" />
<mask <mask
maskUnits="userSpaceOnUse" maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect28575"> id="mask-powermask-path-effect1796">
<g
id="g1794"
transform="matrix(3.1496063,0,0,3.1496063,2.9999997,6.2500913)"
style="">
<path <path
id="mask-powermask-path-effect28575_box" style="fill:none;stroke:#000000;stroke-width:0.972208;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 6.35,3.175 V 8.4666665"
id="path1790" />
<circle
style="opacity:1;fill:#000000;stroke:none;stroke-width:1.065;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="circle1792"
cx="6.3499999"
cy="10.054167"
r="0.52916664" />
</g>
</mask>
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2659">
<path
id="mask-powermask-path-effect2659_box"
style="fill:#ffffff;fill-opacity:1" style="fill:#ffffff;fill-opacity:1"
d="M 1.1424707,-3.0728638 H 48.857529 V 39.073072 H 1.1424707 Z" /> d="M -0.70621928,-0.70618839 H 13.406219 V 13.40625 H -0.70621928 Z" />
<text <g
xml:space="preserve" id="g2657"
style="font-size:42.6667px;line-height:1.25;font-family:sans-serif;stroke-width:0.999999" style="">
x="19.083326" <path
y="32.677097" style="fill:none;stroke:#000000;stroke-width:0.934071;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="text28573"><tspan d="M 6.3499999,3.175 V 8.4666667"
sodipodi:role="line" id="path2653" />
id="tspan28571" <circle
style="font-size:42.6667px;stroke-width:0.999999" style="opacity:1;fill:#000000;stroke:none;stroke-width:1.065;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
x="19.083326" id="circle2655"
y="32.677097">!</tspan></text> cx="6.3499999"
cy="10.163688"
r="0.52916664"
d="M 6.8791665,10.163688 A 0.52916664,0.52916664 0 0 1 6.3499999,10.692854 0.52916664,0.52916664 0 0 1 5.8208333,10.163688 0.52916664,0.52916664 0 0 1 6.3499999,9.6345211 0.52916664,0.52916664 0 0 1 6.8791665,10.163688 Z" />
</g>
</mask> </mask>
<filter <filter
id="mask-powermask-path-effect28575_inverse" id="mask-powermask-path-effect2659_inverse"
inkscape:label="filtermask-powermask-path-effect28575" inkscape:label="filtermask-powermask-path-effect2659"
style="color-interpolation-filters:sRGB" style="color-interpolation-filters:sRGB"
height="100" height="100"
width="100" width="100"
x="-50" x="-50"
y="-50"> y="-50">
<feColorMatrix <feColorMatrix
id="mask-powermask-path-effect28575_primitive1" id="mask-powermask-path-effect2659_primitive1"
values="1" values="1"
type="saturate" type="saturate"
result="fbSourceGraphic" /> result="fbSourceGraphic" />
<feColorMatrix <feColorMatrix
id="mask-powermask-path-effect28575_primitive2" id="mask-powermask-path-effect2659_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 " values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /> in="fbSourceGraphic" />
</filter> </filter>
@ -98,23 +125,12 @@
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer1"> id="layer1">
<path <path
sodipodi:type="star" id="rect1016"
style="fill:#000000;stroke-width:4.14614178;stroke-linecap:round;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4.0999999;stroke-dasharray:none;paint-order:stroke fill markers;stroke-linejoin:round" style="stroke-width:1;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;opacity:1"
id="path1855" d="M 0.79374983,11.90625 6.3499999,0.79374983 11.90625,11.90625 Z"
inkscape:flatsided="true" sodipodi:nodetypes="cccc"
sodipodi:sides="3" mask="url(#mask-powermask-path-effect2659)"
sodipodi:cx="25" inkscape:path-effect="#path-effect2659"
sodipodi:cy="24" inkscape:original-d="M 0.79374983,11.90625 6.3499999,0.79374983 11.90625,11.90625 Z" />
sodipodi:r1="24"
sodipodi:r2="12"
sodipodi:arg1="-1.5707963"
sodipodi:arg2="-0.52359878"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 25.000001,0 20.784608,36.000001 -41.569219,-2e-6 z"
transform="matrix(0.26458333,0,0,0.26458333,-0.26458316,1.5875)"
inkscape:transform-center-y="-1.5875001"
mask="url(#mask-powermask-path-effect28575)"
inkscape:path-effect="#path-effect28575" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -50,5 +50,6 @@ beautiful.username_logout_icon = gears.color.recolor_image(beautiful.icon_dir.."
beautiful.drawer_open_icon = gears.color.recolor_image(beautiful.icon_dir.."drawer-open.svg",beautiful.fg_normal) beautiful.drawer_open_icon = gears.color.recolor_image(beautiful.icon_dir.."drawer-open.svg",beautiful.fg_normal)
beautiful.drawer_closed_icon = gears.color.recolor_image(beautiful.icon_dir.."drawer-closed.svg",beautiful.fg_normal) beautiful.drawer_closed_icon = gears.color.recolor_image(beautiful.icon_dir.."drawer-closed.svg",beautiful.fg_normal)
-- Generic icons -- Generic icons
print(beautiful.icon_dir.."warning.svg")
beautiful.warning_icon = gears.color.recolor_image(beautiful.icon_dir.."warning.svg",beautiful.fg_normal) beautiful.warning_icon = gears.color.recolor_image(beautiful.icon_dir.."warning.svg",beautiful.fg_normal)

View File

@ -4,22 +4,37 @@ local wibox = require("wibox")
local awmtk = require("awmtk") local awmtk = require("awmtk")
local get_app_volume = function(pid) local get_app_volume = function(pid)
-- If pactl is accessible -- Read pactl data
if os.execute("pactl --version") then
-- Generate pactl sink-inputs data
local pactl_process = io.popen("pactl list sink-inputs","r") local pactl_process = io.popen("pactl list sink-inputs","r")
local pactl_data = pactl_process:read("*a") local pactl_data = pactl_process:read("*a")
pactl_process:close() pactl_process:close()
-- Try to find a matching process
while pactl_data:match("^(%w.-\n)%w") do while pactl_data:match("^(%w.-\n)%w") do
local test = pactl_data:match("^(%w.-\n)%w") local test = pactl_data:match("^(%w.-\n)%w")
-- Return volume
if test:match("application.process.id = \""..tostring(pid).."\"") then if test:match("application.process.id = \""..tostring(pid).."\"") then
return test:match("Volume: .-(%d?%d?%d%%)") return test:match("Volume: .-(%d?%d?%d)%%")
end end
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1") pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
end end
-- Return nil and an error if not found matching process
return nil, "Process doesn't play audio" return nil, "Process doesn't play audio"
else end
return nil, "pactl command is not available"
local set_app_volume = function(pid,percentage)
-- Read pactl data
local pactl_process = io.popen("pactl list sink-inputs","r")
local pactl_data = pactl_process:read("*a")
pactl_process:close()
-- Try to find a matching process
while pactl_data:match("^(%w.-\n)%w") do
local test = pactl_data:match("^(%w.-\n)%w")
-- If the application matches, get stream ID and set its volume
if test:match("application.process.id = \""..tostring(pid).."\"") then
local sink_input_id = test:match("Sink Input #(%d*)")
os.execute("pactl set-sink-input-volume "..sink_input_id.." "..tostring(percentage).."%")
end
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
end end
end end
@ -27,11 +42,11 @@ return function(args)
local style = awmtk.style(awmtk.defaults, args.style or {},"client_volume_") local style = awmtk.style(awmtk.defaults, args.style or {},"client_volume_")
local device = args.device or "default" local device = args.device or "default"
local icons = args.icons or { local icons = args.icons or {
high = style.client_volume_icon_high, high = style.volume_icon_high,
medium = style.client_volume_icon_medium, medium = style.volume_icon_medium,
low = style.client_volume_icon_low, low = style.volume_icon_low,
muted = style.client_volume_icon_muted, muted = style.volume_icon_muted,
warn = style.client_volume_warning_icon warn = style.warning_icon
} }
local function get_icon(percent) local function get_icon(percent)
if percent >= 66 then if percent >= 66 then
@ -44,82 +59,54 @@ return function(args)
return icons.muted return icons.muted
end end
end end
local list = { local slider = wibox.widget {
layout = wibox.layout.fixed.horizontal
}
for k,v in pairs(controls) do
local widget = wibox.widget({
{
widget = wibox.widget.textbox,
markup = v,
ellipsize = "end",
font = style.volume_font
},
{
{
widget = wibox.widget.slider, widget = wibox.widget.slider,
id = "widget_slider", id = "widget_slider",
handle_width = style.volume_handle_width or 6, handle_width = style.client_volume_handle_width or 6,
bar_height = style.volumer_bar_width or 5, bar_height = style.client_volumer_bar_width or 5,
bar_color = style.volume_bar_color or "#55CC60", bar_color = style.client_volume_bar_color or "#55CC60",
bar_shape = style.bar_shape, bar_shape = style.bar_shape,
handler_shape = style.handle_shape, handler_shape = style.handle_shape,
forced_height = 20,
forced_width = 100,
value = 100, value = 100,
}
local warning_text = wibox.widget {
markup = "An unknown error has occured",
widget = wibox.widget.textbox
}
local widget = wibox.widget {
{
image = icons.warn,
resize = true,
widget = wibox.widget.imagebox,
forced_height = 20,
forced_width = 20
}, },
widget = wibox.container.rotate, warning_text,
direction = "east" spacing = style.client_volume_container_spacing_horizontal,
}, layout = wibox.layout.fixed.horizontal
layout = wibox.layout.fixed.vertical, }
spacing = style.volume_container_spacing_horizontal, if os.execute("pactl --version") then
forced_width = style.volume_slider_width or 40, client.connect_signal("focus",function(c)
forced_height = style.volume_slider_height or 120 local value,err = get_app_volume(c.pid)
}) if value then
local slider = widget:get_children_by_id("widget_slider")[1] slider.value = value
awful.spawn.easy_async_with_shell(commands.get..v,function(out) widget.children[2] = slider
local volume_percent = out:match("%[(%d+)%%%]") or "" widget.children[1].image = get_icon(tonumber(value))
volume_percent = tonumber(volume_percent) else
if not volume_percent then warning_text.markup = err
return widget.children[2] = warning_text
widget.children[1].image = icons.warn
end end
slider.value = volume_percent
end) end)
slider:connect_signal("widget::redraw_needed",function() slider:connect_signal("widget::redraw_needed",function()
awful.spawn(commands.set..v.." "..slider.value.."%") set_app_volume(client.focus.pid,slider.value)
end) end)
table.insert(list,widget)
end
local tweaker_popup = awful.popup(style.container(list,{
visible = false,
ontop = true
}))
local icon = style.icon({
widget = wibox.widget.imagebox,
image = icons.muted,
id = "widget_icon"
},{},{
function()
if mouse.current_widget_geometry and (not tweaker_popup.visible) then
tweaker_popup:move_next_to(mouse.current_widget_geometry)
tweaker_popup.visible = true
else else
tweaker_popup.visible = false warning_text.markup = "pactl is not available"
widget.children[2] = warning_text
widget.children[1].image = icons.warn
end end
end return widget
})
gears.timer {
autostart = true,
timeout = 0.5,
call_now = true,
callback = function()
awful.spawn.easy_async_with_shell(commands.get_master, function(out)
local volume_percent = out:match("%[(%d+)%%%]") or ""
volume_percent = tonumber(volume_percent)
if not volume_percent then
return
end
icon:get_children_by_id("widget_icon")[1].image = get_icon(volume_percent)
end)
end
}
return icon
end end