-- -- Control playing music/media and sound volume -- Currently supports : -- - playerctl -- - Spotify -- -- -- DEBUG -- local inspect = require("debug/inspect") local awful = require("awful") local beautiful = require("beautiful") local gears = require("gears") local naughty = require("naughty") local wibox = require("wibox") local config = require("config") local hasPlayerctl = os.execute("playerctl -v") == true -- playerctl function sendToPlayerctl(command) os.execute("playerctl " .. command) end -- Spotify function sendToSpotify(command) awful.util.spawn_with_shell("dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player." .. command) end -- Volume control function getVolume() if isMuted() then return 0 end local handle = io.popen("amixer -D pulse sget Master | awk -F\"[][]\" '/%/ { print $2 }' | head -n 1", "r") local volume = string.gsub(handle:read("*a"), "[\n%%]+", "") / 100 handle:close() return volume end function isMuted() local handle = io.popen("amixer -D pulse sget Master | awk -F\"[][]\" '/[onf]{2,3}/ { print $4 }' | head -n -1", "r") local muted = string.gsub(handle:read("*a"), "[\n]+", "") == "off" handle:close() return muted end function getVolumeImage(volume) local path = beautiful.volume_osd_icon_3 if volume < 0.667 then path = beautiful.volume_osd_icon_2 end if volume < 0.334 then path = beautiful.volume_osd_icon_1 end if volume <= 0 then path = beautiful.volume_osd_icon_0 end return gears.color.recolor_image(path, beautiful.volume_osd_image_color) end local volumeWibox = wibox({ ontop = true, bg = beautiful.volume_osd_bg, border_width = beautiful.volume_osd_border_width, border_color = beautiful.volume_osd_border_color, shape = beautiful.volume_osd_shape, width = beautiful.volume_osd_width, height = beautiful.volume_osd_height, widget = wibox.widget { { { image = getVolumeImage(1), widget = wibox.widget.imagebox }, forced_height = beautiful.volume_osd_height - 42, left = 38, right = 16, top = 24, bottom = 16, widget = wibox.container.margin }, { max_value = 1, value = 0.33, shape = gears.shape.rounded_bar, bar_shape = gears.shape.rounded_bar, forced_height = 38, margins = 18, color = beautiful.volume_osd_progress_color, background_color = beautiful.volume_osd_progress_bg, border_color = beautiful.volume_osd_progress_border_color, border_width = beautiful.volume_osd_progress_border_width, widget = wibox.widget.progressbar }, margins = 8, widget = wibox.container.margin, layout = wibox.layout.align.vertical } }) local imagebox = volumeWibox.widget:get_children()[1]:get_children()[1] local progressbar = volumeWibox.widget:get_children()[2] local timer = nil -- {{{ Control local playPause = function() if hasPlayerctl then sendToPlayerctl("play-pause") else sendToSpotify("PlayPause") end end local nextTrack = function() if hasPlayerctl then sendToPlayerctl("next") else sendToSpotify("Next") end end local previousTrack = function() if hasPlayerctl then sendToPlayerctl("previous") else sendToSpotify("Previous") end end local displayVolume = function() -- Update screen local screen = awful.screen:focused() volumeWibox.screen = screen -- Position volumeWibox:geometry({ x = (screen.geometry.x + screen.geometry.width / 2 - beautiful.volume_osd_width / 2), y = (screen.geometry.y + screen.geometry.height / 2 - beautiful.volume_osd_height / 2) }) -- Get volume local volume = getVolume() -- Update values imagebox.image = getVolumeImage(volume) progressbar.value = volume -- Show volumeWibox.visible = true -- Schedule hide if timer ~= nil then timer:stop() end timer = gears.timer { timeout = config.volume_osd_timeout, callback = function() volumeWibox.visible = false timer:stop() timer = nil end } timer:start() end local raiseVolume = function() os.execute("amixer -D pulse set Master 5%+") displayVolume() end local lowerVolume = function() os.execute("amixer -D pulse set Master 5%-") displayVolume() end local toggleMute = function() local muted = isMuted() os.execute("amixer -D pulse set Master " .. (muted and 'on' or 'off')) displayVolume() end -- }}} function getKeys(config) return -- Volume control config.raiseVolume ~= nil and awful.key({}, config.raiseVolume, raiseVolume, { description = "Raise volume", group = "media control" }) or nil, config.lowerVolume ~= nil and awful.key({}, config.lowerVolume, lowerVolume, { description = "Lower volume", group = "media control" }) or nil, config.toggleMute ~= nil and awful.key({}, config.toggleMute, toggleMute, { description = "Toggle mute audio", group = "media control" }) or nil, -- Media control config.playPause ~= nil and awful.key({}, config.playPause, playPause, { description = "Toggle Play / Pause", group = "media control" }) or nil, config.nextTrack ~= nil and awful.key({}, config.nextTrack, nextTrack, { description = "Next track", group = "media control" }) or nil, config.previousTrack ~= nil and awful.key({}, config.previousTrack, previousTrack, { description = "Previous track", group = "media control" }) or nil end return { getKeys = getKeys, }