From 56c8e3439b43f819f7a73bd075737ce93d38e5ef Mon Sep 17 00:00:00 2001 From: Augusto Gunsch Date: Sun, 23 Jan 2022 21:41:44 -0300 Subject: [PATCH] Add cmus widget --- cmus-widget/README.md | 48 ++++++++++++++ cmus-widget/cmus-widget.png | Bin 0 -> 6959 bytes cmus-widget/cmus.lua | 127 ++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 cmus-widget/README.md create mode 100644 cmus-widget/cmus-widget.png create mode 100644 cmus-widget/cmus.lua diff --git a/cmus-widget/README.md b/cmus-widget/README.md new file mode 100644 index 0000000..c24d975 --- /dev/null +++ b/cmus-widget/README.md @@ -0,0 +1,48 @@ +# Cmus widget + +Cmus widget that shows the current playing track. + +![widget](cmus-widget.png) + +Left click toggles playback. + +## Installation + +Clone the repo under **~/.config/awesome/** and add widget in **rc.lua**: + +```lua +local cmus_widget = require('awesome-wm-widgets.cmus-widget.cmus') +... +s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + ... + -- default + cmus_widget(), + -- customized + cmus_widget{ + space = 5, + timeout = 5 + }, +``` + +### Shortcuts + +To improve responsiveness of the widget when playback is changed by a shortcut use corresponding methods of the widget: + +```lua +awful.key({ modkey, "Shift" }, "p", function () cmus_widget:play_pause() end, {description = "play/pause cmus", group = "custom"}), +``` + +## Customization + +It is possible to customize the widget by providing a table with all or some of the following config parameters: + +### Generic parameter + +| Name | Default | Description | +|---|---|---| +| `font` | `Play 9` | Font used for the track title | +| `path_to_icons` | `/usr/share/icons/Arc/actions/symbolic/` | Alternative path for the icons | +| `timeout`| `10` | Refresh cooldown | +| `space` | `3` | Space between icon and track title | diff --git a/cmus-widget/cmus-widget.png b/cmus-widget/cmus-widget.png new file mode 100644 index 0000000000000000000000000000000000000000..ba04401d86dc6c2528e90bd6a00e51328c68e9ba GIT binary patch literal 6959 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 literal 0 HcmV?d00001 diff --git a/cmus-widget/cmus.lua b/cmus-widget/cmus.lua new file mode 100644 index 0000000..51daa89 --- /dev/null +++ b/cmus-widget/cmus.lua @@ -0,0 +1,127 @@ +------------------------------------------------- +-- Cmus Widget for Awesome Window Manager +-- Show what's playing, play/pause, etc + +-- @author Augusto Gunsch +-- @copyright 2022 Augusto Gunsch +------------------------------------------------- + +local awful = require("awful") +local wibox = require("wibox") +local watch = require("awful.widget.watch") +local spawn = require("awful.spawn") +local naughty = require("naughty") + +local cmus_widget = {} + +local function show_warning(message) + naughty.notify{ + preset = naughty.config.presets.critical, + title = "Cmus Widget", + text = message} +end + +local function worker(user_args) + + local args = user_args or {} + local font = args.font or "Play 9" + + local path_to_icons = args.path_to_icons or "/usr/share/icons/Arc/actions/symbolic/" + local timeout = args.timeout or 10 + local space = args.space or 3 + + cmus_widget.widget = wibox.widget { + { + { + id = "playback_icon", + resize = false, + widget = wibox.widget.imagebox, + }, + layout = wibox.container.place + }, + { + id = "text", + font = font, + widget = wibox.widget.textbox + }, + layout = wibox.layout.fixed.horizontal, + update_icon = function(self, name) + self:get_children_by_id("playback_icon")[1]:set_image(path_to_icons .. name) + end, + set_title = function(self, title) + self:get_children_by_id("text")[1]:set_text(title) + end + } + + function update_widget(widget, stdout, _, _, code) + if code == 0 then + local cmus_info = {} + + for s in stdout:gmatch("[^\r\n]+") do + local key, val = string.match(s, "^tag (%a+) (.+)$") + + if key and val then + cmus_info[key] = val + else + local key, val = string.match(s, "^set (%a+) (.+)$") + + if key and val then + cmus_info[key] = val + else + local key, val = string.match(s, "^(%a+) (.+)$") + if key and val then + cmus_info[key] = val + end + end + end + end + + local title = cmus_info.title + + if not title and cmus_info.file then + title = cmus_info.file:gsub("%..-$", "") + title = title:gsub("^.+/", "") + end + + if title then + if cmus_info["status"] == "playing" then + widget:update_icon("media-playback-start-symbolic.svg") + elseif cmus_info["status"] == "paused" then + widget:update_icon("media-playback-pause-symbolic.svg") + else + widget:update_icon("media-playback-stop-symbolic.svg") + end + + widget:set_title(title) + widget.visible = true + else + widget.visible = false + widget.width = 0 + end + else + widget.visible = false + end + end + + function cmus_widget:play_pause() + spawn("cmus-remote -u") + spawn.easy_async("cmus-remote -Q", + function(stdout, _, _, code) + update_widget(cmus_widget.widget, stdout, _, _, code) + end) + end + + cmus_widget.widget:buttons( + awful.util.table.join( + awful.button({}, 1, function() cmus_widget:play_pause() end) + ) + ) + + watch("cmus-remote -Q", timeout, update_widget, cmus_widget.widget) + + return cmus_widget.widget +end + +return setmetatable(cmus_widget, { __call = function(_, ...) + return worker(...) +end })