mirror of
https://github.com/streetturtle/awesome-wm-widgets.git
synced 2024-11-17 07:49:09 +01:00
4bc22fbb70
this code is janky, because the notification is set asynchronously, it can end up not being cleaned by the mouse exit and then you can end up with multiple ones. Also, the image field of the table needs to be icon, but if the icon is an http url like some players print or even a local file like firefox does, setting the icon causes an error as it can't be read.
187 lines
6.2 KiB
Lua
187 lines
6.2 KiB
Lua
-------------------------------------------------
|
|
-- mpris based Arc Widget for Awesome Window Manager
|
|
-- Modelled after Pavel Makhov's work
|
|
-- @author Mohammed Gaber
|
|
-- requires - playerctl
|
|
-- @copyright 2020
|
|
-------------------------------------------------
|
|
local awful = require("awful")
|
|
local beautiful = require("beautiful")
|
|
local watch = require("awful.widget.watch")
|
|
local wibox = require("wibox")
|
|
local gears = require("gears")
|
|
|
|
local GET_MPD_CMD = "playerctl -p %s -f '{{status}};{{xesam:artist}};{{xesam:title}}' metadata"
|
|
|
|
local TOGGLE_MPD_CMD = "playerctl play-pause"
|
|
local NEXT_MPD_CMD = "playerctl next"
|
|
local PREV_MPD_CMD = "playerctl previous"
|
|
local LIST_PLAYERS_CMD = "playerctl -l"
|
|
|
|
local PATH_TO_ICONS = "/usr/share/icons/Arc"
|
|
local PAUSE_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_pause.png"
|
|
local PLAY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_play.png"
|
|
local STOP_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_stop.png"
|
|
local LIBRARY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/music-library.png"
|
|
|
|
local default_player = ''
|
|
|
|
local icon = wibox.widget {
|
|
id = "icon",
|
|
widget = wibox.widget.imagebox,
|
|
image = PLAY_ICON_NAME
|
|
}
|
|
|
|
local mpris_widget = wibox.widget{
|
|
{
|
|
id = 'artist',
|
|
widget = wibox.widget.textbox
|
|
},
|
|
{
|
|
icon,
|
|
max_value = 1,
|
|
value = 0,
|
|
thickness = 2,
|
|
start_angle = 4.71238898, -- 2pi*3/4
|
|
forced_height = 24,
|
|
forced_width = 24,
|
|
rounded_edge = true,
|
|
bg = "#ffffff11",
|
|
paddings = 0,
|
|
widget = wibox.container.arcchart
|
|
},
|
|
{
|
|
id = 'title',
|
|
widget = wibox.widget.textbox
|
|
},
|
|
layout = wibox.layout.fixed.horizontal,
|
|
set_text = function(self, artist, title)
|
|
self:get_children_by_id('artist')[1]:set_text(artist)
|
|
self:get_children_by_id('title')[1]:set_text(title)
|
|
end
|
|
}
|
|
|
|
local rows = { layout = wibox.layout.fixed.vertical }
|
|
|
|
local popup = awful.popup{
|
|
bg = beautiful.bg_normal,
|
|
ontop = true,
|
|
visible = false,
|
|
shape = gears.shape.rounded_rect,
|
|
border_width = 1,
|
|
border_color = beautiful.bg_focus,
|
|
maximum_width = 400,
|
|
offset = { y = 5 },
|
|
widget = {}
|
|
}
|
|
|
|
local function rebuild_popup()
|
|
awful.spawn.easy_async(LIST_PLAYERS_CMD, function(stdout, _, _, _)
|
|
for i = 0, #rows do rows[i]=nil end
|
|
for player_name in stdout:gmatch("[^\r\n]+") do
|
|
if player_name ~='' and player_name ~=nil then
|
|
|
|
local checkbox = wibox.widget{
|
|
{
|
|
checked = player_name == default_player,
|
|
color = beautiful.bg_normal,
|
|
paddings = 2,
|
|
shape = gears.shape.circle,
|
|
forced_width = 20,
|
|
forced_height = 20,
|
|
check_color = beautiful.fg_urgent,
|
|
widget = wibox.widget.checkbox
|
|
},
|
|
valign = 'center',
|
|
layout = wibox.container.place,
|
|
}
|
|
|
|
checkbox:connect_signal("button::press", function()
|
|
default_player = player_name
|
|
rebuild_popup()
|
|
end)
|
|
|
|
table.insert(rows, wibox.widget {
|
|
{
|
|
{
|
|
checkbox,
|
|
{
|
|
{
|
|
text = player_name,
|
|
align = 'left',
|
|
widget = wibox.widget.textbox
|
|
},
|
|
left = 10,
|
|
layout = wibox.container.margin
|
|
},
|
|
spacing = 8,
|
|
layout = wibox.layout.align.horizontal
|
|
},
|
|
margins = 4,
|
|
layout = wibox.container.margin
|
|
},
|
|
bg = beautiful.bg_normal,
|
|
widget = wibox.container.background
|
|
})
|
|
end
|
|
end
|
|
end)
|
|
|
|
popup:setup(rows)
|
|
end
|
|
|
|
local function worker()
|
|
|
|
-- retrieve song info
|
|
local current_song, artist, player_status
|
|
|
|
local update_graphic = function(widget, stdout, _, _, _)
|
|
local words = gears.string.split(stdout, ';')
|
|
player_status = words[1]
|
|
artist = words[2]
|
|
current_song = words[3]
|
|
if current_song ~= nil then
|
|
if string.len(current_song) > 18 then
|
|
current_song = string.sub(current_song, 0, 9) .. ".."
|
|
end
|
|
end
|
|
|
|
if player_status == "Playing" then
|
|
icon.image = PLAY_ICON_NAME
|
|
widget.colors = {beautiful.widget_main_color}
|
|
widget:set_text(artist, current_song)
|
|
elseif player_status == "Paused" then
|
|
icon.image = PAUSE_ICON_NAME
|
|
widget.colors = {beautiful.widget_main_color}
|
|
widget:set_text(artist, current_song)
|
|
elseif player_status == "Stopped" then
|
|
icon.image = STOP_ICON_NAME
|
|
else -- no player is running
|
|
icon.image = LIBRARY_ICON_NAME
|
|
widget.colors = {beautiful.widget_red}
|
|
end
|
|
end
|
|
|
|
mpris_widget:buttons(
|
|
awful.util.table.join(
|
|
awful.button({}, 3, function()
|
|
if popup.visible then
|
|
popup.visible = not popup.visible
|
|
else
|
|
rebuild_popup()
|
|
popup:move_next_to(mouse.current_widget_geometry)
|
|
end
|
|
end),
|
|
awful.button({}, 4, function() awful.spawn(NEXT_MPD_CMD, false) end),
|
|
awful.button({}, 5, function() awful.spawn(PREV_MPD_CMD, false) end),
|
|
awful.button({}, 1, function() awful.spawn(TOGGLE_MPD_CMD, false) end)
|
|
)
|
|
)
|
|
|
|
watch(string.format(GET_MPD_CMD, "'" .. default_player .. "'"), 1, update_graphic, mpris_widget)
|
|
|
|
return mpris_widget
|
|
|
|
end
|
|
|
|
return setmetatable(mpris_widget, {__call = function(_, ...) return worker(...) end})
|