From 0bda31d9083a5e70d40c157a4d7d95eb53c471fe Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Thu, 8 Apr 2021 12:42:13 +0200 Subject: [PATCH] media_control.lua: make volume management fully async --- default_theme.lua | 1 + simple/media_control.lua | 348 ++++++++++++++++++++------------------- 2 files changed, 184 insertions(+), 165 deletions(-) diff --git a/default_theme.lua b/default_theme.lua index adcae79..5227958 100644 --- a/default_theme.lua +++ b/default_theme.lua @@ -187,6 +187,7 @@ theme.volume_osd_border_color = theme.border_normal theme.volume_osd_border_width = dpi(0) theme.volume_osd_progress_bg = theme.bg_minimize theme.volume_osd_progress_color = "#ffffff" +theme.volume_osd_progress_color_muted = "#555555" theme.volume_osd_progress_border_color = theme.volume_osd_border_color theme.volume_osd_progress_border_width = dpi(0) theme.volume_osd_image_color = "#ffffff" diff --git a/simple/media_control.lua b/simple/media_control.lua index 0bac4fc..26defef 100644 --- a/simple/media_control.lua +++ b/simple/media_control.lua @@ -23,109 +23,116 @@ local config = require("config") local hasPlayerctl = os.execute("playerctl -v") == true -- playerctl -function sendToPlayerctl(command) - os.execute("playerctl " .. command) +function sendToPlayerctl(command, callback) + callback = callback or function() + end + awful.spawn.easy_async("playerctl " .. command, callback) 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) +function sendToSpotify(command, callback) + callback = callback or function() + end + awful.spawn.easy_async_with_shell("dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player." .. command, callback) end -- Brightness control -function getBrightness() - local handle = io.popen("xbacklight -get") - local brightness = handle:read("*a") - handle:close() - return brightness +function getBrightness(callback) + callback = callback or function() + end + + awful.spawn.easy_async("xbacklight -get", function(stdout, stderr, reason, exit_code) + callback(stdout) + end) end -function increaseBrightness() - os.execute("xbacklight -inc 2") +function increaseBrightness(callback) + callback = callback or function() + end + awful.spawn.easy_async("xbacklight -inc 2", callback) end -function decreaseBrightness() - os.execute("xbacklight -dec 2") +function decreaseBrightness(callback) + callback = callback or function() + end + awful.spawn.easy_async("xbacklight -dec 2", callback) end -- Volume control -function getVolume() - if isMuted() then return 0 end - local handle = io.popen("amixer " .. config.audio.card .. " sget '" .. config.audio.device .. "' -M | awk -F\"[][]\" '/%/ { print $2 }' | head -n 1", "r") - local volume = string.gsub(handle:read("*a"), "[\n%%]+", "") / 100 - handle:close() - return volume +function isMuted(callback) + awful.spawn.easy_async_with_shell("amixer " .. config.audio.card .. " sget '" .. config.audio.device .. "' | egrep 'Playback.*?\\[o' | egrep -o '\\[o.+\\]'", function(stdout, stderr, reason, exit_code) + callback(string.match(string.gsub(stdout, "[\n]+", ""), "off")) + end) end -function isMuted() - local handle = io.popen("amixer " .. config.audio.card .. " sget '" .. config.audio.device .. "' | egrep 'Playback.*?\\[o' | egrep -o '\\[o.+\\]'", "r") - local muted = string.match(string.gsub(handle:read("*a"), "[\n]+", ""), "off") - handle:close() - return muted +function getVolume(callback) + awful.spawn.easy_async_with_shell("amixer " .. config.audio.card .. " sget '" .. config.audio.device .. "' -M | awk -F\"[][]\" '/%/ { print $2 }' | head -n 1", function(stdout, stderr, reason, exit_code) + callback(string.gsub(stdout, "[\n%%]+", "") / 100) + end) 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) + 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_bar_height + beautiful.volume_osd_padding * 3, - widget = wibox.widget { - { - { - image = getVolumeImage(1), - widget = wibox.widget.imagebox - }, - left = beautiful.volume_osd_padding, - right = beautiful.volume_osd_padding, - top = beautiful.volume_osd_padding, - bottom = 0, - widget = wibox.container.margin, - }, - { - { - { - max_value = 1, - value = 0.33, - shape = gears.shape.rounded_bar, - bar_shape = gears.shape.rounded_bar, - margins = beautiful.volume_osd_padding + 4, - 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 - }, - forced_width = 80, - forced_height = 80, - direction = "east", - layout = wibox.container.rotate, - }, - left = beautiful.volume_osd_padding, - right = beautiful.volume_osd_padding, - top = 0, - bottom = beautiful.volume_osd_padding, - widget = wibox.container.margin, - }, - layout = wibox.layout.align.vertical - }, + 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_bar_height + beautiful.volume_osd_padding * 3, + widget = wibox.widget { + { + { + image = getVolumeImage(1), + widget = wibox.widget.imagebox + }, + left = beautiful.volume_osd_padding, + right = beautiful.volume_osd_padding, + top = beautiful.volume_osd_padding, + bottom = 0, + widget = wibox.container.margin, + }, + { + { + { + max_value = 1, + value = 0.33, + shape = gears.shape.rounded_bar, + bar_shape = gears.shape.rounded_bar, + margins = beautiful.volume_osd_padding + 4, + 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 + }, + forced_width = 80, + forced_height = 80, + direction = "east", + layout = wibox.container.rotate, + }, + left = beautiful.volume_osd_padding, + right = beautiful.volume_osd_padding, + top = 0, + bottom = beautiful.volume_osd_padding, + widget = wibox.container.margin, + }, + layout = wibox.layout.align.vertical + }, }) local imagebox = volumeWibox.widget:get_children()[1]:get_children()[1] @@ -135,116 +142,127 @@ local timer = nil -- {{{ Control local playPause = function() - if hasPlayerctl then - sendToPlayerctl("play-pause") - else - sendToSpotify("PlayPause") - end + if hasPlayerctl then + sendToPlayerctl("play-pause") + else + sendToSpotify("PlayPause") + end end local nextTrack = function() - if hasPlayerctl then - sendToPlayerctl("next") - else - sendToSpotify("Next") - end + if hasPlayerctl then + sendToPlayerctl("next") + else + sendToSpotify("Next") + end end local previousTrack = function() - if hasPlayerctl then - sendToPlayerctl("previous") - else - sendToSpotify("Previous") - end + if hasPlayerctl then + sendToPlayerctl("previous") + else + sendToSpotify("Previous") + end end local displayVolume = function() - -- Update screen - local screen = awful.screen:focused() - volumeWibox.screen = screen + isMuted(function(muted) + getVolume(function(volume) + -- Update values + imagebox.image = getVolumeImage(muted and 0 or volume) + progressbar.value = volume + progressbar.color = muted and beautiful.volume_osd_progress_color_muted or beautiful.volume_osd_progress_color - -- Position - local position = beautiful.volume_osd_position(screen.geometry.width, screen.geometry.height, beautiful.volume_osd_width, beautiful.volume_osd_height) - volumeWibox:geometry({ - x = (screen.geometry.x + position[1]), - y = (screen.geometry.y + position[2]) - }) + if timer ~= nil and timer.started then + timer:again() + return + end - -- Get volume - local volume = getVolume() + -- Update screen + local screen = awful.screen:focused() + volumeWibox.screen = screen - -- Update values - imagebox.image = getVolumeImage(volume) - progressbar.value = volume + -- Position + local position = beautiful.volume_osd_position(screen.geometry.width, screen.geometry.height, beautiful.volume_osd_width, beautiful.volume_osd_height) + volumeWibox:geometry({ + x = (screen.geometry.x + position[1]), + y = (screen.geometry.y + position[2]) + }) - -- Show - volumeWibox.visible = true + -- 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() + -- 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) + end) end local raiseVolume = function() - os.execute("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' 5%+ -M") - displayVolume() + awful.spawn.easy_async("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' 5%+ -M", function(stdout, stderr, reason, exit_code) + displayVolume() + end) end local lowerVolume = function() - os.execute("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' 5%- -M") - displayVolume() + awful.spawn.easy_async("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' 5%- -M", function(stdout, stderr, reason, exit_code) + displayVolume() + end) end local toggleMute = function() - local muted = isMuted() - os.execute("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' " .. (muted and 'on' or 'off')) - displayVolume() + isMuted(function(muted) + awful.spawn.easy_async("amixer " .. config.audio.card .. " set '" .. config.audio.device .. "' " .. (muted and 'on' or 'off'), function(stdout, stderr, reason, exit_code) + displayVolume() + end) + end) end -- }}} function getKeys(keys) - if config.audio.card == 'disabled' then - return - -- Media control - hotkey.make(keys.playPause, playPause, - { description = "Toggle Play / Pause", group = "media control" }), - hotkey.make(keys.nextTrack, nextTrack, - { description = "Next track", group = "media control" }), - hotkey.make(keys.previousTrack, previousTrack, - { description = "Previous track", group = "media control" }) - end + if config.audio.card == 'disabled' then + return + -- Media control + hotkey.make(keys.playPause, playPause, + { description = "Toggle Play / Pause", group = "media control" }), + hotkey.make(keys.nextTrack, nextTrack, + { description = "Next track", group = "media control" }), + hotkey.make(keys.previousTrack, previousTrack, + { description = "Previous track", group = "media control" }) + end - return - -- Volume control - hotkey.make(keys.raiseVolume, raiseVolume, - { description = "Raise volume", group = "media control" }), - hotkey.make(keys.lowerVolume, lowerVolume, - { description = "Lower volume", group = "media control" }), - hotkey.make(keys.toggleMute, toggleMute, - { description = "Toggle mute audio", group = "media control" }), + return + -- Volume control + hotkey.make(keys.raiseVolume, raiseVolume, + { description = "Raise volume", group = "media control" }), + hotkey.make(keys.lowerVolume, lowerVolume, + { description = "Lower volume", group = "media control" }), + hotkey.make(keys.toggleMute, toggleMute, + { description = "Toggle mute audio", group = "media control" }), - -- Media control - hotkey.make(keys.playPause, playPause, - { description = "Toggle Play / Pause", group = "media control" }), - hotkey.make(keys.nextTrack, nextTrack, - { description = "Next track", group = "media control" }), - hotkey.make(keys.previousTrack, previousTrack, - { description = "Previous track", group = "media control" }), - - -- Backlight control - hotkey.make(keys.brightnessUp, increaseBrightness, - { description = "Increase screen backlight brightness", group = "media control"}), - hotkey.make(keys.brightnessDown, decreaseBrightness, - { description = "Decrease screen backlight brightness", group = "media control"}) + -- Media control + hotkey.make(keys.playPause, playPause, + { description = "Toggle Play / Pause", group = "media control" }), + hotkey.make(keys.nextTrack, nextTrack, + { description = "Next track", group = "media control" }), + hotkey.make(keys.previousTrack, previousTrack, + { description = "Previous track", group = "media control" }), + + -- Backlight control + hotkey.make(keys.brightnessUp, increaseBrightness, + { description = "Increase screen backlight brightness", group = "media control" }), + hotkey.make(keys.brightnessDown, decreaseBrightness, + { description = "Decrease screen backlight brightness", group = "media control" }) end return { - getKeys = getKeys, -} \ No newline at end of file + getKeys = getKeys, +}