Fixed volume control on per-application basis
This commit is contained in:
parent
9d468be547
commit
022a6a116f
|
@ -49,53 +49,92 @@ awful.screen.connect_for_each_screen(function(s)
|
||||||
s.mytasklist = require("core.widgets.tasklist")(s)
|
s.mytasklist = require("core.widgets.tasklist")(s)
|
||||||
-- Create the wibox
|
-- Create the wibox
|
||||||
s.mywibox = awful.wibar({
|
s.mywibox = awful.wibar({
|
||||||
position = "bottom",
|
position = "top",
|
||||||
screen = s,
|
screen = s,
|
||||||
bg = beautiful.topbar_bg,
|
bg = beautiful.topbar_bg,
|
||||||
border_width = 1,
|
|
||||||
border_color = beautiful.bg_normal
|
|
||||||
})
|
})
|
||||||
-- Add screen lock
|
-- Add screen lock
|
||||||
require("widgets.lock")({screen = s, obscure = true})
|
require("widgets.lock")({screen = s, obscure = true})
|
||||||
|
require("widgets.unitybar")(s,{
|
||||||
|
top_widgets = {
|
||||||
|
require("widgets.polytasklist")({
|
||||||
|
vertical = true,
|
||||||
|
stretch = false,
|
||||||
|
--constraint = 180,
|
||||||
|
names = false,
|
||||||
|
margins = 5
|
||||||
|
})(s),
|
||||||
|
},
|
||||||
|
bottom_widgets = {
|
||||||
|
require("widgets.polylauncher")({vertical = true})
|
||||||
|
}
|
||||||
|
})
|
||||||
-- Add widgets to the wibox
|
-- Add widgets to the wibox
|
||||||
s.mywibox:setup {
|
s.mywibox:setup {
|
||||||
layout = wibox.layout.align.horizontal,
|
layout = wibox.layout.align.horizontal,
|
||||||
{ -- Left widgets
|
{ -- Left widgets
|
||||||
layout = wibox.layout.fixed.horizontal,
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
{
|
||||||
|
{
|
||||||
require("core.widgets.menu_launcher"),
|
require("core.widgets.menu_launcher"),
|
||||||
require("widgets.polylauncher")({vertical = false}),
|
widget = wibox.container.place,
|
||||||
|
halign = "center"
|
||||||
|
},
|
||||||
|
bg = "#26262633",
|
||||||
|
widget = wibox.container.background,
|
||||||
|
forced_width = require("beautiful.xresources").apply_dpi(61),
|
||||||
|
},
|
||||||
|
--require("widgets.polylauncher")({vertical = false}),
|
||||||
|
--s.mytaglist,
|
||||||
s.mypromptbox,
|
s.mypromptbox,
|
||||||
spacing = 3
|
spacing = 3
|
||||||
},
|
},
|
||||||
-- Middle widget
|
-- Middle widget
|
||||||
{
|
{
|
||||||
require("widgets.polytasklist")({
|
--[[require("widgets.polytasklist")({
|
||||||
|
vertical = false,
|
||||||
|
stretch = false,
|
||||||
constraint = 180,
|
constraint = 180,
|
||||||
names = true,
|
names = true,
|
||||||
margins = 5
|
margins = 5
|
||||||
})(s),
|
})(s),]]
|
||||||
layout = wibox.layout.fixed.horizontal
|
layout = wibox.layout.fixed.horizontal
|
||||||
},
|
},
|
||||||
{ -- Right widgets
|
{ -- Right widgets
|
||||||
layout = wibox.layout.fixed.horizontal,
|
layout = wibox.layout.fixed.horizontal,
|
||||||
awful.widget.keyboardlayout(),
|
awful.widget.keyboardlayout(),
|
||||||
require("widgets.drawer")({
|
|
||||||
wibox.widget.systray(),
|
|
||||||
vertical = false
|
|
||||||
}),
|
|
||||||
require("widgets.wallpapers")({
|
require("widgets.wallpapers")({
|
||||||
screen = s,
|
screen = s,
|
||||||
path = os.getenv("HOME").."/Pictures/Wallpapers/",
|
path = os.getenv("HOME").."/Pictures/Wallpapers/",
|
||||||
|
style = {
|
||||||
|
icon_bg_normal = beautiful.topbar_bg
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
require("widgets.mailbox")({
|
require("widgets.mailbox")({
|
||||||
screen = s,
|
screen = s,
|
||||||
|
style = {
|
||||||
|
rounding = 1,
|
||||||
|
icon_bg_normal = beautiful.topbar_bg
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
--wibox.widget.systray(),
|
--wibox.widget.systray(),
|
||||||
require("widgets.volume")({}),
|
require("widgets.volume")({
|
||||||
|
style = {
|
||||||
|
icon_bg_normal = beautiful.topbar_bg
|
||||||
|
}
|
||||||
|
}),
|
||||||
require("widgets.battery")({
|
require("widgets.battery")({
|
||||||
percentage = true,
|
percentage = true,
|
||||||
|
style = {
|
||||||
|
icon_bg_normal = beautiful.topbar_bg
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
wibox.widget.textclock(),
|
wibox.widget.textclock(),
|
||||||
|
require("widgets.username")({
|
||||||
|
style = {
|
||||||
|
icon_bg_normal = beautiful.topbar_bg
|
||||||
|
}
|
||||||
|
}),
|
||||||
s.mylayoutbox,
|
s.mylayoutbox,
|
||||||
spacing = 4
|
spacing = 4
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,47 +43,6 @@ awful.screen.connect_for_each_screen(function(s)
|
||||||
toggle_tags
|
toggle_tags
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
local controls_widget = wibox.widget {
|
|
||||||
forced_width = 72,
|
|
||||||
forced_height = 24,
|
|
||||||
layout = wibox.layout.fixed.horizontal,
|
|
||||||
}
|
|
||||||
-- To conserve memory we keep one menu at a time
|
|
||||||
local menu_widget = menu({
|
|
||||||
before = {
|
|
||||||
controls_widget
|
|
||||||
},
|
|
||||||
after = {
|
|
||||||
require("widgets.client-volume")({})
|
|
||||||
},
|
|
||||||
items = {
|
|
||||||
{ "Move to tag" ,
|
|
||||||
move_screentags
|
|
||||||
},
|
|
||||||
{ "Toggle on tag",
|
|
||||||
toggle_screentags
|
|
||||||
},
|
|
||||||
{ "Stop task",
|
|
||||||
function()
|
|
||||||
awful.spawn("kill "..tostring(c.pid))
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{ "Kill task",
|
|
||||||
function()
|
|
||||||
awful.spawn("kill -s KILL "..tostring(c.pid))
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{ "Debug info",
|
|
||||||
{
|
|
||||||
before = {
|
|
||||||
require("widgets.window-debug")()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vertical = true
|
|
||||||
})
|
|
||||||
|
|
||||||
return function(c)
|
return function(c)
|
||||||
local buttons = gears.table.join(
|
local buttons = gears.table.join(
|
||||||
awful.button({ }, 1, function()
|
awful.button({ }, 1, function()
|
||||||
|
@ -95,26 +54,35 @@ return function(c)
|
||||||
awful.mouse.client.resize(c)
|
awful.mouse.client.resize(c)
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
|
c.menu = menu({
|
||||||
|
before = {
|
||||||
|
{
|
||||||
|
awful.titlebar.widget.floatingbutton (c),
|
||||||
|
awful.titlebar.widget.stickybutton (c),
|
||||||
|
awful.titlebar.widget.ontopbutton (c),
|
||||||
|
forced_width = 72,
|
||||||
|
forced_height = 24,
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
items = {
|
||||||
|
{ "Move to tag" ,
|
||||||
|
move_screentags
|
||||||
|
},
|
||||||
|
{ "Toggle on tag",
|
||||||
|
toggle_screentags
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vertical = true
|
||||||
|
})
|
||||||
c.menu_button = awful.titlebar.widget.iconwidget(c)
|
c.menu_button = awful.titlebar.widget.iconwidget(c)
|
||||||
-- A little trick we do to conserve memory and cpu usage on regenerating
|
|
||||||
-- buttons is we pop up a menu in the location of the icon
|
|
||||||
-- and insert buttons into the controls widget layout.
|
|
||||||
c.hidden_floatingbutton = awful.titlebar.widget.floatingbutton(c)
|
|
||||||
c.hidden_stickybutton = awful.titlebar.widget.stickybutton(c)
|
|
||||||
c.hidden_ontopbutton = awful.titlebar.widget.ontopbutton(c)
|
|
||||||
c.menu_button:connect_signal("button::press", function()
|
c.menu_button:connect_signal("button::press", function()
|
||||||
menu_widget.toggle()
|
c.menu.toggle()
|
||||||
if controls_widget then
|
|
||||||
controls_widget:reset()
|
|
||||||
controls_widget:add(c.hidden_floatingbutton)
|
|
||||||
controls_widget:add(c.hidden_stickybutton)
|
|
||||||
controls_widget:add(c.hidden_ontopbutton)
|
|
||||||
end
|
|
||||||
c:emit_signal("request::activate", "titlebar", {raise = true})
|
c:emit_signal("request::activate", "titlebar", {raise = true})
|
||||||
end)
|
end)
|
||||||
c:connect_signal("unfocus",function()
|
c:connect_signal("unfocus",function()
|
||||||
if menu_widget.visible then
|
if c.menu.visible then
|
||||||
menu_widget.toggle(0,0)
|
c.menu.toggle(0,0)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
return awful.titlebar(c) : setup {
|
return awful.titlebar(c) : setup {
|
||||||
|
|
|
@ -5,7 +5,7 @@ global = {}
|
||||||
global.awesome_dir = os.getenv("HOME").."/.config/awesome/"
|
global.awesome_dir = os.getenv("HOME").."/.config/awesome/"
|
||||||
global.config_dir = os.getenv("HOME").."/.awesome/"
|
global.config_dir = os.getenv("HOME").."/.awesome/"
|
||||||
global.themes_dir = os.getenv("HOME").."/.config/awesome/themes/"
|
global.themes_dir = os.getenv("HOME").."/.config/awesome/themes/"
|
||||||
global.theme = global.awesome_dir .. "themes/carbon/theme.lua"
|
global.theme = global.awesome_dir .. "themes/unity/theme.lua"
|
||||||
global.terminal = "xterm"
|
global.terminal = "xterm"
|
||||||
global.editor = os.getenv("EDITOR") or "vim"
|
global.editor = os.getenv("EDITOR") or "vim"
|
||||||
global.editor_cmd = global.terminal .. " -e ".. global.editor
|
global.editor_cmd = global.terminal .. " -e ".. global.editor
|
||||||
|
|
|
@ -3,38 +3,38 @@ local gears = require("gears")
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
local awmtk = require("awmtk")
|
local awmtk = require("awmtk")
|
||||||
|
|
||||||
local get_app_volume = function(pid)
|
local get_pactl_data = function()
|
||||||
-- Read pactl data
|
-- Get pactl process data and convert it into a list
|
||||||
|
local pactl_processes = {}
|
||||||
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
|
table.insert(pactl_processes,test)
|
||||||
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")
|
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
|
||||||
end
|
end
|
||||||
|
table.insert(pactl_processes,pactl_data)
|
||||||
|
return pactl_processes
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_app_volume = function(pid)
|
||||||
|
for key,process in pairs(get_pactl_data()) do
|
||||||
|
-- Match app by pid
|
||||||
|
if process:match("application.process.id = \""..tostring(pid).."\"") then
|
||||||
|
return process:match("Volume: .-(%d?%d?%d)%%")
|
||||||
|
end
|
||||||
|
end
|
||||||
-- Return nil and an error if not found matching process
|
-- Return nil and an error if not found matching process
|
||||||
return nil, "Process doesn't play audio"
|
return nil, "Process doesn't play audio"
|
||||||
end
|
end
|
||||||
|
|
||||||
local set_app_volume = function(pid,percentage)
|
local set_app_volume = function(pid,percentage)
|
||||||
-- Read pactl data
|
for key,process in pairs(get_pactl_data()) do
|
||||||
local pactl_process = io.popen("pactl list sink-inputs","r")
|
if process:match("application.process.id = \""..tostring(pid).."\"") then
|
||||||
local pactl_data = pactl_process:read("*a")
|
local sink_input_id = process:match("Sink Input #(%d*)")
|
||||||
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).."%")
|
os.execute("pactl set-sink-input-volume "..sink_input_id.." "..tostring(percentage).."%")
|
||||||
end
|
end
|
||||||
pactl_data = pactl_data:gsub("^%w.-\n(%w)","%1")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ return function(args)
|
||||||
end)
|
end)
|
||||||
slider:connect_signal("widget::redraw_needed",function()
|
slider:connect_signal("widget::redraw_needed",function()
|
||||||
set_app_volume(client.focus.pid,slider.value)
|
set_app_volume(client.focus.pid,slider.value)
|
||||||
|
widget.children[1].image = get_icon(tonumber(slider.value))
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
warning_text.markup = "pactl is not available"
|
warning_text.markup = "pactl is not available"
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
local awful = require("awful")
|
|
||||||
local beautiful = require("beautiful")
|
|
||||||
local gears = require("gears")
|
|
||||||
local spawn = require("awful.spawn")
|
|
||||||
local wibox = require("wibox")
|
|
||||||
local awmtk = require("awmtk")
|
|
||||||
local thumbnailer = require("thumbnail")
|
|
||||||
local widget = {}
|
|
||||||
local function ls(path)
|
|
||||||
local ls_data = io.popen("ls -1 "..path)
|
|
||||||
local output = {}
|
|
||||||
if ls_data then
|
|
||||||
ls_data:read("*a"):gsub("[^\n]+",function(capt) table.insert(output,capt) end)
|
|
||||||
ls_data:close()
|
|
||||||
else
|
|
||||||
error("ls "..path.." failed.")
|
|
||||||
end
|
|
||||||
return output
|
|
||||||
end
|
|
||||||
|
|
||||||
local function worker(args)
|
|
||||||
local args = args or {}
|
|
||||||
assert(type(args["screen"]) ~= "nil","Screen not specified")
|
|
||||||
assert(type(args["path"]) ~= "nil","Path to wallpapers folder not specified")
|
|
||||||
--add an extra slash to path if there is none
|
|
||||||
if not args["path"]:match("/$") then
|
|
||||||
args["path"] = args["path"].."/"
|
|
||||||
end
|
|
||||||
--create local style
|
|
||||||
local style = awmtk.style(awmtk.defaults,args.style or {},"wallpapers_")
|
|
||||||
--set wallpaper
|
|
||||||
local handler = io.open(global.config_dir.."/.wallpaper","r")
|
|
||||||
if handler then
|
|
||||||
local wallpaper_path = handler:read("*a")
|
|
||||||
gears.wallpaper.maximized(wallpaper_path,args["screen"])
|
|
||||||
end
|
|
||||||
local function update_last_wallpaper(s)
|
|
||||||
local handler = io.open(global.config_dir.."/.wallpaper","w")
|
|
||||||
handler:write(s)
|
|
||||||
handler:close()
|
|
||||||
end
|
|
||||||
--read wallpapers from the wallpaper directory
|
|
||||||
local image_list = ls(args["path"])
|
|
||||||
for k,v in pairs(image_list) do
|
|
||||||
if not (v:match("%.jpg$") or v:match("%.png$")) then
|
|
||||||
image_list[k] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--generate thumbnails to save up memory
|
|
||||||
thumbnailer.generate(args["path"],args["path"]..".thumbnails",60)
|
|
||||||
--style variables
|
|
||||||
local button_bg = style.wallpapers_button_bg_focus
|
|
||||||
local function new_wallpaper_button(image,s)
|
|
||||||
local new_widget = style.button({
|
|
||||||
image = args["path"]..".thumbnails/"..image,
|
|
||||||
resize = true,
|
|
||||||
widget = wibox.widget.imagebox
|
|
||||||
},{
|
|
||||||
bg = button_bg,
|
|
||||||
forced_height = style.wallpapers_button_height or 60,
|
|
||||||
forced_width = style.wallpapers_button_width or 100
|
|
||||||
},{
|
|
||||||
function()
|
|
||||||
gears.wallpaper.maximized(args["path"]..image,s)
|
|
||||||
update_last_wallpaper(args["path"]..image)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
return new_widget
|
|
||||||
end
|
|
||||||
local copy_list = {
|
|
||||||
widget = wibox.layout.grid,
|
|
||||||
forced_num_cols = args.columns or 4,
|
|
||||||
homogeneous = true,
|
|
||||||
expand = true,
|
|
||||||
orientation = "vertical",
|
|
||||||
spacing = 5
|
|
||||||
}
|
|
||||||
for k,v in pairs(image_list) do
|
|
||||||
local new_widget = new_wallpaper_button(v,args["screen"])
|
|
||||||
table.insert(copy_list,new_widget)
|
|
||||||
end
|
|
||||||
local popup = awful.popup(style.container(
|
|
||||||
copy_list,
|
|
||||||
{
|
|
||||||
visible = false,
|
|
||||||
ontop = true
|
|
||||||
}
|
|
||||||
))
|
|
||||||
local clip_widget = style.icon({
|
|
||||||
image = style["wallpapers_icon"],
|
|
||||||
resize = true,
|
|
||||||
widget = wibox.widget.imagebox
|
|
||||||
},{},{
|
|
||||||
function()
|
|
||||||
if popup.visible then
|
|
||||||
--rows = nil
|
|
||||||
popup.visible = not popup.visible
|
|
||||||
else
|
|
||||||
--init_popup()
|
|
||||||
popup:move_next_to(mouse.current_widget_geometry)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
widget = clip_widget
|
|
||||||
return clip_widget
|
|
||||||
end
|
|
||||||
|
|
||||||
return setmetatable(widget, { __call = function(_, ...) return worker(...) end })
|
|
Loading…
Reference in New Issue