diff --git a/core/titlebar.lua b/core/titlebar.lua
index ed185f2..45662df 100644
--- a/core/titlebar.lua
+++ b/core/titlebar.lua
@@ -53,6 +53,9 @@ local menu_widget = menu({
before = {
controls_widget
},
+ after = {
+ require("widgets.client-volume")({})
+ },
items = {
{ "Move to tag" ,
move_screentags
diff --git a/themes/carbon/icons/warning.svg b/themes/carbon/icons/warning.svg
index 85ed7e4..3db37e7 100644
--- a/themes/carbon/icons/warning.svg
+++ b/themes/carbon/icons/warning.svg
@@ -6,7 +6,7 @@
height="48"
viewBox="0 0 12.7 12.7"
version="1.1"
- id="svg5"
+ id="svg837"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="warning.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@@ -14,7 +14,7 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
+ id="grid902" />
+ id="defs834">
+
-
+ id="mask-powermask-path-effect1796">
+
+
+
+
+
+
- !
+ d="M -0.70621928,-0.70618839 H 13.406219 V 13.40625 H -0.70621928 Z" />
+
+
+
+
@@ -98,23 +125,12 @@
inkscape:groupmode="layer"
id="layer1">
+ id="rect1016"
+ 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"
+ d="M 0.79374983,11.90625 6.3499999,0.79374983 11.90625,11.90625 Z"
+ sodipodi:nodetypes="cccc"
+ mask="url(#mask-powermask-path-effect2659)"
+ inkscape:path-effect="#path-effect2659"
+ inkscape:original-d="M 0.79374983,11.90625 6.3499999,0.79374983 11.90625,11.90625 Z" />
diff --git a/themes/icons.lua b/themes/icons.lua
index be002a3..f53c1a7 100644
--- a/themes/icons.lua
+++ b/themes/icons.lua
@@ -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_closed_icon = gears.color.recolor_image(beautiful.icon_dir.."drawer-closed.svg",beautiful.fg_normal)
-- Generic icons
+print(beautiful.icon_dir.."warning.svg")
beautiful.warning_icon = gears.color.recolor_image(beautiful.icon_dir.."warning.svg",beautiful.fg_normal)
diff --git a/widgets/client-volume.lua b/widgets/client-volume.lua
index 94c6b0c..23b655a 100644
--- a/widgets/client-volume.lua
+++ b/widgets/client-volume.lua
@@ -4,22 +4,37 @@ local wibox = require("wibox")
local awmtk = require("awmtk")
local get_app_volume = function(pid)
- -- If pactl is accessible
- if os.execute("pactl --version") then
- -- Generate pactl sink-inputs data
- local pactl_process = io.popen("pactl list sink-inputs","r")
- local pactl_data = pactl_process:read("*a")
- pactl_process:close()
- while pactl_data:match("^(%w.-\n)%w") do
- local test = pactl_data:match("^(%w.-\n)%w")
- if test:match("application.process.id = \""..tostring(pid).."\"") then
- return test:match("Volume: .-(%d?%d?%d%%)")
- end
- pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
+ -- 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")
+ -- Return volume
+ if test:match("application.process.id = \""..tostring(pid).."\"") then
+ return test:match("Volume: .-(%d?%d?%d)%%")
end
- return nil, "Process doesn't play audio"
- else
- return nil, "pactl command is not available"
+ pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
+ end
+ -- 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
@@ -27,11 +42,11 @@ return function(args)
local style = awmtk.style(awmtk.defaults, args.style or {},"client_volume_")
local device = args.device or "default"
local icons = args.icons or {
- high = style.client_volume_icon_high,
- medium = style.client_volume_icon_medium,
- low = style.client_volume_icon_low,
- muted = style.client_volume_icon_muted,
- warn = style.client_volume_warning_icon
+ high = style.volume_icon_high,
+ medium = style.volume_icon_medium,
+ low = style.volume_icon_low,
+ muted = style.volume_icon_muted,
+ warn = style.warning_icon
}
local function get_icon(percent)
if percent >= 66 then
@@ -44,82 +59,54 @@ return function(args)
return icons.muted
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
}
- 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,
- 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
+ if os.execute("pactl --version") then
+ client.connect_signal("focus",function(c)
+ local value,err = get_app_volume(c.pid)
+ if value then
+ slider.value = value
+ widget.children[2] = slider
+ widget.children[1].image = get_icon(tonumber(value))
+ else
+ warning_text.markup = err
+ widget.children[2] = warning_text
+ widget.children[1].image = icons.warn
end
- slider.value = volume_percent
end)
slider:connect_signal("widget::redraw_needed",function()
- awful.spawn(commands.set..v.." "..slider.value.."%")
+ set_app_volume(client.focus.pid,slider.value)
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
- 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
- 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
+ return widget
end