Added the volume bars to window context menu
This commit is contained in:
parent
19f95b77c8
commit
e6e79af052
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
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
|
<path
|
||||||
id="mask-powermask-path-effect28575_box"
|
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 |
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
local pactl_process = io.popen("pactl list sink-inputs","r")
|
||||||
-- Generate pactl sink-inputs data
|
local pactl_data = pactl_process:read("*a")
|
||||||
local pactl_process = io.popen("pactl list sink-inputs","r")
|
pactl_process:close()
|
||||||
local pactl_data = pactl_process:read("*a")
|
-- Try to find a matching process
|
||||||
pactl_process:close()
|
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
|
|
||||||
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
|
|
||||||
end
|
end
|
||||||
return nil, "Process doesn't play audio"
|
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
|
||||||
else
|
end
|
||||||
return nil, "pactl command is not available"
|
-- Return nil and an error if not found matching process
|
||||||
|
return nil, "Process doesn't play audio"
|
||||||
|
end
|
||||||
|
|
||||||
|
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 {
|
||||||
|
widget = wibox.widget.slider,
|
||||||
|
id = "widget_slider",
|
||||||
|
handle_width = style.client_volume_handle_width or 6,
|
||||||
|
bar_height = style.client_volumer_bar_width or 5,
|
||||||
|
bar_color = style.client_volume_bar_color or "#55CC60",
|
||||||
|
bar_shape = style.bar_shape,
|
||||||
|
handler_shape = style.handle_shape,
|
||||||
|
forced_height = 20,
|
||||||
|
forced_width = 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
|
||||||
|
},
|
||||||
|
warning_text,
|
||||||
|
spacing = style.client_volume_container_spacing_horizontal,
|
||||||
layout = wibox.layout.fixed.horizontal
|
layout = wibox.layout.fixed.horizontal
|
||||||
}
|
}
|
||||||
for k,v in pairs(controls) do
|
if os.execute("pactl --version") then
|
||||||
local widget = wibox.widget({
|
client.connect_signal("focus",function(c)
|
||||||
{
|
local value,err = get_app_volume(c.pid)
|
||||||
widget = wibox.widget.textbox,
|
if value then
|
||||||
markup = v,
|
slider.value = value
|
||||||
ellipsize = "end",
|
widget.children[2] = slider
|
||||||
font = style.volume_font
|
widget.children[1].image = get_icon(tonumber(value))
|
||||||
},
|
else
|
||||||
{
|
warning_text.markup = err
|
||||||
{
|
widget.children[2] = warning_text
|
||||||
widget = wibox.widget.slider,
|
widget.children[1].image = icons.warn
|
||||||
id = "widget_slider",
|
|
||||||
handle_width = style.volume_handle_width or 6,
|
|
||||||
bar_height = style.volumer_bar_width or 5,
|
|
||||||
bar_color = style.volume_bar_color or "#55CC60",
|
|
||||||
bar_shape = style.bar_shape,
|
|
||||||
handler_shape = style.handle_shape,
|
|
||||||
value = 100,
|
|
||||||
},
|
|
||||||
widget = wibox.container.rotate,
|
|
||||||
direction = "east"
|
|
||||||
},
|
|
||||||
layout = wibox.layout.fixed.vertical,
|
|
||||||
spacing = style.volume_container_spacing_horizontal,
|
|
||||||
forced_width = style.volume_slider_width or 40,
|
|
||||||
forced_height = style.volume_slider_height or 120
|
|
||||||
})
|
|
||||||
local slider = widget:get_children_by_id("widget_slider")[1]
|
|
||||||
awful.spawn.easy_async_with_shell(commands.get..v,function(out)
|
|
||||||
local volume_percent = out:match("%[(%d+)%%%]") or ""
|
|
||||||
volume_percent = tonumber(volume_percent)
|
|
||||||
if not volume_percent then
|
|
||||||
return
|
|
||||||
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)
|
else
|
||||||
|
warning_text.markup = "pactl is not available"
|
||||||
|
widget.children[2] = warning_text
|
||||||
|
widget.children[1].image = icons.warn
|
||||||
end
|
end
|
||||||
local tweaker_popup = awful.popup(style.container(list,{
|
return widget
|
||||||
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
|
|
||||||
tweaker_popup.visible = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue