Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua

Introduction

Hey there everybody !! Before starting, i want to say that this is my first online post, i am writing in my entire life. So please do bear with my silly mistakes or anything wrong i will be writing in this post.

So now going with the flow ; i am an avid music lover and i like the whole idea of development and programming alongside listening to music.

It’s been a year since i migrated to linux ( Btw i use Arch Linux ), and i can’t stress enough, how much my productivity, speed and ease of doing things have increased since then.

My system runs a vanilla arch setup ( barebone arch architecture without any setup ) running Awesome Window Manager. So recently, i thought about making a music bar from scratch. Since Awesome WM is highly configurable and comes with a lot helper utilities, it was really easy to setup such a thing.


Structure 🧬

~/.config/awesome
|--daemon
|--init.lua
|--moe.lua
|--spotify.lua
|--mpd.lua
|--widget
|--moe.lua
|--spotify_song.lua
|--spotify_buttons.lua
|--mpd_song.lua
|--mpd_buttons.lua
|--musicbar.lua
|--helpers.lua
|--rc.lua
|--default.jpg
~/.config/awesome
|--daemon
   |--init.lua
   |--moe.lua
   |--spotify.lua
   |--mpd.lua
|--widget
   |--moe.lua
   |--spotify_song.lua
   |--spotify_buttons.lua
   |--mpd_song.lua
   |--mpd_buttons.lua
|--musicbar.lua
|--helpers.lua
|--rc.lua
|--default.jpg
~/.config/awesome |--daemon |--init.lua |--moe.lua |--spotify.lua |--mpd.lua |--widget |--moe.lua |--spotify_song.lua |--spotify_buttons.lua |--mpd_song.lua |--mpd_buttons.lua |--musicbar.lua |--helpers.lua |--rc.lua |--default.jpg

Enter fullscreen mode Exit fullscreen mode

  • daemons – contains the daemons or background process that provide us information about our subscribed events.

  • widget – contains the widgets that collectively make the musicbar widget.

  • musicbar.lua – the overall shell widget / parent widget that contains all other music widgets in widget directory.

  • helpers.lua – contains helper functions needed by many modules.

  • rc.lua – the main file that is executed by awesome on startup.

  • default.jpg – the default image to show if no cover image is available from listen.moe. Like this one :


Prerequisite

Necessary Fonts:

  • Material Design Iconsdropbox

Once you download them and unpack them, place them into ~/.fonts or ~/.local/share/fonts.

  • You will need to create the directory if it does not exist.
  • It does not matter that the actual font files (.ttf) are deep inside multiple directories. They will be detected as long as they can be accessed from ~/.fonts or ~/.local/share/fonts.

Finally, run the following in order for your system to detect the newly installed fonts.

fc-cache <span>-v</span>
   fc-cache <span>-v</span>
fc-cache -v

Enter fullscreen mode Exit fullscreen mode


Making some helper functions 🤝🤝

helpers.lua is a file which contains some functions that are going to be used frequently in this project codebase. These include colorizing text, connecting signals with a defined action, configuring shapes of widgets etc.

helpers.lua

<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>{}</span>
<span>helpers</span><span>.</span><span>colorize_text</span> <span>=</span> <span>function</span><span>(</span><span>text</span><span>,</span> <span>color</span><span>)</span>
<span>return</span> <span>"<span foreground='"</span><span>..</span><span>color</span><span>..</span><span>"'>"</span><span>..</span><span>text</span><span>..</span><span>"</span>"</span>
<span>end</span>
<span>helpers</span><span>.</span><span>prrect</span> <span>=</span> <span>function</span><span>(</span><span>radius</span><span>,</span> <span>tl</span><span>,</span> <span>tr</span><span>,</span> <span>br</span><span>,</span> <span>bl</span><span>)</span>
<span>return</span> <span>function</span><span>(</span><span>cr</span><span>,</span> <span>width</span><span>,</span> <span>height</span><span>)</span>
<span>gears</span><span>.</span><span>shape</span><span>.</span><span>partially_rounded_rect</span><span>(</span><span>cr</span><span>,</span> <span>width</span><span>,</span> <span>height</span><span>,</span> <span>tl</span><span>,</span> <span>tr</span><span>,</span> <span>br</span><span>,</span> <span>bl</span><span>,</span> <span>radius</span><span>)</span>
<span>end</span>
<span>end</span>
<span>function</span> <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>height</span><span>)</span>
<span>return</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
<span>forced_height</span> <span>=</span> <span>height</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>
<span>end</span>
<span>function</span> <span>helpers</span><span>.</span><span>horizontal_pad</span><span>(</span><span>width</span><span>)</span>
<span>return</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
<span>forced_width</span> <span>=</span> <span>width</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>}</span>
<span>end</span>
<span>function</span> <span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>w</span><span>,</span> <span>hover_cursor</span><span>)</span>
<span>local</span> <span>original_cursor</span> <span>=</span> <span>"left_ptr"</span>
<span>w</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::enter"</span><span>,</span> <span>function</span> <span>()</span>
<span>local</span> <span>w</span> <span>=</span> <span>_G</span><span>.</span><span>mouse</span><span>.</span><span>current_wibox</span>
<span>if</span> <span>w</span> <span>then</span>
<span>w</span><span>.</span><span>cursor</span> <span>=</span> <span>hover_cursor</span>
<span>end</span>
<span>end</span><span>)</span>
<span>w</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::leave"</span><span>,</span> <span>function</span> <span>()</span>
<span>local</span> <span>w</span> <span>=</span> <span>_G</span><span>.</span><span>mouse</span><span>.</span><span>current_wibox</span>
<span>if</span> <span>w</span> <span>then</span>
<span>w</span><span>.</span><span>cursor</span> <span>=</span> <span>original_cursor</span>
<span>end</span>
<span>end</span><span>)</span>
<span>end</span>
<span>return</span> <span>helpers</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>{}</span>

<span>helpers</span><span>.</span><span>colorize_text</span> <span>=</span> <span>function</span><span>(</span><span>text</span><span>,</span> <span>color</span><span>)</span>
    <span>return</span> <span>"<span foreground='"</span><span>..</span><span>color</span><span>..</span><span>"'>"</span><span>..</span><span>text</span><span>..</span><span>"</span>"</span>
<span>end</span>

<span>helpers</span><span>.</span><span>prrect</span> <span>=</span> <span>function</span><span>(</span><span>radius</span><span>,</span> <span>tl</span><span>,</span> <span>tr</span><span>,</span> <span>br</span><span>,</span> <span>bl</span><span>)</span>
    <span>return</span> <span>function</span><span>(</span><span>cr</span><span>,</span> <span>width</span><span>,</span> <span>height</span><span>)</span>
        <span>gears</span><span>.</span><span>shape</span><span>.</span><span>partially_rounded_rect</span><span>(</span><span>cr</span><span>,</span> <span>width</span><span>,</span> <span>height</span><span>,</span> <span>tl</span><span>,</span> <span>tr</span><span>,</span> <span>br</span><span>,</span> <span>bl</span><span>,</span> <span>radius</span><span>)</span>
    <span>end</span>
<span>end</span>

<span>function</span> <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>height</span><span>)</span>
    <span>return</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
        <span>forced_height</span> <span>=</span> <span>height</span><span>,</span>
        <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
    <span>}</span>
<span>end</span>

<span>function</span> <span>helpers</span><span>.</span><span>horizontal_pad</span><span>(</span><span>width</span><span>)</span>
    <span>return</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
        <span>forced_width</span> <span>=</span> <span>width</span><span>,</span>
        <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
    <span>}</span>
<span>end</span>

<span>function</span> <span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>w</span><span>,</span> <span>hover_cursor</span><span>)</span>
    <span>local</span> <span>original_cursor</span> <span>=</span> <span>"left_ptr"</span>

    <span>w</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::enter"</span><span>,</span> <span>function</span> <span>()</span>
        <span>local</span> <span>w</span> <span>=</span> <span>_G</span><span>.</span><span>mouse</span><span>.</span><span>current_wibox</span>
        <span>if</span> <span>w</span> <span>then</span>
            <span>w</span><span>.</span><span>cursor</span> <span>=</span> <span>hover_cursor</span>
        <span>end</span>
    <span>end</span><span>)</span>

    <span>w</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::leave"</span><span>,</span> <span>function</span> <span>()</span>
        <span>local</span> <span>w</span> <span>=</span> <span>_G</span><span>.</span><span>mouse</span><span>.</span><span>current_wibox</span>
        <span>if</span> <span>w</span> <span>then</span>
            <span>w</span><span>.</span><span>cursor</span> <span>=</span> <span>original_cursor</span>
        <span>end</span>
    <span>end</span><span>)</span>
<span>end</span>

<span>return</span> <span>helpers</span>
local wibox = require("wibox") local gears = require("gears") local helpers = {} helpers.colorize_text = function(text, color) return "<span foreground='"..color.."'>"..text.."</span>" end helpers.prrect = function(radius, tl, tr, br, bl) return function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius) end end function helpers.vertical_pad(height) return wibox.widget{ forced_height = height, layout = wibox.layout.fixed.vertical } end function helpers.horizontal_pad(width) return wibox.widget{ forced_width = width, layout = wibox.layout.fixed.horizontal } end function helpers.add_hover_cursor(w, hover_cursor) local original_cursor = "left_ptr" w:connect_signal("mouse::enter", function () local w = _G.mouse.current_wibox if w then w.cursor = hover_cursor end end) w:connect_signal("mouse::leave", function () local w = _G.mouse.current_wibox if w then w.cursor = original_cursor end end) end return helpers

Enter fullscreen mode Exit fullscreen mode


Configuring Daemons

Our very first challenge is to make and configure daemons, which will provide us with information and updates over regular interval.

Daemons can be made using the signals library of awesome. Here we have to configure three daemons specifically for ( listen.moe, spotify, mpd )

The daemons will be initiated with an init.lua . Using it we can easily turn on/off a daemon .


init.lua

<span>require</span><span>(</span><span>"daemon.moe"</span><span>)</span>
<span>require</span><span>(</span><span>"daemon.mpd"</span><span>)</span>
<span>require</span><span>(</span><span>"daemon.spotify"</span><span>)</span>
<span>require</span><span>(</span><span>"daemon.moe"</span><span>)</span>
<span>require</span><span>(</span><span>"daemon.mpd"</span><span>)</span>
<span>require</span><span>(</span><span>"daemon.spotify"</span><span>)</span>
require("daemon.moe") require("daemon.mpd") require("daemon.spotify")

Enter fullscreen mode Exit fullscreen mode

Now, Here is the code for the 3 daemon files.


moe.lua

<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>function</span> <span>emit_info</span> <span>(</span><span>moe_script_output</span><span>)</span>
<span>local</span> <span>count</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'count(%d*)cover'</span><span>)</span>
<span>local</span> <span>cover</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'cover(.*)title'</span><span>)</span>
<span>local</span> <span>title</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'title(.*)artist'</span><span>)</span>
<span>local</span> <span>artist</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'artist(.*)end'</span><span>)</span>
<span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::moe"</span><span>,</span> <span>count</span><span>,</span> <span>cover</span><span>,</span> <span>title</span><span>,</span> <span>artist</span><span>)</span>
<span>end</span>
<span>local</span> <span>moe_script</span> <span>=</span> <span>[[ sh -c 'python $HOME/projects/moe.py' ]]</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>python</span> <span>/</span><span>home</span><span>/</span><span>lucifer</span><span>/</span><span>projects</span><span>/</span><span>moe</span><span>.</span><span>py</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargskill"</span><span>,</span> <span>function</span><span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>moe_script</span><span>,</span> <span>{</span>
<span>stdout</span> <span>=</span> <span>function</span> <span>(</span><span>line</span><span>)</span>
<span>emit_info</span><span>(</span><span>line</span><span>)</span>
<span>end</span>
<span>})</span>
<span>end</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>

<span>local</span> <span>function</span> <span>emit_info</span> <span>(</span><span>moe_script_output</span><span>)</span>
  <span>local</span> <span>count</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'count(%d*)cover'</span><span>)</span>
  <span>local</span> <span>cover</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'cover(.*)title'</span><span>)</span>
  <span>local</span> <span>title</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'title(.*)artist'</span><span>)</span>
  <span>local</span> <span>artist</span> <span>=</span> <span>moe_script_output</span><span>:</span><span>match</span><span>(</span><span>'artist(.*)end'</span><span>)</span>
  <span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::moe"</span><span>,</span> <span>count</span><span>,</span> <span>cover</span><span>,</span> <span>title</span><span>,</span> <span>artist</span><span>)</span>
<span>end</span>

<span>local</span> <span>moe_script</span> <span>=</span> <span>[[ sh -c 'python $HOME/projects/moe.py' ]]</span>

<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>python</span> <span>/</span><span>home</span><span>/</span><span>lucifer</span><span>/</span><span>projects</span><span>/</span><span>moe</span><span>.</span><span>py</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargskill"</span><span>,</span> <span>function</span><span>()</span>
  <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>moe_script</span><span>,</span> <span>{</span>
    <span>stdout</span> <span>=</span> <span>function</span> <span>(</span><span>line</span><span>)</span>
        <span>emit_info</span><span>(</span><span>line</span><span>)</span>
    <span>end</span>
<span>})</span>
<span>end</span><span>)</span>
local awful = require("awful") local function emit_info (moe_script_output) local count = moe_script_output:match('count(%d*)cover') local cover = moe_script_output:match('cover(.*)title') local title = moe_script_output:match('title(.*)artist') local artist = moe_script_output:match('artist(.*)end') awesome.emit_signal("daemon::moe", count, cover, title, artist) end local moe_script = [[ sh -c 'python $HOME/projects/moe.py' ]] awful.spawn.easy_async_with_shell("ps x | grep \"python /home/lucifer/projects/moe.py\" | grep -v grep | awk '{print $1}' | xargskill", function() awful.spawn.with_line_callback(moe_script, { stdout = function (line) emit_info(line) end }) end)

Enter fullscreen mode Exit fullscreen mode

Firstly, we are requiring the ‘awful’ library for spawning process here. The function emit_info takes the stdout of a python script (moe.py – a python script which establishes a web socket connection with listen.moe and writes data on song change ) , grabs the necessary information out of it and emits a signal with that information.

The moe.py script can be placed anywhere but you should update it’s path in the local moe_script. Next we use awful.spawn to kill the python script process ( moe.py ) if it already exists ( in case of restart of awesome ).

After that in the callback function we use awful.spawn.with_line_callback to asynchronously read each line generated by the moe.py script and call emit_info function for that line to grab the necessary information out of it to emit a signal.

Additionaly the moe.py script that provides the information for moe daemon :

<span>#!/usr/bin/python </span>
<span>from</span> <span>sys</span> <span>import</span> <span>stdout</span>
<span>from</span> <span>os.path</span> <span>import</span> <span>exists</span>
<span>from</span> <span>time</span> <span>import</span> <span>sleep</span>
<span>from</span> <span>requests</span> <span>import</span> <span>get</span>
<span>import</span> <span>wget</span>
<span>import</span> <span>json</span>
<span>import</span> <span>asyncio</span>
<span>import</span> <span>websockets</span>
<span>path</span> <span>=</span> <span>'/home/lucifer/projects/'</span>
<span>album_cover_url</span> <span>=</span> <span>'https://cdn.listen.moe/covers/'</span>
<span>artist_cover_url</span> <span>=</span> <span>'https://cdn.listen.moe/artists/'</span>
<span>async</span> <span>def</span> <span>send_ws</span><span>(</span><span>ws</span><span>,</span> <span>data</span><span>):</span>
<span>json_data</span> <span>=</span> <span>json</span><span>.</span><span>dumps</span><span>(</span><span>data</span><span>)</span>
<span>await</span> <span>ws</span><span>.</span><span>send</span><span>(</span><span>json_data</span><span>)</span>
<span>async</span> <span>def</span> <span>_send_pings</span><span>(</span><span>ws</span><span>,</span> <span>interval</span><span>=</span><span>45</span><span>):</span>
<span>while</span> <span>True</span><span>:</span>
<span>await</span> <span>asyncio</span><span>.</span><span>sleep</span><span>(</span><span>interval</span><span>)</span>
<span>msg</span> <span>=</span> <span>{</span><span>'op'</span><span>:</span> <span>9</span><span>}</span>
<span>await</span> <span>send_ws</span><span>(</span><span>ws</span><span>,</span> <span>msg</span><span>)</span>
<span>def</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>URL</span><span>):</span>
<span>PATH</span> <span>=</span> <span>path</span> <span>+</span> <span>cover</span>
<span>if</span> <span>not</span> <span>exists</span><span>(</span><span>PATH</span><span>):</span>
<span>try</span><span>:</span>
<span>wget</span><span>.</span><span>download</span><span>(</span><span>URL</span><span>,</span> <span>out</span><span>=</span><span>PATH</span><span>,</span> <span>bar</span><span>=</span><span>None</span><span>)</span>
<span># file = get(URL, allow_redirects=True, timeout=2.5) </span> <span># open(PATH, 'wb').write(file.content) </span> <span>return</span> <span>True</span>
<span>except</span><span>:</span>
<span>return</span> <span>False</span>
<span>else</span><span>:</span>
<span>return</span> <span>True</span>
<span>async</span> <span>def</span> <span>main</span><span>(</span><span>loop</span><span>):</span>
<span>url</span> <span>=</span> <span>'wss://listen.moe/gateway_v2'</span>
<span>count</span> <span>=</span> <span>''</span>
<span>cover</span> <span>=</span> <span>'!Available'</span>
<span>artist</span> <span>=</span> <span>'Not Available'</span>
<span>title</span> <span>=</span> <span>'Not Available'</span>
<span>while</span> <span>True</span><span>:</span>
<span>try</span><span>:</span>
<span>ws</span> <span>=</span> <span>await</span> <span>websockets</span><span>.</span><span>connect</span><span>(</span><span>url</span><span>)</span>
<span>break</span>
<span>except</span><span>:</span>
<span>sleep</span><span>(</span><span>30</span><span>)</span>
<span>while</span> <span>True</span><span>:</span>
<span>data</span> <span>=</span> <span>json</span><span>.</span><span>loads</span><span>(</span><span>await</span> <span>ws</span><span>.</span><span>recv</span><span>())</span>
<span>if</span> <span>data</span><span>[</span><span>'op'</span><span>]</span> <span>==</span> <span>0</span><span>:</span>
<span>heartbeat</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'heartbeat'</span><span>]</span> <span>/</span> <span>1000</span>
<span>loop</span><span>.</span><span>create_task</span><span>(</span><span>_send_pings</span><span>(</span><span>ws</span><span>,</span> <span>heartbeat</span><span>))</span>
<span>elif</span> <span>data</span><span>[</span><span>'op'</span><span>]</span> <span>==</span> <span>1</span><span>:</span>
<span>if</span> <span>data</span><span>[</span><span>'d'</span><span>]:</span>
<span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'listeners'</span><span>]:</span>
<span>count</span> <span>=</span> <span>str</span><span>(</span><span>data</span><span>[</span><span>'d'</span><span>][</span><span>'listeners'</span><span>])</span>
<span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'title'</span><span>]:</span>
<span>title</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'title'</span><span>]</span>
<span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>]:</span>
<span>artist</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'nameRomaji'</span><span>]</span> <span>or</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'name'</span><span>]</span> <span>or</span> <span>'NotAvailable'</span>
<span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>]</span> <span>and</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]:</span>
<span>cover</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]</span>
<span>if</span> <span>not</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>album_cover_url</span> <span>+</span> <span>cover</span><span>):</span>
<span>cover</span> <span>=</span> <span>'!Available'</span>
<span>elif</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>]</span> <span>and</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]:</span>
<span>cover</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]</span>
<span>if</span> <span>not</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>artist_cover_url</span><span>):</span>
<span>cover</span> <span>=</span> <span>'!Available'</span>
<span>stdout</span><span>.</span><span>write</span><span>(</span>
<span>f</span><span>'count</span><span>{</span><span>count</span><span>}</span><span>cover</span><span>{</span><span>cover</span><span>}</span><span>title</span><span>{</span><span>title</span><span>}</span><span>artist</span><span>{</span><span>artist</span><span>}</span><span>end</span><span>\n</span><span>'</span><span>)</span>
<span>stdout</span><span>.</span><span>flush</span><span>()</span>
<span>if</span> <span>__name__</span> <span>==</span> <span>'__main__'</span><span>:</span>
<span>loop</span> <span>=</span> <span>asyncio</span><span>.</span><span>get_event_loop</span><span>()</span>
<span>loop</span><span>.</span><span>run_until_complete</span><span>(</span><span>main</span><span>(</span><span>loop</span><span>))</span>
<span>#!/usr/bin/python </span>
<span>from</span> <span>sys</span> <span>import</span> <span>stdout</span>
<span>from</span> <span>os.path</span> <span>import</span> <span>exists</span>
<span>from</span> <span>time</span> <span>import</span> <span>sleep</span>
<span>from</span> <span>requests</span> <span>import</span> <span>get</span>
<span>import</span> <span>wget</span>
<span>import</span> <span>json</span>
<span>import</span> <span>asyncio</span>
<span>import</span> <span>websockets</span>

<span>path</span> <span>=</span> <span>'/home/lucifer/projects/'</span>
<span>album_cover_url</span> <span>=</span> <span>'https://cdn.listen.moe/covers/'</span>
<span>artist_cover_url</span> <span>=</span> <span>'https://cdn.listen.moe/artists/'</span>


<span>async</span> <span>def</span> <span>send_ws</span><span>(</span><span>ws</span><span>,</span> <span>data</span><span>):</span>
    <span>json_data</span> <span>=</span> <span>json</span><span>.</span><span>dumps</span><span>(</span><span>data</span><span>)</span>
    <span>await</span> <span>ws</span><span>.</span><span>send</span><span>(</span><span>json_data</span><span>)</span>


<span>async</span> <span>def</span> <span>_send_pings</span><span>(</span><span>ws</span><span>,</span> <span>interval</span><span>=</span><span>45</span><span>):</span>
    <span>while</span> <span>True</span><span>:</span>
        <span>await</span> <span>asyncio</span><span>.</span><span>sleep</span><span>(</span><span>interval</span><span>)</span>
        <span>msg</span> <span>=</span> <span>{</span><span>'op'</span><span>:</span> <span>9</span><span>}</span>
        <span>await</span> <span>send_ws</span><span>(</span><span>ws</span><span>,</span> <span>msg</span><span>)</span>


<span>def</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>URL</span><span>):</span>
    <span>PATH</span> <span>=</span> <span>path</span> <span>+</span> <span>cover</span>
    <span>if</span> <span>not</span> <span>exists</span><span>(</span><span>PATH</span><span>):</span>
        <span>try</span><span>:</span>
            <span>wget</span><span>.</span><span>download</span><span>(</span><span>URL</span><span>,</span> <span>out</span><span>=</span><span>PATH</span><span>,</span> <span>bar</span><span>=</span><span>None</span><span>)</span>
            <span># file = get(URL, allow_redirects=True, timeout=2.5) </span>            <span># open(PATH, 'wb').write(file.content) </span>            <span>return</span> <span>True</span>
        <span>except</span><span>:</span>
            <span>return</span> <span>False</span>
    <span>else</span><span>:</span>
        <span>return</span> <span>True</span>


<span>async</span> <span>def</span> <span>main</span><span>(</span><span>loop</span><span>):</span>
    <span>url</span> <span>=</span> <span>'wss://listen.moe/gateway_v2'</span>
    <span>count</span> <span>=</span> <span>''</span>
    <span>cover</span> <span>=</span> <span>'!Available'</span>
    <span>artist</span> <span>=</span> <span>'Not Available'</span>
    <span>title</span> <span>=</span> <span>'Not Available'</span>
    <span>while</span> <span>True</span><span>:</span>
        <span>try</span><span>:</span>
            <span>ws</span> <span>=</span> <span>await</span> <span>websockets</span><span>.</span><span>connect</span><span>(</span><span>url</span><span>)</span>
            <span>break</span>
        <span>except</span><span>:</span>
            <span>sleep</span><span>(</span><span>30</span><span>)</span>

    <span>while</span> <span>True</span><span>:</span>
        <span>data</span> <span>=</span> <span>json</span><span>.</span><span>loads</span><span>(</span><span>await</span> <span>ws</span><span>.</span><span>recv</span><span>())</span>

        <span>if</span> <span>data</span><span>[</span><span>'op'</span><span>]</span> <span>==</span> <span>0</span><span>:</span>
            <span>heartbeat</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'heartbeat'</span><span>]</span> <span>/</span> <span>1000</span>
            <span>loop</span><span>.</span><span>create_task</span><span>(</span><span>_send_pings</span><span>(</span><span>ws</span><span>,</span> <span>heartbeat</span><span>))</span>
        <span>elif</span> <span>data</span><span>[</span><span>'op'</span><span>]</span> <span>==</span> <span>1</span><span>:</span>
            <span>if</span> <span>data</span><span>[</span><span>'d'</span><span>]:</span>

                <span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'listeners'</span><span>]:</span>
                    <span>count</span> <span>=</span> <span>str</span><span>(</span><span>data</span><span>[</span><span>'d'</span><span>][</span><span>'listeners'</span><span>])</span>

                <span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'title'</span><span>]:</span>
                    <span>title</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'title'</span><span>]</span>

                <span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>]:</span>
                    <span>artist</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'nameRomaji'</span><span>]</span> <span>or</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'name'</span><span>]</span> <span>or</span> <span>'NotAvailable'</span>

                <span>if</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>]</span> <span>and</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]:</span>
                    <span>cover</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'albums'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]</span>
                    <span>if</span> <span>not</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>album_cover_url</span> <span>+</span> <span>cover</span><span>):</span>
                        <span>cover</span> <span>=</span> <span>'!Available'</span>
                <span>elif</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>]</span> <span>and</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]:</span>
                    <span>cover</span> <span>=</span> <span>data</span><span>[</span><span>'d'</span><span>][</span><span>'song'</span><span>][</span><span>'artists'</span><span>][</span><span>0</span><span>][</span><span>'image'</span><span>]</span>
                    <span>if</span> <span>not</span> <span>_save_cover</span><span>(</span><span>cover</span><span>,</span> <span>artist_cover_url</span><span>):</span>
                        <span>cover</span> <span>=</span> <span>'!Available'</span>

                <span>stdout</span><span>.</span><span>write</span><span>(</span>
                    <span>f</span><span>'count</span><span>{</span><span>count</span><span>}</span><span>cover</span><span>{</span><span>cover</span><span>}</span><span>title</span><span>{</span><span>title</span><span>}</span><span>artist</span><span>{</span><span>artist</span><span>}</span><span>end</span><span>\n</span><span>'</span><span>)</span>
                <span>stdout</span><span>.</span><span>flush</span><span>()</span>

<span>if</span> <span>__name__</span> <span>==</span> <span>'__main__'</span><span>:</span>
    <span>loop</span> <span>=</span> <span>asyncio</span><span>.</span><span>get_event_loop</span><span>()</span>
    <span>loop</span><span>.</span><span>run_until_complete</span><span>(</span><span>main</span><span>(</span><span>loop</span><span>))</span>
#!/usr/bin/python from sys import stdout from os.path import exists from time import sleep from requests import get import wget import json import asyncio import websockets path = '/home/lucifer/projects/' album_cover_url = 'https://cdn.listen.moe/covers/' artist_cover_url = 'https://cdn.listen.moe/artists/' async def send_ws(ws, data): json_data = json.dumps(data) await ws.send(json_data) async def _send_pings(ws, interval=45): while True: await asyncio.sleep(interval) msg = {'op': 9} await send_ws(ws, msg) def _save_cover(cover, URL): PATH = path + cover if not exists(PATH): try: wget.download(URL, out=PATH, bar=None) # file = get(URL, allow_redirects=True, timeout=2.5) # open(PATH, 'wb').write(file.content) return True except: return False else: return True async def main(loop): url = 'wss://listen.moe/gateway_v2' count = '' cover = '!Available' artist = 'Not Available' title = 'Not Available' while True: try: ws = await websockets.connect(url) break except: sleep(30) while True: data = json.loads(await ws.recv()) if data['op'] == 0: heartbeat = data['d']['heartbeat'] / 1000 loop.create_task(_send_pings(ws, heartbeat)) elif data['op'] == 1: if data['d']: if data['d']['listeners']: count = str(data['d']['listeners']) if data['d']['song']['title']: title = data['d']['song']['title'] if data['d']['song']['artists']: artist = data['d']['song']['artists'][0]['nameRomaji'] or data['d']['song']['artists'][0]['name'] or 'NotAvailable' if data['d']['song']['albums'] and data['d']['song']['albums'][0]['image']: cover = data['d']['song']['albums'][0]['image'] if not _save_cover(cover, album_cover_url + cover): cover = '!Available' elif data['d']['song']['artists'] and data['d']['song']['artists'][0]['image']: cover = data['d']['song']['artists'][0]['image'] if not _save_cover(cover, artist_cover_url): cover = '!Available' stdout.write( f'count{count}cover{cover}title{title}artist{artist}end\n') stdout.flush() if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(main(loop))

Enter fullscreen mode Exit fullscreen mode

The script when run establishes a web socket connection to a dedicated listen.moe web socket server. The script sleeps 30 sec if no internet connection is established and then fires again to establish the connection.

The script receives a json response object from which we extract the artist name, title name and the cover image endpoint. Images are downloaded using the cover image endpoint with wget python package. The path variable holds the download directory for images and should be updated to your preference in the script.

Some may prefer keeping the covers of the song, but i usually don’t like saving them. So i added a cronjob to remove these images on every reboot.

@reboot rm /home/lucifer/projects/*.{png,jpg,jpeg,tmp}
@reboot rm /home/lucifer/projects/*.{png,jpg,jpeg,tmp}
@reboot rm /home/lucifer/projects/*.{png,jpg,jpeg,tmp}

Enter fullscreen mode Exit fullscreen mode


spotify.lua

<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>function</span> <span>emit_info</span><span>(</span><span>playerctl_output</span><span>)</span>
<span>local</span> <span>artist</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'artist_start(.*)title_start'</span><span>)</span>
<span>local</span> <span>title</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'title_start(.*)status_start'</span><span>)</span>
<span>-- Use the lower case of status</span>
<span>local</span> <span>status</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'status_start(.*)'</span><span>):</span><span>lower</span><span>()</span>
<span>status</span> <span>=</span> <span>string.gsub</span><span>(</span><span>status</span><span>,</span> <span>'^%s*(.-)%s*$'</span><span>,</span> <span>'%1'</span><span>)</span>
<span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
<span>end</span>
<span>-- Sleeps until spotify changes state (pause/play/next/prev)</span>
<span>local</span> <span>spotify_script</span> <span>=</span> <span>[[ sh -c ' playerctl --player spotify metadata --format 'artist_start{{artist}}title_start{{title}}status_start{{status}}' --follow ']]</span>
<span>-- Kill old playerctl process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>playerctl</span> <span>--player spotify metadata\" | grep -v grep | awk '{print $1}' | xargs kill", function ()</span>
<span>-- Emit song info with each line printed</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>spotify_script</span><span>,</span> <span>{</span>
<span>stdout</span> <span>=</span> <span>function</span><span>(</span><span>line</span><span>)</span>
<span>emit_info</span><span>(</span><span>line</span><span>)</span>
<span>end</span>
<span>})</span>
<span>end</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>

<span>local</span> <span>function</span> <span>emit_info</span><span>(</span><span>playerctl_output</span><span>)</span>
    <span>local</span> <span>artist</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'artist_start(.*)title_start'</span><span>)</span>
    <span>local</span> <span>title</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'title_start(.*)status_start'</span><span>)</span>
    <span>-- Use the lower case of status</span>
    <span>local</span> <span>status</span> <span>=</span> <span>playerctl_output</span><span>:</span><span>match</span><span>(</span><span>'status_start(.*)'</span><span>):</span><span>lower</span><span>()</span>
    <span>status</span> <span>=</span> <span>string.gsub</span><span>(</span><span>status</span><span>,</span> <span>'^%s*(.-)%s*$'</span><span>,</span> <span>'%1'</span><span>)</span>

    <span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
<span>end</span>

<span>-- Sleeps until spotify changes state (pause/play/next/prev)</span>
<span>local</span> <span>spotify_script</span> <span>=</span> <span>[[ sh -c ' playerctl --player spotify metadata --format 'artist_start{{artist}}title_start{{title}}status_start{{status}}' --follow ']]</span>

<span>-- Kill old playerctl process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>playerctl</span> <span>--player spotify metadata\" | grep -v grep | awk '{print $1}' | xargs kill", function ()</span>
    <span>-- Emit song info with each line printed</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>spotify_script</span><span>,</span> <span>{</span>
        <span>stdout</span> <span>=</span> <span>function</span><span>(</span><span>line</span><span>)</span>
            <span>emit_info</span><span>(</span><span>line</span><span>)</span>
        <span>end</span>
    <span>})</span>
<span>end</span><span>)</span>
local awful = require("awful") local function emit_info(playerctl_output) local artist = playerctl_output:match('artist_start(.*)title_start') local title = playerctl_output:match('title_start(.*)status_start') -- Use the lower case of status local status = playerctl_output:match('status_start(.*)'):lower() status = string.gsub(status, '^%s*(.-)%s*$', '%1') awesome.emit_signal("daemon::spotify", artist, title, status) end -- Sleeps until spotify changes state (pause/play/next/prev) local spotify_script = [[ sh -c ' playerctl --player spotify metadata --format 'artist_start{{artist}}title_start{{title}}status_start{{status}}' --follow ']] -- Kill old playerctl process awful.spawn.easy_async_with_shell("ps x | grep \"playerctl --player spotify metadata\" | grep -v grep | awk '{print $1}' | xargs kill", function () -- Emit song info with each line printed awful.spawn.with_line_callback(spotify_script, { stdout = function(line) emit_info(line) end }) end)

Enter fullscreen mode Exit fullscreen mode

spotify.lua takes the stdout from playerctl ( A utility command line tool to control MPRIS-enabled media players ). You need to have playerctl installed to make it work.

The script is very much alike to moe.lua except that it depends on playerctl for obtain information regarding the status of spotify player ( song name, album name, playing status ).


mpd.lua

<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>function</span> <span>emit_info</span><span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"sh -c 'mpc -f ARTIST@%artist%@TITLE@%title%@FILE@%file%@'"</span><span>,</span>
<span>function</span><span>(</span><span>stdout</span><span>)</span>
<span>local</span> <span>artist</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'^ARTIST@(.*)@TITLE'</span><span>)</span>
<span>local</span> <span>title</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'@TITLE@(.*)@FILE'</span><span>)</span>
<span>local</span> <span>status</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'</span><span>\n</span><span>%[(.*)%]'</span><span>)</span>
<span>if</span> <span>not</span> <span>artist</span> <span>or</span> <span>artist</span> <span>==</span> <span>""</span> <span>then</span>
<span>artist</span> <span>=</span> <span>"N/A"</span>
<span>end</span>
<span>if</span> <span>not</span> <span>title</span> <span>or</span> <span>title</span> <span>==</span> <span>""</span> <span>then</span>
<span>title</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'@FILE@(.*)@'</span><span>)</span>
<span>if</span> <span>not</span> <span>title</span> <span>or</span> <span>title</span> <span>==</span> <span>""</span> <span>then</span>
<span>title</span> <span>=</span> <span>"N/A"</span>
<span>end</span>
<span>end</span>
<span>local</span> <span>paused</span>
<span>if</span> <span>status</span> <span>==</span> <span>"playing"</span> <span>then</span>
<span>paused</span> <span>=</span> <span>false</span>
<span>else</span>
<span>paused</span> <span>=</span> <span>true</span>
<span>end</span>
<span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>artist</span><span>,</span> <span>title</span><span>,</span> <span>paused</span><span>)</span>
<span>end</span>
<span>)</span>
<span>end</span>
<span>-- Run once to initialize widgets</span>
<span>emit_info</span><span>()</span>
<span>-- Sleeps until mpd changes state (pause/play/next/prev)</span>
<span>local</span> <span>mpd_script</span> <span>=</span> <span>[[ sh -c ' mpc idleloop player ']]</span>
<span>-- Kill old mpc idleloop player process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>player</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
<span>-- Emit song info with each line printed</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_script</span><span>,</span> <span>{</span>
<span>stdout</span> <span>=</span> <span>function</span><span>()</span>
<span>emit_info</span><span>()</span>
<span>end</span>
<span>})</span>
<span>end</span><span>)</span>
<span>----------------------------------------------------------</span>
<span>-- MPD Volume</span>
<span>local</span> <span>function</span> <span>emit_volume_info</span><span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"mpc volume | awk '{print substr($2, 1, length($2)-1)}'"</span><span>,</span>
<span>function</span><span>(</span><span>stdout</span><span>)</span>
<span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd_volume"</span><span>,</span> <span>tonumber</span><span>(</span><span>stdout</span><span>))</span>
<span>end</span>
<span>)</span>
<span>end</span>
<span>-- Run once to initialize widgets</span>
<span>emit_volume_info</span><span>()</span>
<span>-- Sleeps until mpd volume changes</span>
<span>-- >> We use `sed '1~2d'` to remove every other line since the mixer event</span>
<span>-- is printed twice for every volume update.</span>
<span>-- >> The `-u` option forces sed to work in unbuffered mode in order to print</span>
<span>-- without waiting for `mpc idleloop mixer` to finish</span>
<span>local</span> <span>mpd_volume_script</span> <span>=</span> <span>[[ sh -c " mpc idleloop mixer | sed -u '1~2d' "]]</span>
<span>-- Kill old mpc idleloop mixer process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>mixer</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
<span>-- Emit song info with each line printed</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_volume_script</span><span>,</span> <span>{</span>
<span>stdout</span> <span>=</span> <span>function</span><span>()</span>
<span>emit_volume_info</span><span>()</span>
<span>end</span>
<span>})</span>
<span>end</span><span>)</span>
<span>local</span> <span>mpd_options_script</span> <span>=</span> <span>[[ sh -c " mpc idleloop options "]]</span>
<span>local</span> <span>function</span> <span>emit_options_info</span><span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"mpc | tail -1"</span><span>,</span>
<span>function</span><span>(</span><span>stdout</span><span>)</span>
<span>local</span> <span>loop</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'repeat: (.*)'</span><span>)</span>
<span>local</span> <span>random</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'random: (.*)'</span><span>)</span>
<span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd_options"</span><span>,</span> <span>loop</span><span>:</span><span>sub</span><span>(</span><span>1</span><span>,</span> <span>2</span><span>)</span> <span>==</span> <span>"on"</span><span>,</span> <span>random</span><span>:</span><span>sub</span><span>(</span><span>1</span><span>,</span> <span>2</span><span>)</span><span>==</span> <span>"on"</span><span>)</span>
<span>end</span>
<span>)</span>
<span>end</span>
<span>-- Run once to initialize widgets</span>
<span>emit_options_info</span><span>()</span>
<span>-- Kill old mpc idleloop options process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>options</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
<span>-- Emit song info with each line printed</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_options_script</span><span>,</span> <span>{</span>
<span>stdout</span> <span>=</span> <span>function</span><span>()</span>
<span>emit_options_info</span><span>()</span>
<span>end</span>
<span>})</span>
<span>end</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>

<span>local</span> <span>function</span> <span>emit_info</span><span>()</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"sh -c 'mpc -f ARTIST@%artist%@TITLE@%title%@FILE@%file%@'"</span><span>,</span>
        <span>function</span><span>(</span><span>stdout</span><span>)</span>
            <span>local</span> <span>artist</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'^ARTIST@(.*)@TITLE'</span><span>)</span>
            <span>local</span> <span>title</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'@TITLE@(.*)@FILE'</span><span>)</span>
            <span>local</span> <span>status</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'</span><span>\n</span><span>%[(.*)%]'</span><span>)</span>

            <span>if</span> <span>not</span> <span>artist</span> <span>or</span> <span>artist</span> <span>==</span> <span>""</span> <span>then</span>
              <span>artist</span> <span>=</span> <span>"N/A"</span>
            <span>end</span>
            <span>if</span> <span>not</span> <span>title</span> <span>or</span> <span>title</span> <span>==</span> <span>""</span> <span>then</span>
              <span>title</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'@FILE@(.*)@'</span><span>)</span>
              <span>if</span> <span>not</span> <span>title</span> <span>or</span> <span>title</span> <span>==</span> <span>""</span> <span>then</span>
                  <span>title</span> <span>=</span> <span>"N/A"</span>
              <span>end</span>
            <span>end</span>

            <span>local</span> <span>paused</span>
            <span>if</span> <span>status</span> <span>==</span> <span>"playing"</span> <span>then</span>
                <span>paused</span> <span>=</span> <span>false</span>
            <span>else</span>
                <span>paused</span> <span>=</span> <span>true</span>
            <span>end</span>

            <span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>artist</span><span>,</span> <span>title</span><span>,</span> <span>paused</span><span>)</span>
        <span>end</span>
    <span>)</span>
<span>end</span>

<span>-- Run once to initialize widgets</span>
<span>emit_info</span><span>()</span>

<span>-- Sleeps until mpd changes state (pause/play/next/prev)</span>
<span>local</span> <span>mpd_script</span> <span>=</span> <span>[[ sh -c ' mpc idleloop player ']]</span>

<span>-- Kill old mpc idleloop player process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>player</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
    <span>-- Emit song info with each line printed</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_script</span><span>,</span> <span>{</span>
        <span>stdout</span> <span>=</span> <span>function</span><span>()</span>
            <span>emit_info</span><span>()</span>
        <span>end</span>
    <span>})</span>
<span>end</span><span>)</span>

<span>----------------------------------------------------------</span>

<span>-- MPD Volume</span>
<span>local</span> <span>function</span> <span>emit_volume_info</span><span>()</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"mpc volume | awk '{print substr($2, 1, length($2)-1)}'"</span><span>,</span>
        <span>function</span><span>(</span><span>stdout</span><span>)</span>
            <span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd_volume"</span><span>,</span> <span>tonumber</span><span>(</span><span>stdout</span><span>))</span>
        <span>end</span>
    <span>)</span>
<span>end</span>

<span>-- Run once to initialize widgets</span>
<span>emit_volume_info</span><span>()</span>

<span>-- Sleeps until mpd volume changes</span>
<span>-- >> We use `sed '1~2d'` to remove every other line since the mixer event</span>
<span>-- is printed twice for every volume update.</span>
<span>-- >> The `-u` option forces sed to work in unbuffered mode in order to print</span>
<span>-- without waiting for `mpc idleloop mixer` to finish</span>
<span>local</span> <span>mpd_volume_script</span> <span>=</span> <span>[[ sh -c " mpc idleloop mixer | sed -u '1~2d' "]]</span>

<span>-- Kill old mpc idleloop mixer process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>mixer</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
    <span>-- Emit song info with each line printed</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_volume_script</span><span>,</span> <span>{</span>
        <span>stdout</span> <span>=</span> <span>function</span><span>()</span>
            <span>emit_volume_info</span><span>()</span>
        <span>end</span>
    <span>})</span>
<span>end</span><span>)</span>

<span>local</span> <span>mpd_options_script</span> <span>=</span> <span>[[ sh -c " mpc idleloop options "]]</span>

<span>local</span> <span>function</span> <span>emit_options_info</span><span>()</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"mpc | tail -1"</span><span>,</span>
        <span>function</span><span>(</span><span>stdout</span><span>)</span>
            <span>local</span> <span>loop</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'repeat: (.*)'</span><span>)</span>
            <span>local</span> <span>random</span> <span>=</span> <span>stdout</span><span>:</span><span>match</span><span>(</span><span>'random: (.*)'</span><span>)</span>
            <span>awesome</span><span>.</span><span>emit_signal</span><span>(</span><span>"daemon::mpd_options"</span><span>,</span> <span>loop</span><span>:</span><span>sub</span><span>(</span><span>1</span><span>,</span> <span>2</span><span>)</span> <span>==</span> <span>"on"</span><span>,</span> <span>random</span><span>:</span><span>sub</span><span>(</span><span>1</span><span>,</span> <span>2</span><span>)</span><span>==</span> <span>"on"</span><span>)</span>
        <span>end</span>
    <span>)</span>
<span>end</span>

<span>-- Run once to initialize widgets</span>
<span>emit_options_info</span><span>()</span>

<span>-- Kill old mpc idleloop options process</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>easy_async_with_shell</span><span>(</span><span>"ps x | grep \"</span><span>mpc</span> <span>idleloop</span> <span>options</span><span>\</span><span>" | grep -v grep | awk '{print $1}' | xargs kill"</span><span>,</span> <span>function</span> <span>()</span>
    <span>-- Emit song info with each line printed</span>
    <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_line_callback</span><span>(</span><span>mpd_options_script</span><span>,</span> <span>{</span>
        <span>stdout</span> <span>=</span> <span>function</span><span>()</span>
            <span>emit_options_info</span><span>()</span>
        <span>end</span>
    <span>})</span>
<span>end</span><span>)</span>
local awful = require("awful") local function emit_info() awful.spawn.easy_async_with_shell("sh -c 'mpc -f ARTIST@%artist%@TITLE@%title%@FILE@%file%@'", function(stdout) local artist = stdout:match('^ARTIST@(.*)@TITLE') local title = stdout:match('@TITLE@(.*)@FILE') local status = stdout:match('\n%[(.*)%]') if not artist or artist == "" then artist = "N/A" end if not title or title == "" then title = stdout:match('@FILE@(.*)@') if not title or title == "" then title = "N/A" end end local paused if status == "playing" then paused = false else paused = true end awesome.emit_signal("daemon::mpd", artist, title, paused) end ) end -- Run once to initialize widgets emit_info() -- Sleeps until mpd changes state (pause/play/next/prev) local mpd_script = [[ sh -c ' mpc idleloop player ']] -- Kill old mpc idleloop player process awful.spawn.easy_async_with_shell("ps x | grep \"mpc idleloop player\" | grep -v grep | awk '{print $1}' | xargs kill", function () -- Emit song info with each line printed awful.spawn.with_line_callback(mpd_script, { stdout = function() emit_info() end }) end) ---------------------------------------------------------- -- MPD Volume local function emit_volume_info() awful.spawn.easy_async_with_shell("mpc volume | awk '{print substr($2, 1, length($2)-1)}'", function(stdout) awesome.emit_signal("daemon::mpd_volume", tonumber(stdout)) end ) end -- Run once to initialize widgets emit_volume_info() -- Sleeps until mpd volume changes -- >> We use `sed '1~2d'` to remove every other line since the mixer event -- is printed twice for every volume update. -- >> The `-u` option forces sed to work in unbuffered mode in order to print -- without waiting for `mpc idleloop mixer` to finish local mpd_volume_script = [[ sh -c " mpc idleloop mixer | sed -u '1~2d' "]] -- Kill old mpc idleloop mixer process awful.spawn.easy_async_with_shell("ps x | grep \"mpc idleloop mixer\" | grep -v grep | awk '{print $1}' | xargs kill", function () -- Emit song info with each line printed awful.spawn.with_line_callback(mpd_volume_script, { stdout = function() emit_volume_info() end }) end) local mpd_options_script = [[ sh -c " mpc idleloop options "]] local function emit_options_info() awful.spawn.easy_async_with_shell("mpc | tail -1", function(stdout) local loop = stdout:match('repeat: (.*)') local random = stdout:match('random: (.*)') awesome.emit_signal("daemon::mpd_options", loop:sub(1, 2) == "on", random:sub(1, 2)== "on") end ) end -- Run once to initialize widgets emit_options_info() -- Kill old mpc idleloop options process awful.spawn.easy_async_with_shell("ps x | grep \"mpc idleloop options\" | grep -v grep | awk '{print $1}' | xargs kill", function () -- Emit song info with each line printed awful.spawn.with_line_callback(mpd_options_script, { stdout = function() emit_options_info() end }) end)

Enter fullscreen mode Exit fullscreen mode

mpd.lua script provides us with updates from our mpd client regarding ( song name, album name, player status, volume, random/loop enabled ). The script uses mpc ( command line client for MPD player ) to read the status of MPD player.

To get subscribed to events of MPD player, we use the mpc idleloop. Thus on any event ( song change, volume up, pause ) we get some feedback over which we can implement some action based on the event that occoured.

There are 3 signals being generated by the mpd.lua ( song status , volume status , options status ). I basically use the first one only ( song status ), but you can also use the other two to get subscribed about the volume and option updates as well.


Making Widgets

Now that we have configured our daemons, our next task is to make widgets for displaying the information provided to us. Our widgets will depend upon these daemons to update their state and change themselves based on subscribed events.

There are 5 widgets we are going to make :

  1. moe.lua
  2. spotify_song.lua
  3. spotify_buttons.lua
  4. mpd_song.lua
  5. mpd_buttons.lua

moe.lua

<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>naughty</span> <span>=</span> <span>require</span><span>(</span><span>"naughty"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>local</span> <span>default_image</span> <span>=</span> <span>os.getenv</span><span>(</span><span>"HOME"</span><span>)</span><span>..</span><span>".config/awesome/default.jpg"</span>
<span>local</span> <span>moe_playing_colors</span> <span>=</span> <span>{</span>
<span>x</span><span>.</span><span>color7</span><span>,</span>
<span>x</span><span>.</span><span>color8</span><span>,</span>
<span>x</span><span>.</span><span>color9</span><span>,</span>
<span>x</span><span>.</span><span>color10</span><span>,</span>
<span>x</span><span>.</span><span>color11</span><span>,</span>
<span>x</span><span>.</span><span>color12</span><span>,</span>
<span>}</span>
<span>local</span> <span>moe_cover</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>imagebox</span><span>()</span>
<span>local</span> <span>moe_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>moe_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>moe_listeners_count</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>moe_play_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
<span>moe_play_icon</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons medium 30"</span>
<span>moe_play_icon</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>moe_play_icon</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>moe_listeners_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>moe_listeners_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color6</span><span>)</span>
<span>moe_listeners_icon</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons medium 27"</span>
<span>moe_listeners_icon</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>moe_listeners_icon</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>function</span> <span>toggle_icon</span><span>()</span>
<span>if</span> <span>moe_play_icon</span><span>.</span><span>text</span> <span>==</span> <span>""</span> <span>then</span>
<span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
<span>else</span>
<span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
<span>end</span>
<span>end</span>
<span>moe_play_icon</span><span>:</span><span>buttons</span><span>(</span>
<span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>toggle_icon</span><span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"moe"</span><span>)</span>
<span>end</span><span>)</span>
<span>))</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>moe_play_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>local</span> <span>moe_widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>-- Cover Image</span>
<span>{</span>
<span>{</span>
<span>{</span>
<span>image</span> <span>=</span> <span>default_image</span><span>,</span>
<span>clip_shape</span> <span>=</span> <span>helpers</span><span>.</span><span>rrect</span><span>(</span><span>dpi</span><span>(</span><span>16</span><span>)),</span>
<span>widget</span> <span>=</span> <span>moe_cover</span>
<span>},</span>
<span>halign</span> <span>=</span> <span>'center'</span><span>,</span>
<span>valign</span> <span>=</span> <span>'center'</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
<span>},</span>
<span>---shape = helpers.rrect(box_radius / 2),</span>
<span>---widget = wibox.container.background</span>
<span>height</span> <span>=</span> <span>dpi</span><span>(</span><span>250</span><span>),</span>
<span>width</span> <span>=</span> <span>dpi</span><span>(</span><span>250</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>constraint</span>
<span>},</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>10</span><span>)),</span>
<span>-- Title widget</span>
<span>{</span>
<span>{</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"MoeChan"</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>),</span>
<span>font</span> <span>=</span> <span>"sans medium 14"</span><span>,</span>
<span>widget</span> <span>=</span> <span>moe_title</span>
<span>},</span>
<span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>-- Artist widget</span>
<span>{</span>
<span>{</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>text</span> <span>=</span> <span>"unavailable"</span><span>,</span>
<span>font</span> <span>=</span> <span>"sans medium 12"</span><span>,</span>
<span>widget</span> <span>=</span> <span>moe_artist</span>
<span>},</span>
<span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>5</span><span>)),</span>
<span>{</span>
<span>{</span>
<span>-- play icon</span>
<span>{</span>
<span>moe_play_icon</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>},</span>
<span>helpers</span><span>.</span><span>horizontal_pad</span><span>(</span><span>dpi</span><span>(</span><span>70</span><span>)),</span>
<span>-- headphone icon</span>
<span>{</span>
<span>moe_listeners_icon</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span><span>,</span>
<span>},</span>
<span>-- listener count</span>
<span>{</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>text</span> <span>=</span> <span>""</span><span>,</span>
<span>font</span> <span>=</span> <span>"sans medium 12"</span><span>,</span>
<span>widget</span> <span>=</span> <span>moe_listeners_count</span>
<span>},</span>
<span>spacing</span> <span>=</span> <span>10</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>},</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
<span>},</span>
<span>spacing</span> <span>=</span> <span>4</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::moe"</span><span>,</span> <span>function</span><span>(</span><span>count</span> <span>,</span><span>cover</span><span>,</span> <span>title</span><span>,</span> <span>artist</span><span>)</span>
<span>if</span> <span>tostring</span><span>(</span><span>cover</span><span>)</span> <span>==</span> <span>"!Available"</span> <span>then</span>
<span>moe_cover</span><span>.</span><span>image</span> <span>=</span> <span>default_image</span>
<span>else</span>
<span>moe_cover</span><span>.</span><span>image</span> <span>=</span> <span>os.getenv</span><span>(</span><span>"HOME"</span><span>)</span><span>..</span><span>"/projects/"</span><span>..</span><span>cover</span>
<span>end</span>
<span>moe_title</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>title</span><span>,</span> <span>moe_playing_colors</span><span>[</span><span>math.random</span><span>(</span><span>6</span><span>)])</span>
<span>moe_artist</span><span>.</span><span>text</span> <span>=</span> <span>artist</span>
<span>moe_listeners_count</span><span>.</span><span>text</span> <span>=</span> <span>tostring</span><span>(</span><span>count</span><span>)</span>
<span>naughty</span><span>.</span><span>notify</span><span>({</span> <span>title</span> <span>=</span> <span>"Moe | Now Playing"</span><span>,</span> <span>message</span> <span>=</span> <span>title</span><span>..</span><span>" by "</span><span>..</span><span>artist</span> <span>})</span>
<span>end</span><span>)</span>
<span>return</span> <span>moe_widget</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>naughty</span> <span>=</span> <span>require</span><span>(</span><span>"naughty"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>

<span>local</span> <span>default_image</span> <span>=</span> <span>os.getenv</span><span>(</span><span>"HOME"</span><span>)</span><span>..</span><span>".config/awesome/default.jpg"</span>

<span>local</span> <span>moe_playing_colors</span> <span>=</span> <span>{</span>
    <span>x</span><span>.</span><span>color7</span><span>,</span>
    <span>x</span><span>.</span><span>color8</span><span>,</span>
    <span>x</span><span>.</span><span>color9</span><span>,</span>
    <span>x</span><span>.</span><span>color10</span><span>,</span>
    <span>x</span><span>.</span><span>color11</span><span>,</span>
    <span>x</span><span>.</span><span>color12</span><span>,</span>
<span>}</span>

<span>local</span> <span>moe_cover</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>imagebox</span><span>()</span>
<span>local</span> <span>moe_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>moe_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>moe_listeners_count</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>

<span>local</span> <span>moe_play_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
<span>moe_play_icon</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons medium 30"</span>
<span>moe_play_icon</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>moe_play_icon</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>

<span>local</span> <span>moe_listeners_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>moe_listeners_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color6</span><span>)</span>
<span>moe_listeners_icon</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons medium 27"</span>
<span>moe_listeners_icon</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>moe_listeners_icon</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>

<span>local</span> <span>function</span> <span>toggle_icon</span><span>()</span>
    <span>if</span> <span>moe_play_icon</span><span>.</span><span>text</span> <span>==</span> <span>""</span> <span>then</span>
      <span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
    <span>else</span>
      <span>moe_play_icon</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>)</span>
    <span>end</span>
<span>end</span>

<span>moe_play_icon</span><span>:</span><span>buttons</span><span>(</span>
    <span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
        <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
            <span>toggle_icon</span><span>()</span>
            <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"moe"</span><span>)</span>
        <span>end</span><span>)</span>
<span>))</span>

<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>moe_play_icon</span><span>,</span> <span>"hand1"</span><span>)</span>


<span>local</span> <span>moe_widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>-- Cover Image</span>
    <span>{</span>
        <span>{</span>
            <span>{</span>
                <span>image</span> <span>=</span> <span>default_image</span><span>,</span>
                <span>clip_shape</span> <span>=</span> <span>helpers</span><span>.</span><span>rrect</span><span>(</span><span>dpi</span><span>(</span><span>16</span><span>)),</span>
                <span>widget</span> <span>=</span> <span>moe_cover</span>
            <span>},</span>
            <span>halign</span> <span>=</span> <span>'center'</span><span>,</span>
            <span>valign</span> <span>=</span> <span>'center'</span><span>,</span>
            <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
         <span>},</span>
      <span>---shape = helpers.rrect(box_radius / 2),</span>
      <span>---widget = wibox.container.background</span>
     <span>height</span> <span>=</span> <span>dpi</span><span>(</span><span>250</span><span>),</span>
     <span>width</span> <span>=</span> <span>dpi</span><span>(</span><span>250</span><span>),</span>
     <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>constraint</span>
    <span>},</span>
    <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>10</span><span>)),</span>
    <span>-- Title widget</span>
    <span>{</span>
        <span>{</span>
            <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
            <span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"MoeChan"</span><span>,</span> <span>x</span><span>.</span><span>color4</span><span>),</span>
            <span>font</span> <span>=</span> <span>"sans medium 14"</span><span>,</span>
            <span>widget</span> <span>=</span> <span>moe_title</span>
        <span>},</span>
        <span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
        <span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
        <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
    <span>},</span>
    <span>-- Artist widget</span>
    <span>{</span>
        <span>{</span>
            <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
            <span>text</span> <span>=</span> <span>"unavailable"</span><span>,</span>
            <span>font</span> <span>=</span> <span>"sans medium 12"</span><span>,</span>
            <span>widget</span> <span>=</span> <span>moe_artist</span>
        <span>},</span>
        <span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
        <span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
        <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
    <span>},</span>
    <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>5</span><span>)),</span>
    <span>{</span>
        <span>{</span>
        <span>-- play icon</span>
            <span>{</span>
                <span>moe_play_icon</span><span>,</span>
                <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
            <span>},</span>
            <span>helpers</span><span>.</span><span>horizontal_pad</span><span>(</span><span>dpi</span><span>(</span><span>70</span><span>)),</span>
        <span>-- headphone icon</span>
            <span>{</span>
                <span>moe_listeners_icon</span><span>,</span>
                <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span><span>,</span>
            <span>},</span>
        <span>-- listener count</span>
            <span>{</span>
                <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
                <span>text</span> <span>=</span> <span>""</span><span>,</span>
                <span>font</span> <span>=</span> <span>"sans medium 12"</span><span>,</span>
                <span>widget</span> <span>=</span> <span>moe_listeners_count</span>
            <span>},</span>
            <span>spacing</span> <span>=</span> <span>10</span><span>,</span>
            <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
        <span>},</span>
        <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
        <span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
        <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
    <span>},</span>
    <span>spacing</span> <span>=</span> <span>4</span><span>,</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>

<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::moe"</span><span>,</span> <span>function</span><span>(</span><span>count</span> <span>,</span><span>cover</span><span>,</span> <span>title</span><span>,</span> <span>artist</span><span>)</span>
    <span>if</span> <span>tostring</span><span>(</span><span>cover</span><span>)</span> <span>==</span> <span>"!Available"</span> <span>then</span>
      <span>moe_cover</span><span>.</span><span>image</span> <span>=</span> <span>default_image</span>    
    <span>else</span>
      <span>moe_cover</span><span>.</span><span>image</span> <span>=</span> <span>os.getenv</span><span>(</span><span>"HOME"</span><span>)</span><span>..</span><span>"/projects/"</span><span>..</span><span>cover</span>
    <span>end</span>
    <span>moe_title</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>title</span><span>,</span> <span>moe_playing_colors</span><span>[</span><span>math.random</span><span>(</span><span>6</span><span>)])</span>
    <span>moe_artist</span><span>.</span><span>text</span> <span>=</span> <span>artist</span>
    <span>moe_listeners_count</span><span>.</span><span>text</span> <span>=</span> <span>tostring</span><span>(</span><span>count</span><span>)</span>
    <span>naughty</span><span>.</span><span>notify</span><span>({</span> <span>title</span> <span>=</span> <span>"Moe | Now Playing"</span><span>,</span> <span>message</span> <span>=</span> <span>title</span><span>..</span><span>" by "</span><span>..</span><span>artist</span> <span>})</span>
<span>end</span><span>)</span>

<span>return</span> <span>moe_widget</span>
local awful = require("awful") local wibox = require("wibox") local naughty = require("naughty") local helpers = require("helpers") local default_image = os.getenv("HOME")..".config/awesome/default.jpg" local moe_playing_colors = { x.color7, x.color8, x.color9, x.color10, x.color11, x.color12, } local moe_cover = wibox.widget.imagebox() local moe_title = wibox.widget.textbox() local moe_artist = wibox.widget.textbox() local moe_listeners_count = wibox.widget.textbox() local moe_play_icon = wibox.widget.textbox() moe_play_icon.markup = helpers.colorize_text("", x.color4) moe_play_icon.font = "Material Icons medium 30" moe_play_icon.align = "center" moe_play_icon.valign = "center" local moe_listeners_icon = wibox.widget.textbox() moe_listeners_icon.markup = helpers.colorize_text("", x.color6) moe_listeners_icon.font = "Material Icons medium 27" moe_listeners_icon.align = "center" moe_listeners_icon.valign = "center" local function toggle_icon() if moe_play_icon.text == "" then moe_play_icon.markup = helpers.colorize_text("", x.color4) else moe_play_icon.markup = helpers.colorize_text("", x.color4) end end moe_play_icon:buttons( gears.table.join( awful.button({ }, 1, function () toggle_icon() awful.spawn.with_shell("moe") end) )) helpers.add_hover_cursor(moe_play_icon, "hand1") local moe_widget = wibox.widget { -- Cover Image { { { image = default_image, clip_shape = helpers.rrect(dpi(16)), widget = moe_cover }, halign = 'center', valign = 'center', layout = wibox.container.place }, ---shape = helpers.rrect(box_radius / 2), ---widget = wibox.container.background height = dpi(250), width = dpi(250), layout = wibox.container.constraint }, helpers.vertical_pad(dpi(10)), -- Title widget { { align = "center", markup = helpers.colorize_text("MoeChan", x.color4), font = "sans medium 14", widget = moe_title }, left = dpi(20), right = dpi(20), widget = wibox.container.margin }, -- Artist widget { { align = "center", text = "unavailable", font = "sans medium 12", widget = moe_artist }, left = dpi(20), right = dpi(20), widget = wibox.container.margin }, helpers.vertical_pad(dpi(5)), { { -- play icon { moe_play_icon, widget = wibox.container.background }, helpers.horizontal_pad(dpi(70)), -- headphone icon { moe_listeners_icon, widget = wibox.container.background, }, -- listener count { align = "center", text = "", font = "sans medium 12", widget = moe_listeners_count }, spacing = 10, widget = wibox.layout.fixed.horizontal }, align = "center", valign = "center", widget = wibox.container.place }, spacing = 4, layout = wibox.layout.fixed.vertical } awesome.connect_signal("daemon::moe", function(count ,cover, title, artist) if tostring(cover) == "!Available" then moe_cover.image = default_image else moe_cover.image = os.getenv("HOME").."/projects/"..cover end moe_title.markup = helpers.colorize_text(title, moe_playing_colors[math.random(6)]) moe_artist.text = artist moe_listeners_count.text = tostring(count) naughty.notify({ title = "Moe | Now Playing", message = title.." by "..artist }) end) return moe_widget

Enter fullscreen mode Exit fullscreen mode

moe.lua returns the listen.moe widget for the musicbar. The libraries include :

  • awful -> For buttons and spawning processes.
  • wibox -> The main widget box library.
  • naughty -> The notification library.
  • helpers -> The user defined helper library.

The file consists of moe_playing_colors which are essentially theme colors taken from xrdb and are defined in rc.lua ( later in this post ). Alongside we have a local variable default image which is basically a image that is put in place of cover image if it’s not available.

Next we have created 1 imagebox and 4 textbox for imagecover, song title, artist title, play icon and listener count.

moe_play_icon:buttons control the action when the icon is clicked. When it does, it fires a shell script ‘moe’ ( defined below ) which plays the music from listen.moe using mpv player as a background process.

You can either install the fonts defined in {textbox}.font or change them according to your preference.

moe_widget is our main listen.moe widget which consists of all individual wibox widgets ( cover image, song title, artist title, play icon, listeners count ).

For subscribing to the daemon updates ( daemon/moe.lua ), we use the awesome.connect_signal and based on the information update our widget state.

Additionaly the shell script moe :

<span>#!/bin/sh</span>
<span>moe</span><span>=</span><span>"https://listen.moe/stream"</span>
pkill <span>-f</span> <span>$moe</span> <span>||</span> mpv <span>"</span><span>$moe</span><span>"</span>
<span>#!/bin/sh</span>

<span>moe</span><span>=</span><span>"https://listen.moe/stream"</span>

pkill <span>-f</span> <span>$moe</span> <span>||</span> mpv <span>"</span><span>$moe</span><span>"</span>
#!/bin/sh moe="https://listen.moe/stream" pkill -f $moe || mpv "$moe"

Enter fullscreen mode Exit fullscreen mode

Keep in mind you need to add this script to your path to make it available everywhere.


spotify_song.lua

<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>-- Declare widgets</span>
<span>local</span> <span>spotify_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>spotify_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>-- Main widget that includes all others</span>
<span>local</span> <span>spotify_widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>-- Title widget</span>
<span>{</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>text</span> <span>=</span> <span>"Spotify"</span><span>,</span>
<span>font</span> <span>=</span> <span>"sans 14"</span><span>,</span>
<span>widget</span> <span>=</span> <span>spotify_title</span>
<span>},</span>
<span>-- Artist widget</span>
<span>{</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>text</span> <span>=</span> <span>"unavailable"</span><span>,</span>
<span>font</span> <span>=</span> <span>"sans 10"</span><span>,</span>
<span>widget</span> <span>=</span> <span>spotify_artist</span>
<span>},</span>
<span>spacing</span> <span>=</span> <span>2</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>
<span>-- Subcribe to spotify updates</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
<span>-- Do whatever you want with artist, title, status</span>
<span>-- ...</span>
<span>spotify_artist</span><span>.</span><span>text</span> <span>=</span> <span>artist</span>
<span>spotify_title</span><span>.</span><span>text</span> <span>=</span> <span>title</span>
<span>-- Example notification (might not be needed if spotify already sends one)</span>
<span>-- if status == "playing" then</span>
<span>-- naughty.notify({ title = "Spotify | Now Playing", message= title.." by "..artist })</span>
<span>-- end</span>
<span>end</span><span>)</span>
<span>return</span> <span>spotify_widget</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>

<span>-- Declare widgets</span>
<span>local</span> <span>spotify_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>local</span> <span>spotify_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>

<span>-- Main widget that includes all others</span>
<span>local</span> <span>spotify_widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>-- Title widget</span>
    <span>{</span>
        <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
        <span>text</span> <span>=</span> <span>"Spotify"</span><span>,</span>
        <span>font</span> <span>=</span> <span>"sans 14"</span><span>,</span>
        <span>widget</span> <span>=</span> <span>spotify_title</span>
    <span>},</span>
    <span>-- Artist widget</span>
    <span>{</span>
        <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
        <span>text</span> <span>=</span> <span>"unavailable"</span><span>,</span>
        <span>font</span> <span>=</span> <span>"sans 10"</span><span>,</span>
        <span>widget</span> <span>=</span> <span>spotify_artist</span>
    <span>},</span>
    <span>spacing</span> <span>=</span> <span>2</span><span>,</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>

<span>-- Subcribe to spotify updates</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
    <span>-- Do whatever you want with artist, title, status</span>
    <span>-- ...</span>
    <span>spotify_artist</span><span>.</span><span>text</span> <span>=</span> <span>artist</span>
    <span>spotify_title</span><span>.</span><span>text</span> <span>=</span> <span>title</span>

    <span>-- Example notification (might not be needed if spotify already sends one)</span>
    <span>-- if status == "playing" then</span>
    <span>-- naughty.notify({ title = "Spotify | Now Playing", message= title.." by "..artist })</span>
    <span>-- end</span>
<span>end</span><span>)</span>

<span>return</span> <span>spotify_widget</span>
local wibox = require("wibox") -- Declare widgets local spotify_artist = wibox.widget.textbox() local spotify_title = wibox.widget.textbox() -- Main widget that includes all others local spotify_widget = wibox.widget { -- Title widget { align = "center", text = "Spotify", font = "sans 14", widget = spotify_title }, -- Artist widget { align = "center", text = "unavailable", font = "sans 10", widget = spotify_artist }, spacing = 2, layout = wibox.layout.fixed.vertical } -- Subcribe to spotify updates awesome.connect_signal("daemon::spotify", function(artist, title, status) -- Do whatever you want with artist, title, status -- ... spotify_artist.text = artist spotify_title.text = title -- Example notification (might not be needed if spotify already sends one) -- if status == "playing" then -- naughty.notify({ title = "Spotify | Now Playing", message= title.." by "..artist }) -- end end) return spotify_widget

Enter fullscreen mode Exit fullscreen mode

spotify.lua returns the spotify song widget which contains the song artist and song title.

The code is very much similar to moe.lua widget except that here we are connecting to the daemon::spotify signal.

Since spotify already notifies us about song changes i do not like receiving extra notification, thus i commented out the notification line in awesome.connect_signal. This is just to avoid getting 2 notifications.


spotify_buttons.lua

<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>local</span> <span>spotify_prev_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>spotify_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"≪"</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>spotify_prev_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>spotify_prev_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>spotify_prev_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>spotify_next_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>spotify_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"≫"</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>spotify_next_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>spotify_next_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>spotify_next_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>-- local note_symbol = ""</span>
<span>-- local note_symbol = ""</span>
<span>local</span> <span>note_symbol</span> <span>=</span> <span>"ッ"</span>
<span>local</span> <span>big_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>big_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 17"</span>
<span>big_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>local</span> <span>small_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>small_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span><span>)</span>
<span>small_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 13"</span>
<span>-- small_note.valign = "bottom"</span>
<span>local</span> <span>double_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>big_note</span><span>,</span>
<span>-- small_note,</span>
<span>{</span>
<span>small_note</span><span>,</span>
<span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>11</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>-</span><span>5</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>}</span>
<span>local</span> <span>spotify_toggle_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>double_note</span><span>,</span>
<span>-- bg = "#00000000",</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_toggle_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify play-pause"</span><span>)</span>
<span>end</span><span>)</span>
<span>))</span>
<span>local</span> <span>spotify_prev_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>spotify_prev_symbol</span><span>,</span>
<span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_prev_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify previous"</span><span>)</span>
<span>end</span><span>)</span>
<span>))</span>
<span>local</span> <span>spotify_next_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>spotify_next_symbol</span><span>,</span>
<span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_next_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify next"</span><span>)</span>
<span>end</span><span>)</span>
<span>))</span>
<span>local</span> <span>music_playing_colors</span> <span>=</span> <span>{</span>
<span>x</span><span>.</span><span>color1</span><span>,</span>
<span>x</span><span>.</span><span>color2</span><span>,</span>
<span>x</span><span>.</span><span>color3</span><span>,</span>
<span>x</span><span>.</span><span>color4</span><span>,</span>
<span>x</span><span>.</span><span>color5</span><span>,</span>
<span>x</span><span>.</span><span>color6</span><span>,</span>
<span>}</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
<span>local</span> <span>accent</span><span>,</span> <span>small_note_color</span>
<span>if</span> <span>string.lower</span><span>(</span><span>status</span><span>)</span> <span>==</span> <span>"paused"</span> <span>then</span>
<span>accent</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span>
<span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span>
<span>else</span>
<span>accent</span> <span>=</span> <span>music_playing_colors</span><span>[</span><span>math.random</span><span>(</span><span>6</span><span>)]</span>
<span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span>
<span>end</span>
<span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>accent</span><span>)</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>small_note_color</span><span>)</span>
<span>spotify_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>spotify_prev_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>spotify_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>spotify_next_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>end</span><span>)</span>
<span>local</span> <span>spotify_buttons</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>nil</span><span>,</span>
<span>{</span>
<span>spotify_prev_icon</span><span>,</span>
<span>spotify_toggle_icon</span><span>,</span>
<span>spotify_next_icon</span><span>,</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>14</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>},</span>
<span>expand</span> <span>=</span> <span>"none"</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>align</span><span>.</span><span>horizontal</span><span>,</span>
<span>}</span>
<span>-- Add clickable mouse effects on some widgets</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_next_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_prev_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_toggle_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>return</span> <span>spotify_buttons</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>

<span>local</span> <span>spotify_prev_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>spotify_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"≪"</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>spotify_prev_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>spotify_prev_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>spotify_prev_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>spotify_next_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>spotify_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>"≫"</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>spotify_next_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>spotify_next_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>spotify_next_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>

<span>-- local note_symbol = ""</span>
<span>-- local note_symbol = ""</span>
<span>local</span> <span>note_symbol</span> <span>=</span> <span>"ッ"</span>
<span>local</span> <span>big_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>big_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 17"</span>
<span>big_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span><span>)</span>
<span>local</span> <span>small_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>small_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span><span>)</span>
<span>small_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 13"</span>
<span>-- small_note.valign = "bottom"</span>
<span>local</span> <span>double_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>big_note</span><span>,</span>
    <span>-- small_note,</span>
    <span>{</span>
        <span>small_note</span><span>,</span>
        <span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>11</span><span>),</span>
        <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
    <span>},</span>
    <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>-</span><span>5</span><span>),</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>}</span>

<span>local</span> <span>spotify_toggle_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>double_note</span><span>,</span>
    <span>-- bg = "#00000000",</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_toggle_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify play-pause"</span><span>)</span>
    <span>end</span><span>)</span>
<span>))</span>

<span>local</span> <span>spotify_prev_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>spotify_prev_symbol</span><span>,</span>
    <span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_prev_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify previous"</span><span>)</span>
    <span>end</span><span>)</span>
<span>))</span>

<span>local</span> <span>spotify_next_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>spotify_next_symbol</span><span>,</span>
    <span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>spotify_next_icon</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"playerctl --player spotify next"</span><span>)</span>
    <span>end</span><span>)</span>
<span>))</span>

<span>local</span> <span>music_playing_colors</span> <span>=</span> <span>{</span>
    <span>x</span><span>.</span><span>color1</span><span>,</span>
    <span>x</span><span>.</span><span>color2</span><span>,</span>
    <span>x</span><span>.</span><span>color3</span><span>,</span>
    <span>x</span><span>.</span><span>color4</span><span>,</span>
    <span>x</span><span>.</span><span>color5</span><span>,</span>
    <span>x</span><span>.</span><span>color6</span><span>,</span>
<span>}</span>

<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::spotify"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
    <span>local</span> <span>accent</span><span>,</span> <span>small_note_color</span>
    <span>if</span> <span>string.lower</span><span>(</span><span>status</span><span>)</span> <span>==</span> <span>"paused"</span> <span>then</span>
        <span>accent</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span>
        <span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span>
    <span>else</span>
        <span>accent</span> <span>=</span> <span>music_playing_colors</span><span>[</span><span>math.random</span><span>(</span><span>6</span><span>)]</span>
        <span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span>
    <span>end</span>

    <span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>accent</span><span>)</span>
    <span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>small_note_color</span><span>)</span>

    <span>spotify_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>spotify_prev_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
    <span>spotify_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>spotify_next_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>end</span><span>)</span>

<span>local</span> <span>spotify_buttons</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>nil</span><span>,</span>
    <span>{</span>
        <span>spotify_prev_icon</span><span>,</span>
        <span>spotify_toggle_icon</span><span>,</span>
        <span>spotify_next_icon</span><span>,</span>
        <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>14</span><span>),</span>
        <span>layout</span>  <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
    <span>},</span>
    <span>expand</span> <span>=</span> <span>"none"</span><span>,</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>align</span><span>.</span><span>horizontal</span><span>,</span>
<span>}</span>

<span>-- Add clickable mouse effects on some widgets</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_next_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_prev_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>spotify_toggle_icon</span><span>,</span> <span>"hand1"</span><span>)</span>

<span>return</span> <span>spotify_buttons</span>
local gears = require("gears") local awful = require("awful") local wibox = require("wibox") local helpers = require("helpers") local spotify_prev_symbol = wibox.widget.textbox() spotify_prev_symbol.markup = helpers.colorize_text("≪", x.foreground.."33") spotify_prev_symbol.font = "Material Icons Bold 18" spotify_prev_symbol.align = "center" spotify_prev_symbol.valign = "center" local spotify_next_symbol = wibox.widget.textbox() spotify_next_symbol.markup = helpers.colorize_text("≫", x.foreground.."33") spotify_next_symbol.font = "Material Icons Bold 18" spotify_next_symbol.align = "center" spotify_next_symbol.valign = "center" -- local note_symbol = "" -- local note_symbol = "" local note_symbol = "ッ" local big_note = wibox.widget.textbox() big_note.font = "Material Icons Bold 17" big_note.align = "center" big_note.markup = helpers.colorize_text(note_symbol, x.foreground.."33") local small_note = wibox.widget.textbox() small_note.align = "center" small_note.markup = helpers.colorize_text(note_symbol, x.foreground.."55") small_note.font = "Material Icons Bold 13" -- small_note.valign = "bottom" local double_note = wibox.widget { big_note, -- small_note, { small_note, top = dpi(11), widget = wibox.container.margin }, spacing = dpi(-5), layout = wibox.layout.fixed.horizontal } local spotify_toggle_icon = wibox.widget { double_note, -- bg = "#00000000", widget = wibox.container.background } spotify_toggle_icon:buttons(gears.table.join( awful.button({ }, 1, function () awful.spawn.with_shell("playerctl --player spotify play-pause") end) )) local spotify_prev_icon = wibox.widget { spotify_prev_symbol, shape = gears.shape.circle, widget = wibox.container.background } spotify_prev_icon:buttons(gears.table.join( awful.button({ }, 1, function () awful.spawn.with_shell("playerctl --player spotify previous") end) )) local spotify_next_icon = wibox.widget { spotify_next_symbol, shape = gears.shape.circle, widget = wibox.container.background } spotify_next_icon:buttons(gears.table.join( awful.button({ }, 1, function () awful.spawn.with_shell("playerctl --player spotify next") end) )) local music_playing_colors = { x.color1, x.color2, x.color3, x.color4, x.color5, x.color6, } awesome.connect_signal("daemon::spotify", function(artist, title, status) local accent, small_note_color if string.lower(status) == "paused" then accent = x.foreground.."33" small_note_color = x.foreground.."55" else accent = music_playing_colors[math.random(6)] small_note_color = x.foreground end big_note.markup = helpers.colorize_text(note_symbol, accent) small_note.markup = helpers.colorize_text(note_symbol, small_note_color) spotify_prev_symbol.markup = helpers.colorize_text(spotify_prev_symbol.text, accent) spotify_next_symbol.markup = helpers.colorize_text(spotify_next_symbol.text, accent) end) local spotify_buttons = wibox.widget { nil, { spotify_prev_icon, spotify_toggle_icon, spotify_next_icon, spacing = dpi(14), layout = wibox.layout.fixed.horizontal }, expand = "none", layout = wibox.layout.align.horizontal, } -- Add clickable mouse effects on some widgets helpers.add_hover_cursor(spotify_next_icon, "hand1") helpers.add_hover_cursor(spotify_prev_icon, "hand1") helpers.add_hover_cursor(spotify_toggle_icon, "hand1") return spotify_buttons

Enter fullscreen mode Exit fullscreen mode

spotify_buttons.lua contains the buttons for controlling the spotify directly from your musicbar.

The play/pause, previous, next icons are binded to certain action. The playerctl utility is the tool which is used for carrying out these actions ( pause/play, next song, previous song ).

The color of the icons changes when a song is playing. The colors are randomly picked from an array music_playing_colors.


mpd_song.lua

<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>-- Set colors</span>
<span>local</span> <span>title_color</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>local</span> <span>artist_color</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>local</span> <span>paused_color</span> <span>=</span> <span>x</span><span>.</span><span>color8</span>
<span>local</span> <span>mpd_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
<span>text</span> <span>=</span> <span>"---------"</span><span>,</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span>
<span>}</span>
<span>local</span> <span>mpd_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
<span>text</span> <span>=</span> <span>"---------"</span><span>,</span>
<span>align</span> <span>=</span> <span>"center"</span><span>,</span>
<span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span>
<span>}</span>
<span>-- Main widget</span>
<span>local</span> <span>mpd_song</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
<span>mpd_title</span><span>,</span>
<span>mpd_artist</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>
<span>local</span> <span>artist_fg</span>
<span>local</span> <span>artist_bg</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
<span>if</span> <span>status</span> <span>==</span> <span>"paused"</span> <span>then</span>
<span>artist_fg</span> <span>=</span> <span>paused_color</span>
<span>title_fg</span> <span>=</span> <span>paused_color</span>
<span>else</span>
<span>artist_fg</span> <span>=</span> <span>artist_color</span>
<span>title_fg</span> <span>=</span> <span>title_color</span>
<span>end</span>
<span>-- Escape &'s</span>
<span>title</span> <span>=</span> <span>string.gsub</span><span>(</span><span>title</span><span>,</span> <span>"&"</span><span>,</span> <span>"&amp;"</span><span>)</span>
<span>artist</span> <span>=</span> <span>string.gsub</span><span>(</span><span>artist</span><span>,</span> <span>"&"</span><span>,</span> <span>"&amp;"</span><span>)</span>
<span>mpd_title</span><span>.</span><span>markup</span> <span>=</span>
<span>"<span foreground='"</span> <span>..</span> <span>title_fg</span> <span>..</span><span>"'>"</span>
<span>..</span> <span>title</span> <span>..</span> <span>"</span>"</span>
<span>mpd_artist</span><span>.</span><span>markup</span> <span>=</span>
<span>"<span foreground='"</span> <span>..</span> <span>artist_fg</span> <span>..</span><span>"'>"</span>
<span>..</span> <span>artist</span> <span>..</span> <span>"</span>"</span>
<span>end</span><span>)</span>
<span>return</span> <span>mpd_song</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>

<span>-- Set colors</span>
<span>local</span> <span>title_color</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>local</span> <span>artist_color</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>local</span> <span>paused_color</span> <span>=</span> <span>x</span><span>.</span><span>color8</span>

<span>local</span> <span>mpd_title</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
    <span>text</span> <span>=</span> <span>"---------"</span><span>,</span>
    <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
    <span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span>
<span>}</span>

<span>local</span> <span>mpd_artist</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
    <span>text</span> <span>=</span> <span>"---------"</span><span>,</span>
    <span>align</span> <span>=</span> <span>"center"</span><span>,</span>
    <span>valign</span> <span>=</span> <span>"center"</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span>
<span>}</span>

<span>-- Main widget</span>
<span>local</span> <span>mpd_song</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>{</span>
    <span>mpd_title</span><span>,</span>
    <span>mpd_artist</span><span>,</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>}</span>

<span>local</span> <span>artist_fg</span>
<span>local</span> <span>artist_bg</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>status</span><span>)</span>
    <span>if</span> <span>status</span> <span>==</span> <span>"paused"</span> <span>then</span>
        <span>artist_fg</span> <span>=</span> <span>paused_color</span>
        <span>title_fg</span> <span>=</span> <span>paused_color</span>
    <span>else</span>
        <span>artist_fg</span> <span>=</span> <span>artist_color</span>
        <span>title_fg</span> <span>=</span> <span>title_color</span>
    <span>end</span>

    <span>-- Escape &'s</span>
    <span>title</span> <span>=</span> <span>string.gsub</span><span>(</span><span>title</span><span>,</span> <span>"&"</span><span>,</span> <span>"&amp;"</span><span>)</span>
    <span>artist</span> <span>=</span> <span>string.gsub</span><span>(</span><span>artist</span><span>,</span> <span>"&"</span><span>,</span> <span>"&amp;"</span><span>)</span>

    <span>mpd_title</span><span>.</span><span>markup</span> <span>=</span>
        <span>"<span foreground='"</span> <span>..</span> <span>title_fg</span> <span>..</span><span>"'>"</span>
        <span>..</span> <span>title</span> <span>..</span> <span>"</span>"</span>
    <span>mpd_artist</span><span>.</span><span>markup</span> <span>=</span>
        <span>"<span foreground='"</span> <span>..</span> <span>artist_fg</span> <span>..</span><span>"'>"</span>
        <span>..</span> <span>artist</span> <span>..</span> <span>"</span>"</span>
<span>end</span><span>)</span>

<span>return</span> <span>mpd_song</span>
local gears = require("gears") local wibox = require("wibox") -- Set colors local title_color = x.color7 local artist_color = x.color7 local paused_color = x.color8 local mpd_title = wibox.widget{ text = "---------", align = "center", valign = "center", widget = wibox.widget.textbox } local mpd_artist = wibox.widget{ text = "---------", align = "center", valign = "center", widget = wibox.widget.textbox } -- Main widget local mpd_song = wibox.widget{ mpd_title, mpd_artist, layout = wibox.layout.fixed.vertical } local artist_fg local artist_bg awesome.connect_signal("daemon::mpd", function(artist, title, status) if status == "paused" then artist_fg = paused_color title_fg = paused_color else artist_fg = artist_color title_fg = title_color end -- Escape &'s title = string.gsub(title, "&", "&amp;") artist = string.gsub(artist, "&", "&amp;") mpd_title.markup = "<span foreground='" .. title_fg .."'>" .. title .. "</span>" mpd_artist.markup = "<span foreground='" .. artist_fg .."'>" .. artist .. "</span>" end) return mpd_song

Enter fullscreen mode Exit fullscreen mode

mpd_song.lua returns us the widget for displaying songs playing through MPD. Most of this is similar to spotify_song.lua.

Here we are connecting to the daemon::mpd signal to receive the information about events we are subscribed to.


mpd_buttons.lua

<span>-- Text buttons for mpd control using "Material Design Icons" font</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>local</span> <span>mpd_prev_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>mpd_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>mpd_prev_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>mpd_prev_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>mpd_prev_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>mpd_next_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>mpd_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>mpd_next_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>mpd_next_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>mpd_next_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>note_symbol</span> <span>=</span> <span>""</span>
<span>local</span> <span>big_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>(</span><span>note_symbol</span><span>)</span>
<span>big_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 15"</span>
<span>big_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>small_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>small_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>small_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 11"</span>
<span>-- small_note.valign = "bottom"</span>
<span>local</span> <span>double_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>big_note</span><span>,</span>
<span>-- small_note,</span>
<span>{</span>
<span>small_note</span><span>,</span>
<span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>11</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>-</span><span>9</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>}</span>
<span>local</span> <span>mpd_toggle_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>double_note</span><span>,</span>
<span>-- bg = "#00000000",</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_toggle_icon</span><span>:</span><span>buttons</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q toggle"</span><span>)</span>
<span>end</span><span>)</span>
<span>)</span>
<span>local</span> <span>mpd_prev_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>mpd_prev_symbol</span><span>,</span>
<span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_prev_icon</span><span>:</span><span>buttons</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q prev"</span><span>)</span>
<span>end</span><span>)</span>
<span>)</span>
<span>local</span> <span>mpd_next_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>mpd_next_symbol</span><span>,</span>
<span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_next_icon</span><span>:</span><span>buttons</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q next"</span><span>)</span>
<span>end</span><span>)</span>
<span>)</span>
<span>local</span> <span>music_playing_counter</span> <span>=</span> <span>0</span>
<span>local</span> <span>last_artist</span>
<span>local</span> <span>last_title</span>
<span>local</span> <span>music_playing_colors</span> <span>=</span> <span>{</span>
<span>x</span><span>.</span><span>color1</span><span>,</span>
<span>x</span><span>.</span><span>color2</span><span>,</span>
<span>x</span><span>.</span><span>color3</span><span>,</span>
<span>x</span><span>.</span><span>color4</span><span>,</span>
<span>x</span><span>.</span><span>color5</span><span>,</span>
<span>x</span><span>.</span><span>color6</span><span>,</span>
<span>}</span>
<span>local</span> <span>last_color</span> <span>=</span> <span>music_playing_colors</span><span>[</span><span>1</span><span>]</span>
<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>paused</span><span>)</span>
<span>local</span> <span>accent</span><span>,</span> <span>small_note_color</span>
<span>if</span> <span>paused</span> <span>then</span>
<span>accent</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span>
<span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span>
<span>else</span>
<span>if</span> <span>artist</span> <span>~=</span> <span>last_artist</span> <span>and</span> <span>title</span> <span>~=</span> <span>last_title</span> <span>then</span>
<span>accent</span> <span>=</span> <span>music_playing_colors</span><span>[(</span><span>music_playing_counter</span> <span>%</span> <span>#</span><span>music_playing_colors</span><span>)</span> <span>+</span> <span>1</span><span>]</span>
<span>music_playing_counter</span> <span>=</span> <span>music_playing_counter</span> <span>+</span> <span>1</span>
<span>else</span>
<span>accent</span> <span>=</span> <span>last_color</span>
<span>end</span>
<span>last_artist</span> <span>=</span> <span>artist</span>
<span>last_title</span> <span>=</span> <span>title</span>
<span>last_color</span> <span>=</span> <span>accent</span>
<span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span>
<span>end</span>
<span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>accent</span><span>)</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>small_note_color</span><span>)</span>
<span>-- mpd_prev_icon.bg = accent</span>
<span>-- mpd_next_icon.bg = accent</span>
<span>mpd_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>mpd_prev_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>mpd_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>mpd_next_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>end</span><span>)</span>
<span>local</span> <span>mpd_buttons</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
<span>nil</span><span>,</span>
<span>{</span>
<span>mpd_prev_icon</span><span>,</span>
<span>mpd_toggle_icon</span><span>,</span>
<span>mpd_next_icon</span><span>,</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>14</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>},</span>
<span>expand</span> <span>=</span> <span>"none"</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>align</span><span>.</span><span>horizontal</span><span>,</span>
<span>}</span>
<span>-- Add clickable mouse effects on some widgets</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_next_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_prev_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_toggle_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>return</span> <span>mpd_buttons</span>
<span>-- Text buttons for mpd control using "Material Design Icons" font</span>
<span>local</span> <span>gears</span> <span>=</span> <span>require</span><span>(</span><span>"gears"</span><span>)</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>

<span>local</span> <span>mpd_prev_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>mpd_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>mpd_prev_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>mpd_prev_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>mpd_prev_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>mpd_next_symbol</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>mpd_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>""</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>mpd_next_symbol</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 18"</span>
<span>mpd_next_symbol</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>mpd_next_symbol</span><span>.</span><span>valign</span> <span>=</span> <span>"center"</span>

<span>local</span> <span>note_symbol</span> <span>=</span> <span>""</span>
<span>local</span> <span>big_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>(</span><span>note_symbol</span><span>)</span>
<span>big_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 15"</span>
<span>big_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>local</span> <span>small_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span><span>.</span><span>textbox</span><span>()</span>
<span>small_note</span><span>.</span><span>align</span> <span>=</span> <span>"center"</span>
<span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>x</span><span>.</span><span>foreground</span><span>)</span>
<span>small_note</span><span>.</span><span>font</span> <span>=</span> <span>"Material Icons Bold 11"</span>
<span>-- small_note.valign = "bottom"</span>
<span>local</span> <span>double_note</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>big_note</span><span>,</span>
    <span>-- small_note,</span>
    <span>{</span>
        <span>small_note</span><span>,</span>
        <span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>11</span><span>),</span>
        <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
    <span>},</span>
    <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>-</span><span>9</span><span>),</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
<span>}</span>

<span>local</span> <span>mpd_toggle_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>double_note</span><span>,</span>
    <span>-- bg = "#00000000",</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_toggle_icon</span><span>:</span><span>buttons</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q toggle"</span><span>)</span>
    <span>end</span><span>)</span>
<span>)</span>

<span>local</span> <span>mpd_prev_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>mpd_prev_symbol</span><span>,</span>
    <span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_prev_icon</span><span>:</span><span>buttons</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q prev"</span><span>)</span>
    <span>end</span><span>)</span>
<span>)</span>

<span>local</span> <span>mpd_next_icon</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>mpd_next_symbol</span><span>,</span>
    <span>shape</span> <span>=</span> <span>gears</span><span>.</span><span>shape</span><span>.</span><span>circle</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>mpd_next_icon</span><span>:</span><span>buttons</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q next"</span><span>)</span>
    <span>end</span><span>)</span>
<span>)</span>

<span>local</span> <span>music_playing_counter</span> <span>=</span> <span>0</span>
<span>local</span> <span>last_artist</span>
<span>local</span> <span>last_title</span>
<span>local</span> <span>music_playing_colors</span> <span>=</span> <span>{</span>
    <span>x</span><span>.</span><span>color1</span><span>,</span>
    <span>x</span><span>.</span><span>color2</span><span>,</span>
    <span>x</span><span>.</span><span>color3</span><span>,</span>
    <span>x</span><span>.</span><span>color4</span><span>,</span>
    <span>x</span><span>.</span><span>color5</span><span>,</span>
    <span>x</span><span>.</span><span>color6</span><span>,</span>
<span>}</span>
<span>local</span> <span>last_color</span> <span>=</span> <span>music_playing_colors</span><span>[</span><span>1</span><span>]</span>

<span>awesome</span><span>.</span><span>connect_signal</span><span>(</span><span>"daemon::mpd"</span><span>,</span> <span>function</span><span>(</span><span>artist</span><span>,</span> <span>title</span><span>,</span> <span>paused</span><span>)</span>
    <span>local</span> <span>accent</span><span>,</span> <span>small_note_color</span>
    <span>if</span> <span>paused</span> <span>then</span>
        <span>accent</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"33"</span>
        <span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span><span>..</span><span>"55"</span>
    <span>else</span>
        <span>if</span> <span>artist</span> <span>~=</span> <span>last_artist</span> <span>and</span> <span>title</span> <span>~=</span> <span>last_title</span> <span>then</span>
            <span>accent</span> <span>=</span> <span>music_playing_colors</span><span>[(</span><span>music_playing_counter</span> <span>%</span> <span>#</span><span>music_playing_colors</span><span>)</span> <span>+</span> <span>1</span><span>]</span>
            <span>music_playing_counter</span> <span>=</span> <span>music_playing_counter</span> <span>+</span> <span>1</span>
        <span>else</span>
            <span>accent</span> <span>=</span> <span>last_color</span>
        <span>end</span>
        <span>last_artist</span> <span>=</span> <span>artist</span>
        <span>last_title</span> <span>=</span> <span>title</span>
        <span>last_color</span> <span>=</span> <span>accent</span>
        <span>small_note_color</span> <span>=</span> <span>x</span><span>.</span><span>foreground</span>
    <span>end</span>

    <span>big_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>accent</span><span>)</span>
    <span>small_note</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>note_symbol</span><span>,</span> <span>small_note_color</span><span>)</span>
    <span>-- mpd_prev_icon.bg = accent</span>
    <span>-- mpd_next_icon.bg = accent</span>
    <span>mpd_prev_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>mpd_prev_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
    <span>mpd_next_symbol</span><span>.</span><span>markup</span> <span>=</span> <span>helpers</span><span>.</span><span>colorize_text</span><span>(</span><span>mpd_next_symbol</span><span>.</span><span>text</span><span>,</span> <span>accent</span><span>)</span>
<span>end</span><span>)</span>

<span>local</span> <span>mpd_buttons</span> <span>=</span> <span>wibox</span><span>.</span><span>widget</span> <span>{</span>
    <span>nil</span><span>,</span>
    <span>{</span>
        <span>mpd_prev_icon</span><span>,</span>
        <span>mpd_toggle_icon</span><span>,</span>
        <span>mpd_next_icon</span><span>,</span>
        <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>14</span><span>),</span>
        <span>layout</span>  <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>horizontal</span>
    <span>},</span>
    <span>expand</span> <span>=</span> <span>"none"</span><span>,</span>
    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>align</span><span>.</span><span>horizontal</span><span>,</span>
<span>}</span>

<span>-- Add clickable mouse effects on some widgets</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_next_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_prev_icon</span><span>,</span> <span>"hand1"</span><span>)</span>
<span>helpers</span><span>.</span><span>add_hover_cursor</span><span>(</span><span>mpd_toggle_icon</span><span>,</span> <span>"hand1"</span><span>)</span>

<span>return</span> <span>mpd_buttons</span>
-- Text buttons for mpd control using "Material Design Icons" font local gears = require("gears") local awful = require("awful") local wibox = require("wibox") local helpers = require("helpers") local mpd_prev_symbol = wibox.widget.textbox() mpd_prev_symbol.markup = helpers.colorize_text("", x.foreground) mpd_prev_symbol.font = "Material Icons Bold 18" mpd_prev_symbol.align = "center" mpd_prev_symbol.valign = "center" local mpd_next_symbol = wibox.widget.textbox() mpd_next_symbol.markup = helpers.colorize_text("", x.foreground) mpd_next_symbol.font = "Material Icons Bold 18" mpd_next_symbol.align = "center" mpd_next_symbol.valign = "center" local note_symbol = "" local big_note = wibox.widget.textbox(note_symbol) big_note.font = "Material Icons Bold 15" big_note.align = "center" local small_note = wibox.widget.textbox() small_note.align = "center" small_note.markup = helpers.colorize_text(note_symbol, x.foreground) small_note.font = "Material Icons Bold 11" -- small_note.valign = "bottom" local double_note = wibox.widget { big_note, -- small_note, { small_note, top = dpi(11), widget = wibox.container.margin }, spacing = dpi(-9), layout = wibox.layout.fixed.horizontal } local mpd_toggle_icon = wibox.widget { double_note, -- bg = "#00000000", widget = wibox.container.background } mpd_toggle_icon:buttons( awful.button({ }, 1, function () awful.spawn.with_shell("mpc -q toggle") end) ) local mpd_prev_icon = wibox.widget { mpd_prev_symbol, shape = gears.shape.circle, widget = wibox.container.background } mpd_prev_icon:buttons( awful.button({ }, 1, function () awful.spawn.with_shell("mpc -q prev") end) ) local mpd_next_icon = wibox.widget { mpd_next_symbol, shape = gears.shape.circle, widget = wibox.container.background } mpd_next_icon:buttons( awful.button({ }, 1, function () awful.spawn.with_shell("mpc -q next") end) ) local music_playing_counter = 0 local last_artist local last_title local music_playing_colors = { x.color1, x.color2, x.color3, x.color4, x.color5, x.color6, } local last_color = music_playing_colors[1] awesome.connect_signal("daemon::mpd", function(artist, title, paused) local accent, small_note_color if paused then accent = x.foreground.."33" small_note_color = x.foreground.."55" else if artist ~= last_artist and title ~= last_title then accent = music_playing_colors[(music_playing_counter % #music_playing_colors) + 1] music_playing_counter = music_playing_counter + 1 else accent = last_color end last_artist = artist last_title = title last_color = accent small_note_color = x.foreground end big_note.markup = helpers.colorize_text(note_symbol, accent) small_note.markup = helpers.colorize_text(note_symbol, small_note_color) -- mpd_prev_icon.bg = accent -- mpd_next_icon.bg = accent mpd_prev_symbol.markup = helpers.colorize_text(mpd_prev_symbol.text, accent) mpd_next_symbol.markup = helpers.colorize_text(mpd_next_symbol.text, accent) end) local mpd_buttons = wibox.widget { nil, { mpd_prev_icon, mpd_toggle_icon, mpd_next_icon, spacing = dpi(14), layout = wibox.layout.fixed.horizontal }, expand = "none", layout = wibox.layout.align.horizontal, } -- Add clickable mouse effects on some widgets helpers.add_hover_cursor(mpd_next_icon, "hand1") helpers.add_hover_cursor(mpd_prev_icon, "hand1") helpers.add_hover_cursor(mpd_toggle_icon, "hand1") return mpd_buttons

Enter fullscreen mode Exit fullscreen mode

mpd_buttons.lua returns the widget for button control for controlling you MPD client straight from musicbar. It has the same spotify_buttons.lua buttons.

However, one minor change in mpd_buttons.lua is that it keeps track of the last color used and thus doesn’t display same color twice in succession for the icons color.


Putting together the Musicbar

Now that we have finally configured all our daemons and widgets, it is finally time to assemble the full musicbar with these widgets and daemons.

The music bar is erected on the right side of my screen and pops out when i hover the mouse pointer over the right edge.

musicbar.lua

<span>-- modules</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>
<span>-- Moe</span>
<span>local</span> <span>moe</span> <span>=</span> <span>require</span><span>(</span><span>"widget.moe"</span><span>)</span>
<span>-- Spotify</span>
<span>local</span> <span>spotify_buttons</span> <span>=</span> <span>require</span><span>(</span><span>"widget.spotify_buttons"</span><span>)</span>
<span>local</span> <span>spotify</span> <span>=</span> <span>require</span><span>(</span><span>"widget.spotify"</span><span>)</span>
<span>local</span> <span>spotify_widget_children</span> <span>=</span> <span>spotify</span><span>:</span><span>get_all_children</span><span>()</span>
<span>local</span> <span>spotify_title</span> <span>=</span> <span>spotify_widget_children</span><span>[</span><span>1</span><span>]</span>
<span>local</span> <span>spotify_artist</span> <span>=</span> <span>spotify_widget_children</span><span>[</span><span>2</span><span>]</span>
<span>spotify_title</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>22</span><span>)</span>
<span>spotify_artist</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>16</span><span>)</span>
<span>-- Mpd</span>
<span>local</span> <span>mpd_buttons</span> <span>=</span> <span>require</span><span>(</span><span>"widget.mpd_buttons"</span><span>)</span>
<span>local</span> <span>mpd_song</span> <span>=</span> <span>require</span><span>(</span><span>"widget.mpd_song"</span><span>)</span>
<span>local</span> <span>mpd_widget_children</span> <span>=</span> <span>mpd_song</span><span>:</span><span>get_all_children</span><span>()</span>
<span>local</span> <span>mpd_title</span> <span>=</span> <span>mpd_widget_children</span><span>[</span><span>1</span><span>]</span>
<span>local</span> <span>mpd_artist</span> <span>=</span> <span>mpd_widget_children</span><span>[</span><span>2</span><span>]</span>
<span>mpd_title</span><span>.</span><span>font</span> <span>=</span> <span>"sans medium 14"</span>
<span>mpd_artist</span><span>.</span><span>font</span> <span>=</span> <span>"sans medium 10"</span>
<span>-- Set forced height in order to limit the widgets to one line.</span>
<span>-- Might need to be adjusted depending on the font.</span>
<span>mpd_title</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>22</span><span>)</span>
<span>mpd_artist</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>16</span><span>)</span>
<span>mpd_song</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q toggle"</span><span>)</span>
<span>end</span><span>),</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>3</span><span>,</span> <span>apps</span><span>.</span><span>music</span><span>),</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>4</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q prev"</span><span>)</span>
<span>end</span><span>),</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>5</span><span>,</span> <span>function</span> <span>()</span>
<span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q next"</span><span>)</span>
<span>end</span><span>)</span>
<span>))</span>
<span>-- Create the music sidebar</span>
<span>music_sidebar</span> <span>=</span> <span>wibox</span><span>({</span><span>visible</span> <span>=</span> <span>false</span><span>,</span> <span>ontop</span> <span>=</span> <span>true</span><span>,</span> <span>type</span> <span>=</span> <span>"dock"</span><span>,</span> <span>screen</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>})</span>
<span>music_sidebar</span><span>.</span><span>bg</span> <span>=</span> <span>"#00000000"</span> <span>-- For anti aliasing</span>
<span>music_sidebar</span><span>.</span><span>fg</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>music_sidebar</span><span>.</span><span>opacity</span> <span>=</span> <span>1</span>
<span>music_sidebar</span><span>.</span><span>height</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>.</span><span>geometry</span><span>.</span><span>height</span><span>/</span><span>1</span><span>.</span><span>5</span>
<span>music_sidebar</span><span>.</span><span>width</span> <span>=</span> <span>dpi</span><span>(</span><span>300</span><span>)</span>
<span>music_sidebar</span><span>.</span><span>y</span> <span>=</span> <span>0</span>
<span>awful</span><span>.</span><span>placement</span><span>.</span><span>right</span><span>(</span><span>music_sidebar</span><span>)</span>
<span>awful</span><span>.</span><span>placement</span><span>.</span><span>maximize_vertically</span><span>(</span><span>sidebar</span><span>,</span> <span>{</span> <span>honor_workarea</span> <span>=</span> <span>true</span><span>,</span> <span>margins</span> <span>=</span> <span>{</span> <span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>)</span> <span>*</span> <span>2</span> <span>}</span> <span>})</span>
<span>music_sidebar</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
<span>-- Middle click - Hide sidebar</span>
<span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>2</span><span>,</span> <span>function</span> <span>()</span>
<span>music_sidebar_hide</span><span>()</span>
<span>end</span><span>)</span>
<span>))</span>
<span>music_sidebar</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::leave"</span><span>,</span> <span>function</span> <span>()</span>
<span>music_sidebar_hide</span><span>()</span>
<span>end</span><span>)</span>
<span>music_sidebar_show</span> <span>=</span> <span>function</span><span>()</span>
<span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
<span>end</span>
<span>music_sidebar_hide</span> <span>=</span> <span>function</span><span>()</span>
<span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>false</span>
<span>end</span>
<span>music_sidebar_toggle</span> <span>=</span> <span>function</span><span>()</span>
<span>if</span> <span>music_sidebar</span><span>.</span><span>visible</span> <span>then</span>
<span>music_sidebar_hide</span><span>()</span>
<span>else</span>
<span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
<span>end</span>
<span>end</span>
<span>-- Activate sidebar by moving the mouse at the edge of the screen</span>
<span>local</span> <span>music_sidebar_activator</span> <span>=</span> <span>wibox</span><span>({</span><span>y</span> <span>=</span> <span>music_sidebar</span><span>.</span><span>y</span><span>,</span> <span>width</span> <span>=</span> <span>1</span><span>,</span> <span>visible</span> <span>=</span> <span>true</span><span>,</span> <span>ontop</span> <span>=</span> <span>false</span><span>,</span> <span>opacity</span> <span>=</span> <span>0</span><span>,</span> <span>below</span> <span>=</span> <span>true</span><span>,</span> <span>screen</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>})</span>
<span>music_sidebar_activator</span><span>.</span><span>height</span> <span>=</span> <span>music_sidebar</span><span>.</span><span>height</span>
<span>music_sidebar_activator</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::enter"</span><span>,</span> <span>function</span> <span>()</span>
<span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
<span>end</span><span>)</span>
<span>awful</span><span>.</span><span>placement</span><span>.</span><span>right</span><span>(</span><span>music_sidebar_activator</span><span>)</span>
<span>-- Music sidebar placement</span>
<span>music_sidebar</span><span>:</span><span>setup</span> <span>{</span>
<span>{</span>
<span>{</span>
<span>{</span>
<span>{</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>25</span><span>)),</span>
<span>moe</span><span>,</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>15</span><span>)),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>},</span>
<span>halign</span> <span>=</span> <span>'center'</span><span>,</span>
<span>valign</span> <span>=</span> <span>'center'</span><span>,</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
<span>},</span>
<span>shape</span> <span>=</span> <span>helpers</span><span>.</span><span>prrect</span><span>(</span><span>dpi</span><span>(</span><span>40</span><span>),</span> <span>true</span><span>,</span> <span>false</span><span>,</span> <span>false</span><span>,</span> <span>true</span><span>),</span>
<span>bg</span> <span>=</span> <span>x</span><span>.</span><span>color8</span><span>..</span><span>"30"</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>},</span>
<span>{</span>
<span>{</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>30</span><span>)),</span>
<span>{</span>
<span>spotify_buttons</span><span>,</span>
<span>spotify</span><span>,</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>},</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>},</span>
<span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>{</span>
<span>{</span>
<span>mpd_buttons</span><span>,</span>
<span>mpd_song</span><span>,</span>
<span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>},</span>
<span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>40</span><span>),</span>
<span>bottom</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
<span>},</span>
<span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>25</span><span>)),</span>
<span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
<span>},</span>
<span>shape</span> <span>=</span> <span>helpers</span><span>.</span><span>prrect</span><span>(</span><span>dpi</span><span>(</span><span>40</span><span>),</span> <span>true</span><span>,</span> <span>false</span><span>,</span> <span>false</span><span>,</span> <span>true</span><span>),</span>
<span>bg</span> <span>=</span> <span>x</span><span>.</span><span>background</span><span>,</span>
<span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
<span>-- modules</span>
<span>local</span> <span>awful</span> <span>=</span> <span>require</span><span>(</span><span>"awful"</span><span>)</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>local</span> <span>wibox</span> <span>=</span> <span>require</span><span>(</span><span>"wibox"</span><span>)</span>

<span>-- Moe</span>
<span>local</span> <span>moe</span> <span>=</span> <span>require</span><span>(</span><span>"widget.moe"</span><span>)</span>

<span>-- Spotify</span>
<span>local</span> <span>spotify_buttons</span> <span>=</span> <span>require</span><span>(</span><span>"widget.spotify_buttons"</span><span>)</span>
<span>local</span> <span>spotify</span> <span>=</span> <span>require</span><span>(</span><span>"widget.spotify"</span><span>)</span>
<span>local</span> <span>spotify_widget_children</span> <span>=</span> <span>spotify</span><span>:</span><span>get_all_children</span><span>()</span>
<span>local</span> <span>spotify_title</span> <span>=</span> <span>spotify_widget_children</span><span>[</span><span>1</span><span>]</span>
<span>local</span> <span>spotify_artist</span> <span>=</span> <span>spotify_widget_children</span><span>[</span><span>2</span><span>]</span>
<span>spotify_title</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>22</span><span>)</span>
<span>spotify_artist</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>16</span><span>)</span>

<span>-- Mpd</span>
<span>local</span> <span>mpd_buttons</span> <span>=</span> <span>require</span><span>(</span><span>"widget.mpd_buttons"</span><span>)</span>
<span>local</span> <span>mpd_song</span> <span>=</span> <span>require</span><span>(</span><span>"widget.mpd_song"</span><span>)</span>
<span>local</span> <span>mpd_widget_children</span> <span>=</span> <span>mpd_song</span><span>:</span><span>get_all_children</span><span>()</span>
<span>local</span> <span>mpd_title</span> <span>=</span> <span>mpd_widget_children</span><span>[</span><span>1</span><span>]</span>
<span>local</span> <span>mpd_artist</span> <span>=</span> <span>mpd_widget_children</span><span>[</span><span>2</span><span>]</span>
<span>mpd_title</span><span>.</span><span>font</span> <span>=</span> <span>"sans medium 14"</span>
<span>mpd_artist</span><span>.</span><span>font</span> <span>=</span> <span>"sans medium 10"</span>

<span>-- Set forced height in order to limit the widgets to one line.</span>
<span>-- Might need to be adjusted depending on the font.</span>
<span>mpd_title</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>22</span><span>)</span>
<span>mpd_artist</span><span>.</span><span>forced_height</span> <span>=</span> <span>dpi</span><span>(</span><span>16</span><span>)</span>

<span>mpd_song</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>1</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q toggle"</span><span>)</span>
    <span>end</span><span>),</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>3</span><span>,</span> <span>apps</span><span>.</span><span>music</span><span>),</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>4</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q prev"</span><span>)</span>
    <span>end</span><span>),</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>5</span><span>,</span> <span>function</span> <span>()</span>
        <span>awful</span><span>.</span><span>spawn</span><span>.</span><span>with_shell</span><span>(</span><span>"mpc -q next"</span><span>)</span>
    <span>end</span><span>)</span>
<span>))</span>



<span>-- Create the music sidebar</span>
<span>music_sidebar</span> <span>=</span> <span>wibox</span><span>({</span><span>visible</span> <span>=</span> <span>false</span><span>,</span> <span>ontop</span> <span>=</span> <span>true</span><span>,</span> <span>type</span> <span>=</span> <span>"dock"</span><span>,</span> <span>screen</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>})</span>
<span>music_sidebar</span><span>.</span><span>bg</span> <span>=</span> <span>"#00000000"</span> <span>-- For anti aliasing</span>
<span>music_sidebar</span><span>.</span><span>fg</span> <span>=</span> <span>x</span><span>.</span><span>color7</span>
<span>music_sidebar</span><span>.</span><span>opacity</span> <span>=</span> <span>1</span>
<span>music_sidebar</span><span>.</span><span>height</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>.</span><span>geometry</span><span>.</span><span>height</span><span>/</span><span>1</span><span>.</span><span>5</span>
<span>music_sidebar</span><span>.</span><span>width</span> <span>=</span> <span>dpi</span><span>(</span><span>300</span><span>)</span>
<span>music_sidebar</span><span>.</span><span>y</span> <span>=</span> <span>0</span>

<span>awful</span><span>.</span><span>placement</span><span>.</span><span>right</span><span>(</span><span>music_sidebar</span><span>)</span>
<span>awful</span><span>.</span><span>placement</span><span>.</span><span>maximize_vertically</span><span>(</span><span>sidebar</span><span>,</span> <span>{</span> <span>honor_workarea</span> <span>=</span> <span>true</span><span>,</span> <span>margins</span> <span>=</span> <span>{</span> <span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>)</span> <span>*</span> <span>2</span> <span>}</span> <span>})</span>

<span>music_sidebar</span><span>:</span><span>buttons</span><span>(</span><span>gears</span><span>.</span><span>table</span><span>.</span><span>join</span><span>(</span>
    <span>-- Middle click - Hide sidebar</span>
    <span>awful</span><span>.</span><span>button</span><span>({</span> <span>},</span> <span>2</span><span>,</span> <span>function</span> <span>()</span>
        <span>music_sidebar_hide</span><span>()</span>
    <span>end</span><span>)</span>
<span>))</span>

<span>music_sidebar</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::leave"</span><span>,</span> <span>function</span> <span>()</span>
        <span>music_sidebar_hide</span><span>()</span>
<span>end</span><span>)</span>

<span>music_sidebar_show</span> <span>=</span> <span>function</span><span>()</span>
    <span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
<span>end</span>

<span>music_sidebar_hide</span> <span>=</span> <span>function</span><span>()</span>
    <span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>false</span>
<span>end</span>

<span>music_sidebar_toggle</span> <span>=</span> <span>function</span><span>()</span>
    <span>if</span> <span>music_sidebar</span><span>.</span><span>visible</span> <span>then</span>
        <span>music_sidebar_hide</span><span>()</span>
    <span>else</span>
        <span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
    <span>end</span>
<span>end</span>

<span>-- Activate sidebar by moving the mouse at the edge of the screen</span>

<span>local</span> <span>music_sidebar_activator</span> <span>=</span> <span>wibox</span><span>({</span><span>y</span> <span>=</span> <span>music_sidebar</span><span>.</span><span>y</span><span>,</span> <span>width</span> <span>=</span> <span>1</span><span>,</span> <span>visible</span> <span>=</span> <span>true</span><span>,</span> <span>ontop</span> <span>=</span> <span>false</span><span>,</span> <span>opacity</span> <span>=</span> <span>0</span><span>,</span> <span>below</span> <span>=</span> <span>true</span><span>,</span> <span>screen</span> <span>=</span> <span>screen</span><span>.</span><span>primary</span><span>})</span>
    <span>music_sidebar_activator</span><span>.</span><span>height</span> <span>=</span> <span>music_sidebar</span><span>.</span><span>height</span>
    <span>music_sidebar_activator</span><span>:</span><span>connect_signal</span><span>(</span><span>"mouse::enter"</span><span>,</span> <span>function</span> <span>()</span>
        <span>music_sidebar</span><span>.</span><span>visible</span> <span>=</span> <span>true</span>
    <span>end</span><span>)</span>
        <span>awful</span><span>.</span><span>placement</span><span>.</span><span>right</span><span>(</span><span>music_sidebar_activator</span><span>)</span>

<span>-- Music sidebar placement</span>
<span>music_sidebar</span><span>:</span><span>setup</span> <span>{</span>
            <span>{</span>
                <span>{</span>
                    <span>{</span>
                        <span>{</span>
                          <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>25</span><span>)),</span>
                          <span>moe</span><span>,</span>
                          <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>15</span><span>)),</span>
                          <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
                        <span>},</span>
                      <span>halign</span> <span>=</span> <span>'center'</span><span>,</span>
                      <span>valign</span> <span>=</span> <span>'center'</span><span>,</span>
                      <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>place</span>
                    <span>},</span>
                  <span>shape</span> <span>=</span> <span>helpers</span><span>.</span><span>prrect</span><span>(</span><span>dpi</span><span>(</span><span>40</span><span>),</span> <span>true</span><span>,</span> <span>false</span><span>,</span> <span>false</span><span>,</span> <span>true</span><span>),</span>
                  <span>bg</span> <span>=</span> <span>x</span><span>.</span><span>color8</span><span>..</span><span>"30"</span><span>,</span>
                  <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
                <span>},</span>
                <span>{</span>
                  <span>{</span>
                    <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>30</span><span>)),</span>
                    <span>{</span>
                      <span>spotify_buttons</span><span>,</span>
                      <span>spotify</span><span>,</span>
                      <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>),</span>
                      <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
                    <span>},</span>
                    <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
                  <span>},</span>
                  <span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
                  <span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
                  <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
                <span>},</span>
                <span>{</span>
                    <span>{</span>
                        <span>mpd_buttons</span><span>,</span>
                        <span>mpd_song</span><span>,</span>
                        <span>spacing</span> <span>=</span> <span>dpi</span><span>(</span><span>5</span><span>),</span>
                        <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
                    <span>},</span>
                    <span>top</span> <span>=</span> <span>dpi</span><span>(</span><span>40</span><span>),</span>
                    <span>bottom</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
                    <span>left</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
                    <span>right</span> <span>=</span> <span>dpi</span><span>(</span><span>20</span><span>),</span>
                    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>margin</span>
                <span>},</span>
                <span>helpers</span><span>.</span><span>vertical_pad</span><span>(</span><span>dpi</span><span>(</span><span>25</span><span>)),</span>
                <span>layout</span> <span>=</span> <span>wibox</span><span>.</span><span>layout</span><span>.</span><span>fixed</span><span>.</span><span>vertical</span>
            <span>},</span>
    <span>shape</span> <span>=</span> <span>helpers</span><span>.</span><span>prrect</span><span>(</span><span>dpi</span><span>(</span><span>40</span><span>),</span> <span>true</span><span>,</span> <span>false</span><span>,</span> <span>false</span><span>,</span> <span>true</span><span>),</span>
    <span>bg</span> <span>=</span> <span>x</span><span>.</span><span>background</span><span>,</span>
    <span>widget</span> <span>=</span> <span>wibox</span><span>.</span><span>container</span><span>.</span><span>background</span>
<span>}</span>
-- modules local awful = require("awful") local helpers = require("helpers") local wibox = require("wibox") -- Moe local moe = require("widget.moe") -- Spotify local spotify_buttons = require("widget.spotify_buttons") local spotify = require("widget.spotify") local spotify_widget_children = spotify:get_all_children() local spotify_title = spotify_widget_children[1] local spotify_artist = spotify_widget_children[2] spotify_title.forced_height = dpi(22) spotify_artist.forced_height = dpi(16) -- Mpd local mpd_buttons = require("widget.mpd_buttons") local mpd_song = require("widget.mpd_song") local mpd_widget_children = mpd_song:get_all_children() local mpd_title = mpd_widget_children[1] local mpd_artist = mpd_widget_children[2] mpd_title.font = "sans medium 14" mpd_artist.font = "sans medium 10" -- Set forced height in order to limit the widgets to one line. -- Might need to be adjusted depending on the font. mpd_title.forced_height = dpi(22) mpd_artist.forced_height = dpi(16) mpd_song:buttons(gears.table.join( awful.button({ }, 1, function () awful.spawn.with_shell("mpc -q toggle") end), awful.button({ }, 3, apps.music), awful.button({ }, 4, function () awful.spawn.with_shell("mpc -q prev") end), awful.button({ }, 5, function () awful.spawn.with_shell("mpc -q next") end) )) -- Create the music sidebar music_sidebar = wibox({visible = false, ontop = true, type = "dock", screen = screen.primary}) music_sidebar.bg = "#00000000" -- For anti aliasing music_sidebar.fg = x.color7 music_sidebar.opacity = 1 music_sidebar.height = screen.primary.geometry.height/1.5 music_sidebar.width = dpi(300) music_sidebar.y = 0 awful.placement.right(music_sidebar) awful.placement.maximize_vertically(sidebar, { honor_workarea = true, margins = { top = dpi(5) * 2 } }) music_sidebar:buttons(gears.table.join( -- Middle click - Hide sidebar awful.button({ }, 2, function () music_sidebar_hide() end) )) music_sidebar:connect_signal("mouse::leave", function () music_sidebar_hide() end) music_sidebar_show = function() music_sidebar.visible = true end music_sidebar_hide = function() music_sidebar.visible = false end music_sidebar_toggle = function() if music_sidebar.visible then music_sidebar_hide() else music_sidebar.visible = true end end -- Activate sidebar by moving the mouse at the edge of the screen local music_sidebar_activator = wibox({y = music_sidebar.y, width = 1, visible = true, ontop = false, opacity = 0, below = true, screen = screen.primary}) music_sidebar_activator.height = music_sidebar.height music_sidebar_activator:connect_signal("mouse::enter", function () music_sidebar.visible = true end) awful.placement.right(music_sidebar_activator) -- Music sidebar placement music_sidebar:setup { { { { { helpers.vertical_pad(dpi(25)), moe, helpers.vertical_pad(dpi(15)), layout = wibox.layout.fixed.vertical }, halign = 'center', valign = 'center', layout = wibox.container.place }, shape = helpers.prrect(dpi(40), true, false, false, true), bg = x.color8.."30", widget = wibox.container.background }, { { helpers.vertical_pad(dpi(30)), { spotify_buttons, spotify, spacing = dpi(5), layout = wibox.layout.fixed.vertical }, layout = wibox.layout.fixed.vertical }, left = dpi(20), right = dpi(20), widget = wibox.container.margin }, { { mpd_buttons, mpd_song, spacing = dpi(5), layout = wibox.layout.fixed.vertical }, top = dpi(40), bottom = dpi(20), left = dpi(20), right = dpi(20), widget = wibox.container.margin }, helpers.vertical_pad(dpi(25)), layout = wibox.layout.fixed.vertical }, shape = helpers.prrect(dpi(40), true, false, false, true), bg = x.background, widget = wibox.container.background }

Enter fullscreen mode Exit fullscreen mode


Bringing the musicbar alive in rc.lua

Now that we have assembled all the required pieces to the puzzle, it’s time to assemble and put them to work in rc.lua.

Add the following lines to the top of your rc.lua

<span>-- Initialization</span>
<span>-- ===================================================================</span>
<span>-- Theme handling library</span>
<span>local</span> <span>beautiful</span> <span>=</span> <span>require</span><span>(</span><span>"beautiful"</span><span>)</span>
<span>local</span> <span>xrdb</span> <span>=</span> <span>beautiful</span><span>.</span><span>xresources</span><span>.</span><span>get_current_theme</span><span>()</span>
<span>-- Make dpi function global</span>
<span>dpi</span> <span>=</span> <span>beautiful</span><span>.</span><span>xresources</span><span>.</span><span>apply_dpi</span>
<span>-- Make xresources colors global</span>
<span>x</span> <span>=</span> <span>{</span>
<span>-- xrdb variable</span>
<span>background</span> <span>=</span> <span>xrdb</span><span>.</span><span>background</span><span>,</span>
<span>foreground</span> <span>=</span> <span>xrdb</span><span>.</span><span>foreground</span><span>,</span>
<span>color0</span> <span>=</span> <span>xrdb</span><span>.</span><span>color0</span><span>,</span>
<span>color1</span> <span>=</span> <span>xrdb</span><span>.</span><span>color1</span><span>,</span>
<span>color2</span> <span>=</span> <span>xrdb</span><span>.</span><span>color2</span><span>,</span>
<span>color3</span> <span>=</span> <span>xrdb</span><span>.</span><span>color3</span><span>,</span>
<span>color4</span> <span>=</span> <span>xrdb</span><span>.</span><span>color4</span><span>,</span>
<span>color5</span> <span>=</span> <span>xrdb</span><span>.</span><span>color5</span><span>,</span>
<span>color6</span> <span>=</span> <span>xrdb</span><span>.</span><span>color6</span><span>,</span>
<span>color7</span> <span>=</span> <span>xrdb</span><span>.</span><span>color7</span><span>,</span>
<span>color8</span> <span>=</span> <span>xrdb</span><span>.</span><span>color8</span><span>,</span>
<span>color9</span> <span>=</span> <span>xrdb</span><span>.</span><span>color9</span><span>,</span>
<span>color10</span> <span>=</span> <span>xrdb</span><span>.</span><span>color10</span><span>,</span>
<span>color11</span> <span>=</span> <span>xrdb</span><span>.</span><span>color11</span><span>,</span>
<span>color12</span> <span>=</span> <span>xrdb</span><span>.</span><span>color12</span><span>,</span>
<span>color13</span> <span>=</span> <span>xrdb</span><span>.</span><span>color13</span><span>,</span>
<span>color14</span> <span>=</span> <span>xrdb</span><span>.</span><span>color14</span><span>,</span>
<span>color15</span> <span>=</span> <span>xrdb</span><span>.</span><span>color15</span><span>,</span>
<span>}</span>
<span>-- Load helper functions</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>
<span>-- Load the musicbar </span>
<span>require</span><span>(</span><span>"musicbar"</span><span>)</span>
<span>-- >> Daemons</span>
<span>-- Make sure to initialize it last in order to allow all widgets to connect to their needed daemon signals.</span>
<span>require</span><span>(</span><span>"daemon"</span><span>)</span>
<span>-----------<< Rest of your config >>-----------------</span>
<span>-- Initialization</span>
<span>-- ===================================================================</span>
<span>-- Theme handling library</span>
<span>local</span> <span>beautiful</span> <span>=</span> <span>require</span><span>(</span><span>"beautiful"</span><span>)</span>
<span>local</span> <span>xrdb</span> <span>=</span> <span>beautiful</span><span>.</span><span>xresources</span><span>.</span><span>get_current_theme</span><span>()</span>
<span>-- Make dpi function global</span>
<span>dpi</span> <span>=</span> <span>beautiful</span><span>.</span><span>xresources</span><span>.</span><span>apply_dpi</span>
<span>-- Make xresources colors global</span>
<span>x</span> <span>=</span> <span>{</span>
    <span>-- xrdb variable</span>
    <span>background</span> <span>=</span> <span>xrdb</span><span>.</span><span>background</span><span>,</span>
    <span>foreground</span> <span>=</span> <span>xrdb</span><span>.</span><span>foreground</span><span>,</span>
    <span>color0</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color0</span><span>,</span>
    <span>color1</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color1</span><span>,</span>
    <span>color2</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color2</span><span>,</span>
    <span>color3</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color3</span><span>,</span>
    <span>color4</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color4</span><span>,</span>
    <span>color5</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color5</span><span>,</span>
    <span>color6</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color6</span><span>,</span>
    <span>color7</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color7</span><span>,</span>
    <span>color8</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color8</span><span>,</span>
    <span>color9</span>     <span>=</span> <span>xrdb</span><span>.</span><span>color9</span><span>,</span>
    <span>color10</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color10</span><span>,</span>
    <span>color11</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color11</span><span>,</span>
    <span>color12</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color12</span><span>,</span>
    <span>color13</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color13</span><span>,</span>
    <span>color14</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color14</span><span>,</span>
    <span>color15</span>    <span>=</span> <span>xrdb</span><span>.</span><span>color15</span><span>,</span>
<span>}</span>

<span>-- Load helper functions</span>
<span>local</span> <span>helpers</span> <span>=</span> <span>require</span><span>(</span><span>"helpers"</span><span>)</span>

<span>-- Load the musicbar </span>
<span>require</span><span>(</span><span>"musicbar"</span><span>)</span>

<span>-- >> Daemons</span>
<span>-- Make sure to initialize it last in order to allow all widgets to connect to their needed daemon signals.</span>
<span>require</span><span>(</span><span>"daemon"</span><span>)</span>


<span>-----------<< Rest of your config >>-----------------</span>
-- Initialization -- =================================================================== -- Theme handling library local beautiful = require("beautiful") local xrdb = beautiful.xresources.get_current_theme() -- Make dpi function global dpi = beautiful.xresources.apply_dpi -- Make xresources colors global x = { -- xrdb variable background = xrdb.background, foreground = xrdb.foreground, color0 = xrdb.color0, color1 = xrdb.color1, color2 = xrdb.color2, color3 = xrdb.color3, color4 = xrdb.color4, color5 = xrdb.color5, color6 = xrdb.color6, color7 = xrdb.color7, color8 = xrdb.color8, color9 = xrdb.color9, color10 = xrdb.color10, color11 = xrdb.color11, color12 = xrdb.color12, color13 = xrdb.color13, color14 = xrdb.color14, color15 = xrdb.color15, } -- Load helper functions local helpers = require("helpers") -- Load the musicbar require("musicbar") -- >> Daemons -- Make sure to initialize it last in order to allow all widgets to connect to their needed daemon signals. require("daemon") -----------<< Rest of your config >>-----------------

Enter fullscreen mode Exit fullscreen mode

With this, hopefully if you’ll restart your awesome window manager you will get a musicbar on your right edge when you hover the mouse over that edge.

Thank You, for following me to the end. Hopefully, it was benificial to you as much as it was to me.


Resources ️

All configs along with directory structure :

ashish-patwal / Moe-Lua-Daemon

Music Bar for Awesome WM ( listen.moe , spotify, MPD )

Update

  • This repository now holds the code for musicbar ( listen.moe, mpd, spotify ).

Basic Info

  • A lua daemon for fetching information from listen.moe using websocket through python websocket script.
  • Also contains code for mpd and spotify music bar .
  • Used for Awesome Window Manager .

ToDo

  • Add widget for displaying info
  • Add async fetching of images of artists / album covers to display in widget
  • Ability to stream the music alongside using mpv
  • Ability to Start / Stop

Screenshots

图片[1]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋
图片[2]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋


View on GitHub

Do give me a follow if you liked the content. I will be posting some really interesting stuff.

图片[3]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋
图片[4]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋 Ashish Patwal @ashishpatwal147
图片[5]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋 I have gone from ” I wish they provided this feature ” to ” I’ll just program my own feature ” . Wrote my own music bar (
listen.moe , Spotify , and mpd player ) with lua and awesome wm . 14:13 PM – 14 Jan 2022
图片[6]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋
图片[7]-Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua-拾光赋

ashish-patwal / dotfiles

My dotfiles for the ArchLinux OS . Dual Boot . Heavily Riced . Scripting is ️ .

原文链接:Make a Music Bar ( listen.moe , mpd , spotify ) using Awesome Window Manager and Lua

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
Have faith in your dreams and someday your rainbow will come smiling through.
请对梦想充满信心,总有一天属于你的彩虹会在天空微笑
评论 抢沙发

请登录后发表评论

    暂无评论内容